很早之前就想做一款無刷電機控制器,忙于工作一直沒有弄。最近有點時間畫板,打樣,焊接,調試,總算順利的轉起來。期間也遇到很多問題,上網查資料,自己量波形前前后后搞了差不多近一個月,(中間又出差一周)總算搞的差不多了,特意寫個總結。
板子外觀 100*60mm 中等大小。DC 12V 輸入,設計最大電流 10A.(實際沒試過那么大的電機,手頭的電機也就 5 6A 的樣子)硬件上可以切換有感(HALL)和無感(EMF)兩種模式,外部滑動變阻器調速 預留有 PWM 輸入、剎車、正反轉、USB 和 uart 等接口。
先來說下原理無刷電機其實就是直流電機,和傳統的 DC 電機是一樣的,只是把有刷的電滑環變成了電子換向器。

因為少了電滑環的摩擦所以壽命靜音方面有了很大的提升,轉速也更高。

當然難點就在如何獲取當前轉子的位置好換相,所以又分為兩種有感和無感。
有感就是在電機端蓋的部位加裝霍爾傳感器分別相隔 30 度或 60 度。無感就是靠檢測懸浮相的感應電動勢過零點(后面在細講)。
當然各有各的優缺點,有感在低速方面好,可以頻繁啟停換相。無感的結構簡單成本低,航模上應用居多。
先說有感,電源首先被分成了 3 個繞組 U V W 這個交流電還是有區別的。
它只是 3 個 h 橋按一定的順序導通模擬出來的,本質還是直流電。電機靠 hall 位置按一定順序換相,轉速與電壓電流有關。這一點切記,不是換的越快轉的越快。(位置決定換相時刻,電壓決定轉速)一般調速就是調電壓,6 步 pwm 方式是目前常用的。當然后續還有 foc 等更好算法。
硬件部分網上基本都是成熟的方案。三相 H 橋,H 橋一般有上臂 mos 和下臂 mos 組成,如果只是簡單的做演示上臂選 pmos 下臂選 nmos 控制電路簡單直接用單片機的 io 就可以驅動。但是 pmos 低內阻的價格高。功率上面很難做大。
這也就是為什么基本所有的商業控制器全是 nmos 的原因。
但是上臂用 nmos 存在一個問題 vgs 控制電壓大與 vcc 4v 以上才能完全導通。為了簡化電路采用了 ir 公司出的驅動 ic,它內部有自舉升壓電路。外部僅需一個續流的二極管及儲能電容即可。


有感模式控制相對簡單,3 個霍爾傳感器輸出一般都是數字信號,分壓后直接接單片機 io。

當然控制方式上也就簡單很多,三個霍爾接中斷輸入,在中斷處理程序中根據組合狀態換相,程序上也沒什么復雜的。主程序 一直檢測 ad 值,改變 pwm 占空比,及電流保護等。
如下一個典型的換相代碼。Stm32 有兩個高級定時器 tim1 tim8 可以輸出 4 組互補型 pwm,還可以設定死區時間等,使用上非常方便。
switch(step)
{
case 4: //B+ C-
/* Next step: Step 2 Configuration -------------------------------------- */
TIM_CCxCmd(BLDC_TIMx,TIM_Channel_1,TIM_CCx_Disable);
TIM_CCxNCmd(BLDC_TIMx,TIM_Channel_1,TIM_CCxN_Disable);
}


下圖為 uvw 三相的霍爾檢測到的電平及 w 相的波形。

下圖為 uvw 三相波形及 w 相霍爾電平

下圖為 w 相電平, w 相上臂 on 下臂 pwm ,w 相霍爾信號。

下圖為 w 相 ir2304 芯片輸出,上臂電壓可明顯看到已高于 vcc,下臂為 pwm 信號

在說說無感模式,由于沒有了霍爾,電機無法知道轉子當前的位置所以就無法換相,而感應電動勢也只有在轉起來之后才有,所以無感模式的啟動是個難點。
一般方法都是分三段法:1 預定位 2 啟動 3 進入閉環反饋
正如網友說的江湖一層紙,戳破不值半文錢。
1. 預定為就是強制給某一相通電一段時間,讓電機定位到這個位置。占空比 30-50%不要太大,可能會發熱。
2. 啟動,就是逐步的強制換相,當然要有個加速的過程,使電機轉起來。
這個過程太慢會抖動反轉,太快會丟步。參數需要一點點試,有點像控制步進電機。要能使電機轉的能產生電動勢,我也是參照的德國 MK 電調的算法。
每次延時時間比上一次少 1/25,形成一個加速的過程,直到電機完全轉起來產生足夠的電動勢。
3. 閉環反饋控制換相跟有感差不多一樣。
speed_duty=30; //30% start
BLDC_PHASE_CHANGE(Step[Phase]); // 固定一相
Delay_MS(200);
speed_duty=pwm;
timer = 300;
while(1)
{
for(i=0;i<timer; i++)
{
Delay_US(120); // 等待
}
timer-= timer/25+1;
if(timer < 25)
{
if(TEST_MANUELL)
{
timer = 25; // 開環強制換向
}
else
{
bldc_dev.motor_state=RUN;
break;
}
}
Phase++;
Phase %= 6;
BLDC_PHASE_CHANGE(Step[Phase]); //
}
說到感應電動勢很多人不明白,先來說說電流,電機線圈的內阻通常很小比如 0.2 歐,電機的電壓比如 10v,按理來說電流 100a 為何電機不燒哪?
其實電機線圈在通電的一瞬間并不是完全導通的,因為有反向電動感應勢的存在,可能有 -9.8v。10v-9.8v = 0.2v /0.2 = 1A. 這樣算起來電流還合理。
在說說那個初中學習的法拉第 ,當線圈切割磁場時會產生感應電動勢,根據右手定則。。。。。。。。不懂的自行上網搜。

如下圖當 ac 相在通電 12v 的情況下,靜止狀態下正中間中性點理論為 6v,但是轉起來就不一定了,因為 b 相實際是在切割磁場,是會產生電動勢的。而電動勢的大小正負取決與當前在磁場 ns 極的位置。當切割 ns 時為 -1,切割 sn 時為 1,平行時為 0.

利用這一特性不就剛好可以獲得轉子的位置嗎?
首先檢測電路網上已經一大很成熟了。
如下圖,當然很多時候需要在 4.7k 對地的電阻上并一個 100nf 的電容,做一個低通濾波。也可以在軟件中做濾波處理。

我們所要做的就是檢測這個懸浮相的電動勢過零點。
網上常用的兩種方法:1 單片機 ad 采集;2 比較器比較。我選擇了比較器 lm339 價格已經很便宜了,在高速上比 ad 有明顯優勢,只要比較 cin bin ain 與 n 點的壓差即可獲得零點。

理想很完美,現實很殘酷,實際中根本得不到這么完美的波形。
如下圖,這個已經是比較好的了,還是有很多毛刺。這個給單片機中斷,肯定一大堆問題,嚴重的換錯相燒 mos 管。


為什么會有這些毛刺呢,有些還挺有規律。
參考了網上的介紹,這中間還有一個叫消磁的東西。

原理不深究了,反正時間很短,軟件上做一個濾波消掉就可以了。
進入中斷函數后做如下處理 ,定時器的中斷我暫時用的 20us。
const unsigned int FilterNums = 0xff;
static unsigned int nums =0;
static unsigned int Queue_UStatus =0;
static unsigned int Queue_VStatus =0;
static unsigned int Queue_WStatus =0;
static unsigned char EMF_SVal =0;
unsigned char Filter_U_Status=0;
unsigned char Filter_V_Status=0;
unsigned char Filter_W_Status=0;
unsigned char EMF_Val=0;
unsigned int status_h;
unsigned int status_l;
unsigned int Delay30deg =0;
/* 清除中斷標志位 */
if ( TIM_GetITStatus(TIM3 , TIM_IT_Update) != RESET )
{
TIM_ClearITPendingBit(TIM3 , TIM_FLAG_Update);


至于網上說檢測到過零點后,延時 30 度換相,對電源效率有影響。我試了下,好像沒什么明顯的差異。也有人說在大功率的電機下不延時反而更平滑等等。真實怎樣有待各位實際實驗了。
最后秀幾張轉起來的照片


硬盤電機 無感模式

電動工具電機 有感模式

加裝散熱片的樣子
|