stm32簡說步進電機(有程式碼)!!!
步進電機(也稱脈衝電機)(將電脈衝轉換為相應的角位移或線位移的電磁機械裝置,具有快速啟動,停能力,在電機的負荷不超過它能提供的動態轉矩時,可以通過輸入脈衝來控制它在一瞬間的啟動或者停止。在非超載的情況下,步距角和轉速只和輸入的脈衝頻率有關,和環境溫度,氣壓,振動無關,也不受電網電壓的波動和負載變化的影響,因此,控制較為精準)即給電機一個脈衝訊號,電機則轉過一個步距角
步進電機是一種感應電機,它的工作原理:利用電子電路,將直流電變成分時供電的,多相時序控制電流,用這種電流為步進電機供電,步進電機才能正常工作,驅動器就是為步進電機分時供電的,多相時序控制器,就是說:必須用由雙環形脈衝訊號功率驅動電路等組成的控制系統方可使用。
步距角:控制系統每發一個步進脈衝訊號,電機所轉動的角度。電機出廠時給了一個步距角的值,如:86BYG250A型 電機的值為0.9、1.8(表示半步工作時為0.9,整步為1.8),被稱之為“電機的固有步距角”,但是不一定是 電機實際工作時的真正步距角,真正的步距角和驅動器有關
相數:電機內部的線圈組數,目前常用的有二相,三相,四相,五相步進電機。電機相數不同,其步距角也就不同了, 一般二相電機的步距角為0.9/1,8,三相為0.36/0.72,五相為0.36/0.72。在沒有細分驅動器的情況下,使用者主要 靠選擇不同相數的步進電機來滿足自己步距角的要求。如果使用細分驅動器,那麼相數好像也就沒有了意義
拍數:完成一個磁場週期性變化所需脈衝數或導電狀態,或指電機轉過一個步距角所需脈衝數。以如下的四相電機為 例,有四相四拍執行方式,AB-BC-CD-DA-AB;四相八拍:A-AB-B-BC-C-CD-D-DA-A
失步:電機運轉時運轉的步數不等於理論上的步數,稱之為失步
開環控制與閉環控制:(主要看系統中有沒有反饋環節)(反饋指的是動作所引起的效果)
(反饋簡單的理解就是:“你打了別人一巴掌,我們看到了它的臉是紅的,嗯嗯,這就是眼睛所得到的反饋”)
閉環控制:存在反饋環節的控制,就是當前的系統能夠實時的檢測控制的輸出結果,並將檢測到的資訊通過反饋環節反映到輸入端,調整輸入量,達到修正控制誤差,提高控制精度的目的,(對外部擾動和系統引數變化不敏感)如:
(閉環)
全自動洗衣機,給洗衣機加水時,裡邊有一個紅外感測器,掃描到水位高低,當水位合適時,洗衣機自動停止加水
家用空調根據感測器採集到當前的溫度,然後比較設定溫度,通過設定指令,控制室內外機的工作情況,改變頻率,壓縮機的轉速等進行簡單的調節,然後不斷地進行控制
尋跡小車時,兩邊的紅外感測器不斷的檢測黑線,將返回的結果輸入到相應i/o口上,我們對這些i/o口進行中斷檢測就可以知道,當前時刻的位置,然後可以執行相應的操作(左轉,右轉);
調節平衡天平的時候,其中一種方法就是利用mpu6050獲取當前所處位置的角度,呼叫PID演算法,對當前的位置或者角度進行處理,然後對調整後的角度再次進行反饋處理
(家用空調調節溫度)
家用空調調節指定的溫度,靠的是電子感測器,(電子感測器就是一個熱敏電阻,不同的溫度會有不同的阻值),利用也可以理解為電子膨脹,不同的溫度會有不同的阻值。利用對入風口的空氣進行取樣,把資料傳輸到控制板上,然後,在與設定的溫度進行比較,產生一個指令來實現控制。(製冷的話,比較之後:輸出室內風機和室外機的開機指令,內外機開始工作(室外機包括壓縮機,室外風機,四通閥等部件),工作一定溫度的話,室內溫度將會:1,(定頻空調)達到設定值,室外機停止工作,室內機保持工作,保證空氣迴圈,當室內溫度逐漸上升,大於設定值2-3度時,室外機重新啟動製冷,室內溫度將又開始下降,重複這個過程,室內溫度就能保持在設定溫度值上下1度左右範圍內波動;
2,(變頻空調)接近設定值,室外機的變頻板輸出的頻率下降,壓縮機轉速下降,製冷量也相應降低,室內溫度保持在與設定值相同的數值下。隨著室內熱源的變化,室內機溫度感測器實時檢測溫度的變化,主控板輸出的控制訊號使變頻器跟隨變化調節壓縮機工作頻率,從而改變瞬時製冷量,確保室內溫度穩定)
開環控制:不存在反饋環節的控制,也就是控制器與被控制物件間只有順序作業而無反方向聯絡且控制單方向進行,
,無自動糾偏能力,不用取輸出量變化訊號控制輸入量。
如:在開車的過程中,我們來控制方向盤
人工轉換電扇的檔位實現轉速的控制,不用反饋回來實際的轉速
給洗衣機加水時:我們通過來觀察水位來確定什麼時候關掉水龍頭
(所以,簡單的說:就是看有沒有反饋:開環沒有,閉環有,對於用到機器上來說,每一件事都是有反饋的,只是情況不同而已,當反饋是人自己來判斷的話,那麼這個系統就是開環的,如果反饋是機器自己來判斷的話,那麼這個系統就是閉環的)
從整體的角度來看:
主控程式+按鍵+步進電機
主控程式(test.c)
#include "sys.h"
#include "usart.h"
#include "delay.h"
#include "led.h"
#include "key.h"
#include "motor.h"
int main(void)
{
u8 t;
Stm32_Clock_Init(9); //系統時鐘設定
delay_init(72); //延時初始化
LED_Init(); //初始化與LED連線的硬體介面
KEY_Init(); //初始化與按鍵連線的硬體介面
LED0=0; //點亮LED
MOTOR_Init();
while(1)
{
MOTOR();
}
}
整體截圖:
然後接下來就是:led.c
#include "sys.h"
#include "led.h"
//////////////////////////////////////////////////////////////////////////////////
//LED IO初始化
void LED_Init(void)
{
RCC->APB2ENR|=1<<2; //使能PORTA時鐘
RCC->APB2ENR|=1<<5; //使能PORTD時鐘
GPIOA->CRH&=0XFFFFFFF0;
GPIOA->CRH|=0X00000003;//PA8 推輓輸出
GPIOA->ODR|=1<<8; //PA8 輸出高
GPIOD->CRL&=0XFFFFF0FF;
GPIOD->CRL|=0X00000300;//PD.2推輓輸出
GPIOD->ODR|=1<<2; //PD.2輸出高
}
led.h
#ifndef __LED_H
#define __LED_H
#include "sys.h"
//////////////////////////////////////////////////////////////////////////////////
//LED埠定義
#define LED0 PAout(8) // PA8
#define LED1 PDout(2) // PD2
void LED_Init(void); //初始化
#endif
然後就是:key.c
#include "key.h"
#include "delay.h"
//////////////////////////////////////////////////////////////////////////////////
//本程式只供學習使用,未經作者許可,不得用於其它任何用途
//ALIENTEK Mini STM32開發板
//按鍵輸入 驅動程式碼
//正點原子@ALIENTEK
//技術論壇:www.openedv.com
//修改日期:2014/3/06
//版本:V1.0
//版權所有,盜版必究。
//Copyright(C) 廣州市星翼電子科技有限公司 2009-2019
//All rights reserved
//////////////////////////////////////////////////////////////////////////////////
//按鍵初始化函式
//PA0.15和PC5 設定成輸入
void KEY_Init(void)
{
RCC->APB2ENR|=1<<2; //使能PORTA時鐘
RCC->APB2ENR|=1<<4; //使能PORTC時鐘
JTAG_Set(SWD_ENABLE); //關閉JTAG,開啟SWD
GPIOA->CRL&=0XFFFFFFF0; //PA0設定成輸入
GPIOA->CRL|=0X00000008;
GPIOA->CRH&=0X0FFFFFFF; //PA15設定成輸入
GPIOA->CRH|=0X80000000;
GPIOA->ODR|=1<<15; //PA15上拉,PA0預設下拉
GPIOC->CRL&=0XFF0FFFFF; //PC5設定成輸入
GPIOC->CRL|=0X00800000;
GPIOC->ODR|=1<<5; //PC5上拉
}
//按鍵處理函式
//返回按鍵值
//mode:0,不支援連續按;1,支援連續按;
//返回值:
//0,沒有任何按鍵按下
//KEY0_PRES,KEY0按下
//KEY1_PRES,KEY1按下
//WKUP_PRES,WK_UP按下
//注意此函式有響應優先順序,KEY0>KEY1>WK_UP!!
u8 KEY_Scan(u8 mode)
{
static u8 key_up=1;//按鍵按鬆開標誌
if(mode)key_up=1; //支援連按
if(key_up&&(KEY0==0||KEY1==0||WK_UP==1))
{
delay_ms(10);//去抖動
key_up=0;
if(KEY0==0)return KEY0_PRES;
else if(KEY1==0)return KEY1_PRES;
else if(WK_UP==1)return WKUP_PRES;
}else if(KEY0==1&&KEY1==1&&WK_UP==0)key_up=1;
return 0;// 無按鍵按下
}
key.h
#ifndef __KEY_H
#define __KEY_H
#include "sys.h"
//////////////////////////////////////////////////////////////////////////////////
//本程式只供學習使用,未經作者許可,不得用於其它任何用途
//ALIENTEK Mini STM32開發板
//按鍵輸入 驅動程式碼
//正點原子@ALIENTEK
//技術論壇:www.openedv.com
//修改日期:2014/3/06
//版本:V1.0
//版權所有,盜版必究。
//Copyright(C) 廣州市星翼電子科技有限公司 2009-2019
//All rights reserved
//////////////////////////////////////////////////////////////////////////////////
#define KEY0_PRES 1 //KEY0按下
#define KEY1_PRES 2 //KEY1按下
#define WKUP_PRES 3 //WK_UP按下
#define KEY0 PCin(5) //PC5
#define KEY1 PAin(15) //PA15
#define WK_UP PAin(0) //PA0 WK_UP
void KEY_Init(void); //IO初始化
u8 KEY_Scan(u8 mode); //按鍵掃描函式
#endif
接下來就是:motor.c
#include "motor.h"
#include "delay.h"
//////////////////////////////////////////////////////////////////////////////////
//電機初始化函式
//PA0.15和PC5 設定成輸入
void MOTOR_Init(void)
{
RCC->APB2ENR|=1<<2; //使能PORTA時鐘
GPIOA->CRL&=0XFFFF0000; //PA0設定成輸出
GPIOA->CRL|=0X00003333;
//小車左輪
GPIOA->ODR|=0<<0; //PA0上拉
GPIOA->ODR|=0<<1; //PA1上拉
GPIOA->ODR|=0<<2; //PA2上拉
GPIOA->ODR|=0<<3; //PA3上拉
RCC->APB2ENR|=1<<4; //使能PORTC時鐘
//小車右輪
GPIOC->CRL&=0X00FFFFFF; //PC6,7
GPIOC->CRL|=0X33000000;
GPIOC->CRH&=0XFFFFFF00; //PC8,9
GPIOC->CRH|=0X00000033;
GPIOC->ODR|=0<<6; //PC6上拉
GPIOC->ODR|=0<<7; //PC7上拉
GPIOC->ODR|=0<<8; //PC7上拉
GPIOC->ODR|=0<<9; //PC5上拉
}
void MOTOR(void) //IO初始化
{
while(1)
{
// L_A1 = 1; L_A2 = 0; L_A3 = 0; L_A4 = 0;
// delay_ms(10);
// L_A1 = 1; L_A2 = 1; L_A3 = 0; L_A4 = 0;
// delay_ms(10);
// L_A1 = 0; L_A2 = 1; L_A3 = 0; L_A4 = 0;
// delay_ms(10);
// L_A1 = 0; L_A2 = 1; L_A3 = 1; L_A4 = 0;
// delay_ms(10);
//
//
// L_A1 = 0; L_A2 = 0; L_A3 = 1; L_A4 = 0;
// delay_ms(10);
// L_A1 = 0; L_A2 = 0; L_A3 = 1; L_A4 = 1;
// delay_ms(10);
// L_A1 = 0; L_A2 = 0; L_A3 = 0; L_A4 = 1;
// delay_ms(10);
// L_A1 = 1; L_A2 = 0; L_A3 = 0; L_A4 = 1;
// delay_ms(10);
L_A1 = 1; L_A3 = 0; L_A2 = 0; L_A4 = 0;
delay_ms(10);
L_A1 = 0; L_A3 = 1; L_A2 = 0; L_A4 = 0;
delay_ms(10);
L_A1 = 0; L_A3 = 0; L_A2 = 1; L_A4 = 0;
delay_ms(10);
L_A1 = 0; L_A3 = 0; L_A2 = 0; L_A4 = 1;
delay_ms(10);
}
}
motor.h
#ifndef __MOTOR_H
#define __MOTOR_H
#include "sys.h"
#include "delay.h"
//////////////////////////////////////////////////////////////////////////////////
//All rights reserved
//////////////////////////////////////////////////////////////////////////////////
#define L_A1 PAout(0) //PA0
#define L_A2 PAout(1) //PA1
#define L_A3 PAout(2) //PA2
#define L_A4 PAout(3) //PA3
#define R_A1 PCout(6) //PC6
#define R_A2 PCout(7) //PC7
#define R_A3 PCout(8) //PC8
#define R_A4 PCout(9) //PC9
void MOTOR_Init(void);
void MOTOR(void);
#endif
好了,以上就是我們的程式了,,,,,
截圖:
如上,是我們要載入的程式
本文大部分例項借鑑與:原子stm32