前段時間公務(wù)繁忙,收到的MM32SPIN160C開發(fā)板也無暇顧及,趁周末時間,來體驗一下這款開發(fā)板的電機(jī)驅(qū)動能力。
一、硬件方面:
板卡為專用電機(jī)驅(qū)動板,因此底板加了一塊散熱片,開發(fā)板的四腳加了腳墊,以便更好地散熱,防止底板電路與金屬物件接觸而導(dǎo)致短路。開發(fā)板采用ARM Cortex-M0的32位MCU,MCU最高工作頻率可達(dá)72MHz,內(nèi)置高速存儲器,豐富的I/O 端口和外設(shè)連接到外部總線。具有1個12位的ADC、1個比較器、1個16位通用定時器、1個32位通用定時器、3個16位基本定時器和1個16位高級定時器。還包含標(biāo)準(zhǔn)的通信接口,即1個I2C接口、1個SPI接口和1個UART接口。適合開發(fā)吊風(fēng)扇,電動工具,三相永磁無刷電機(jī)等多種應(yīng)用場合。
? ?? ? 由MM32SPIN160C的名稱可知該型號的基礎(chǔ)配置
? ?? ? 開發(fā)板主要功能列表:
①、輸入電壓范圍: 12V~28V
②、使用60V/40A N-MOS管*6
③、使用外掛(SPIN0x) GBW 6MHz 高速運(yùn)放*4
④、MCU 電源使用5V
⑤、支持有/無霍, 方波/弦波驅(qū)動
⑥、支持1/2 Shunt R 三相電流采樣
⑦、BEMF 電壓回授使用ADC 采樣
⑧、DC Bus 電壓, 總電流量測
⑨、使用MCU 內(nèi)建比較器做為過電流保護(hù)
? ?? ? 在淘寶上買了個尼得科無刷電機(jī),無刷電機(jī)最大優(yōu)點(diǎn)是沒有碳刷轉(zhuǎn)換器,壽命長,適合長時間工作的場所。
? ?? ?【額定電壓】DC 12V
? ?? ?【空載電流】1A
? ?? ?【額定功率】10W
? ?? ?【空載轉(zhuǎn)速】12000轉(zhuǎn)/分鐘
? ?? ?【適合電壓】6-12V(6000-12000轉(zhuǎn))
? ?? ?【重量】130克
? ?? ?? ? 電機(jī)的接口線路如下圖所示:
二、電路圖方面
? ?? ?關(guān)于該開發(fā)板的PCBA點(diǎn)位圖如下:
開發(fā)板的電路原理圖如下:
三、開發(fā)環(huán)境方面
板上集成了JLink調(diào)試接口,支持串行調(diào)試(SWD),官方提供的資源包中包括基本工程示例,可使用IAR、MDK工具打開,本人習(xí)慣使用MDK,因此將基本工程示例導(dǎo)入進(jìn)Keil中,如果電腦聯(lián)網(wǎng),此時會提示安裝“MindMotion.MM32SPIN0x_DFP.1.0.8”pack包;如果電腦處于離線狀態(tài),可從靈動微官網(wǎng)下載基于MM32SPIN160C開發(fā)板的pack包,如下附件,然后將pack導(dǎo)入Keil工具中,而后直接編譯即可。
將JLink燒錄器與開發(fā)板上的CN7接口相連接,Keil中設(shè)置SWD模式,即可識別到調(diào)試器,并設(shè)置燒錄后自動重啟。
然后將開發(fā)板上CN1、CN2、CN3與電機(jī)、電源適配器正確連接,由于板卡支持12~28V的電壓輸入,而電機(jī)的額定電壓是12V,因此采用12V/1A的電源適配器,實(shí)物連線圖如下:

采用不帶霍爾的輪詢控制方式,直接燒錄后,電機(jī)起震,沒有如期得向逆時針或順時針旋轉(zhuǎn),現(xiàn)象如同是前進(jìn)兩步后退兩步,一直在抖動。在線調(diào)試,發(fā)現(xiàn)驅(qū)動換相函數(shù)存在問題,每種無刷電機(jī)的接線有所差異。關(guān)于BLDC電機(jī),推薦看看TI的技術(shù)視頻教程深入理解無刷直流電機(jī)(BLDC)原理以及控制,關(guān)于有刷電機(jī)與無刷電機(jī)的工作原理如下:
??? ?
由上圖,有刷電機(jī)的主要結(jié)構(gòu)就是定子+轉(zhuǎn)子+電刷,通過旋轉(zhuǎn)磁場獲得轉(zhuǎn)動力矩,從而輸出動能。電刷與換向器不斷接觸摩擦,在轉(zhuǎn)動中起到導(dǎo)電和換相作用。有刷電機(jī)采用機(jī)械換向,磁極不動,線圈旋轉(zhuǎn)。電機(jī)工作時,線圈和換向器旋轉(zhuǎn),磁鋼和碳刷不轉(zhuǎn),線圈電流方向的交替變化是隨電機(jī)轉(zhuǎn)動的換相器和電刷來完成的。
? ? ?
?由上圖,無刷電機(jī)中,換相的工作交由控制器中的控制電路(一般為霍爾傳感器+控制器,更先進(jìn)的技術(shù)是磁編碼器)來完成。無刷電機(jī)采取電子換向,線圈不動,磁極旋轉(zhuǎn)。無刷電機(jī),是使用一套電子設(shè)備,通過霍爾元件,感知永磁體磁極的位置,根據(jù)這種感知,使用電子線路,適時切換線圈中電流的方向,保證產(chǎn)生正確方向的磁力,來驅(qū)動電機(jī),消除了有刷電機(jī)的缺點(diǎn)。
? ?? ? 四、工程源碼
部分源碼如下:
#include "sys.h"
typedef enum {
? ? CW? ?? ?= 0,? ? // 順時鐘方向
? ? CCW? ???= 1? ???// 逆時針方向
} motor_dir_t;
typedef enum {
? ? START? ?= 0,? ? // 啟動
? ? STOP? ? = 1,? ? // 停機(jī)
? ? RUN? ???= 2? ???// 運(yùn)行
} motor_state_t;
typedef struct{
? ? motor_dir_t tMotorDirection;? ?? ???// 電機(jī)旋轉(zhuǎn)方向
? ? motor_state_t tMotorState;? ?? ?? ? // 電機(jī)狀態(tài)
? ? uint16_t tDuty;? ?? ?? ?? ?? ?? ?? ?// 速度占空比:0~100??為100是占空比為100%
? ? uint16_t tSpeed;? ?? ?? ?? ?? ?? ???// 電機(jī)轉(zhuǎn)速
? ? uint8_t chHallValue;? ?? ?? ?? ?? ? // 霍爾狀態(tài)
? ? struct{
? ?? ???uint8_t chStartCount;? ?? ?? ???// 啟動計數(shù)
? ?? ???uint16_t hwTimeCount;? ?? ?? ???// 堵轉(zhuǎn)超時溢出計數(shù)
? ? }tCount;
}User_TypeDef_t;
volatile User_TypeDef_t g_tMotor = {
? ? CW,
? ? START,
? ? 40,
? ? 0,
? ? 1,
? ? 0,
? ? 0
};
extern void Bldc_Phase_Chaneg(uint8_t step);
extern void Hall_Exti_Callback(void);
extern void Systick_Callback(void);
int main(void)
{
? ? Systick_Init();
? ?
? ? Led_Init();
? ? Hall_Init();
? ? Bldc_Pwm_Init();
? ? Gate_Driver_Init();
? ? while(1) {
? ?? ???switch(g_tMotor.tMotorState) {
? ?? ?? ?? ?case START:? ?? ?? ?// 電機(jī)啟動
? ?? ?? ?? ?? ? if(++g_tMotor.tCount.chStartCount > 20){? ? //電機(jī)啟動失敗
? ?? ?? ?? ?? ?? ???g_tMotor.tMotorState = STOP;
? ?? ?? ?? ?? ?? ???g_tMotor.tCount.chStartCount = 0;
? ?? ?? ?? ?? ? }
? ?? ?? ?? ?? ? SET_DUTY_U(BLDC_TIM_PERIOD * g_tMotor.tDuty / 100);
? ?? ?? ?? ?? ? SET_DUTY_V(BLDC_TIM_PERIOD * g_tMotor.tDuty / 100);
? ?? ?? ?? ?? ? SET_DUTY_W(BLDC_TIM_PERIOD * g_tMotor.tDuty / 100);
? ?? ?? ?? ?? ? GATE_DRIVER_ENABLE();
? ?? ?? ?? ?? ? Hall_Exti_Callback();
? ?? ?? ?? ?? ? Systick_Delay(5);
? ?? ?? ?? ?? ? break;
? ?? ?? ?? ?case RUN:? ?? ?? ?// 電機(jī)運(yùn)行
? ?? ?? ?? ?? ? if (0){//some err
? ?? ?? ?? ?? ?? ???g_tMotor.tMotorState = STOP;
? ?? ?? ?? ?? ? }
? ?? ?? ?? ?? ? Hall_Exti_Callback();
? ?? ?? ?? ?? ? break;
? ?? ?? ?? ?case STOP:? ?? ?? ?// 停機(jī)
? ?? ?? ?? ?? ? GATE_DRIVER_DISABLE();
? ?? ?? ?? ?? ? BLDC_UH_DISABLE();
? ?? ?? ?? ?? ? BLDC_UL_DISABLE();
? ?? ?? ?? ?? ? BLDC_VH_DISABLE();
? ?? ?? ?? ?? ? BLDC_VL_DISABLE();
? ?? ?? ?? ?? ? BLDC_WH_DISABLE();
? ?? ?? ?? ?? ? BLDC_WL_DISABLE();
? ?? ?? ?? ?? ? break;
? ?? ???}
? ? }
}
void Bldc_Phase_Chaneg(uint8_t step)
{
? ? ? ? Systick_Delay(5);? ? //為了更好得看清楚,稍加延時
? ? ? ? switch(step) {
? ?? ???case 3: //A+ C-
? ?? ?? ?? ?BLDC_UH_ENABLE();
? ?? ?? ?? ?BLDC_UL_DISABLE();
? ?? ?? ?? ?BLDC_VH_DISABLE();;
? ?? ?? ?? ?BLDC_VL_DISABLE();
? ?? ?? ?? ?BLDC_WH_DISABLE();
? ?? ?? ?? ?BLDC_WL_ENABLE();
? ?? ?? ?? ?break;
? ?? ???case 1: //B+ C-
? ?? ?? ?? ?BLDC_UH_DISABLE();
? ?? ?? ?? ?BLDC_UL_DISABLE();
? ?? ?? ?? ?BLDC_VH_ENABLE();
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? BLDC_VL_DISABLE();
? ?? ?? ?? ?BLDC_WH_DISABLE();
? ?? ?? ?? ?BLDC_WL_ENABLE();
? ?? ?? ?? ?break;
? ?? ???case 5: //B+ A-
? ?? ?? ?? ?BLDC_UH_DISABLE();
? ?? ?? ?? ?BLDC_UL_ENABLE();
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ???BLDC_VH_ENABLE();
? ?? ?? ?? ?BLDC_VL_DISABLE();
? ?? ?? ?? ?BLDC_WH_DISABLE();
? ?? ?? ?? ?BLDC_WH_DISABLE();
? ?? ?? ?? ?break;
? ?? ???case 4: //C+ A-
? ?? ?? ?? ?BLDC_UH_DISABLE();
? ?? ?? ?? ?BLDC_UL_ENABLE();
? ?? ?? ?? ?BLDC_VH_DISABLE();
? ?? ?? ?? ?BLDC_VL_DISABLE();
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ???BLDC_WH_ENABLE();
? ?? ?? ?? ?BLDC_WL_DISABLE();
? ?? ?? ?? ?break;
? ?? ???case 6: //C+ B-
? ?? ?? ?? ?BLDC_UH_DISABLE();
? ?? ?? ?? ?BLDC_UL_DISABLE();
? ?? ?? ?? ?BLDC_VH_DISABLE();
? ?? ?? ?? ?BLDC_VL_ENABLE();
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ???BLDC_WH_ENABLE();
? ?? ?? ?? ?BLDC_WL_DISABLE();
? ?? ?? ?? ?break;
? ?? ???case 2: //A+ B-
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ?BLDC_UH_ENABLE();
? ?? ?? ?? ?BLDC_UL_DISABLE();
? ?? ?? ?? ?BLDC_VH_DISABLE();
? ?? ?? ?? ?BLDC_VL_ENABLE();
? ?? ?? ?? ?BLDC_WH_DISABLE();
? ?? ?? ?? ?BLDC_WL_DISABLE();
? ?? ?? ?? ?break;
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
? ?? ???default:
? ?? ?? ?? ?BLDC_UH_DISABLE();
? ?? ?? ?? ?BLDC_UL_DISABLE();
? ?? ?? ?? ?BLDC_VH_DISABLE();
? ?? ?? ?? ?BLDC_VL_DISABLE();
? ?? ?? ?? ?BLDC_WH_DISABLE();
? ?? ?? ?? ?BLDC_WL_DISABLE();
? ?? ?? ?? ?break;
? ? }
? ? ? ?
}
void Systick_Callback(void)
{
? ? if(RUN == g_tMotor.tMotorState) {
? ?? ???g_tMotor.tCount.hwTimeCount ++;
? ?? ???if(g_tMotor.tCount.hwTimeCount > 2000) { // 2s超時,電機(jī)卡住不運(yùn)轉(zhuǎn)超過2s時間
? ?? ?? ?? ?GATE_DRIVER_DISABLE();
? ?? ?? ?? ?BLDC_UH_DISABLE();
? ?? ?? ?? ?BLDC_UL_DISABLE();
? ?? ?? ?? ?BLDC_VH_DISABLE();
? ?? ?? ?? ?BLDC_VL_DISABLE();
? ?? ?? ?? ?BLDC_WH_DISABLE();
? ?? ?? ?? ?BLDC_WL_DISABLE();
? ?? ?? ?? ?g_tMotor.tMotorState = STOP;
? ?? ?? ?? ?g_tMotor.tCount.hwTimeCount = 0;
? ?? ???}
? ? }
}
void Hall_Exti_Callback(void)
{
? ? volatile uint8_t chStep = 0;
//? ? chStep = (uint8_t)((HALL_PORT_U->IDR >> HALL_PINSOURCE_U) |
//? ?? ?? ?? ?? ?? ?? ???(HALL_PORT_V->IDR >> (HALL_PINSOURCE_V - 1)) |
//? ?? ?? ?? ?? ?? ?? ???(HALL_PORT_W->IDR >> (HALL_PINSOURCE_W - 2))) & 0x07;
? ? if(g_tMotor.tMotorState == STOP) {
? ?? ???return;
? ? }
? ? if((HALL_PORT_U ->IDR & HALL_PIN_U) != (uint32_t)Bit_RESET) {
? ?? ???chStep |= 0x01;
? ? }
? ? if((HALL_PORT_V ->IDR & HALL_PIN_V) != (uint32_t)Bit_RESET) {
? ?? ???chStep |= 0x02;
? ? }
? ? if((HALL_PORT_W ->IDR & HALL_PIN_W) != (uint32_t)Bit_RESET) {
? ?? ???chStep |= 0x04;
? ? }
? ? ? ? ? ? ? ?
? ? if (g_tMotor.chHallValue != chStep) {? ?//判斷是否換向
? ?? ???g_tMotor.tMotorState = RUN;
? ?? ???g_tMotor.chHallValue = chStep ;
? ? }
? ? if(g_tMotor.tMotorDirection == CCW) {? ?// 方向判斷
? ?? ???chStep =??7 - chStep;
? ? }
? ? Bldc_Phase_Chaneg(chStep);? ? //驅(qū)動換相
? ? ? ?
? ? g_tMotor.tCount.hwTimeCount = 0;
}
? ???? Jumper設(shè)定為出廠設(shè)置狀態(tài),工程編譯后,燒錄完成,電機(jī)順利啟動,代碼中稍加了點(diǎn)延時,方便更清楚得看到電機(jī)的轉(zhuǎn)動,電機(jī)轉(zhuǎn)動又快又有勁,可與通用電動螺絲批相比較,但噪聲有點(diǎn)大,有待優(yōu)化。驅(qū)動工程源碼見如下附件,通過MM32SPIN160C電機(jī)驅(qū)動板的使用,體驗了靈動微MCU的庫函數(shù)與ST的相兼容,移植起來更便捷,如果靈動微有像ST一樣CubeMX開發(fā)工具就更強(qiáng)了。
下載程序源代碼等資料,請點(diǎn)擊閱讀原文!