FPGA研途之路——永遠的步進(一)
本例用的是Alinx的FPGA開發(fā)板,其主控芯片用的是cyclonelVCE6系列,后續(xù)因為要學習BLDC的驅(qū)控,就先拿步進電機練練手。既然是(一),程序.上肯定并不復(fù)雜,只實現(xiàn)簡單的加減速及正反轉(zhuǎn),后續(xù)學習閉環(huán)驅(qū)動。
以兩相電機為例,步進電機驅(qū)動器和控制器的接線方式有共陰和共陽兩種接
法,不同的接法會導(dǎo)致程序的電平輸出不同,程序中應(yīng)格外注意。VCC3.3也能夠驅(qū)動,不排除有些驅(qū)動器的TTL電平高些,所以有時I/O還會外接放大電路。


下圖是整個程序的netlist,功能模塊上有以下幾個:
4個按鍵輸入,分別用于加減速、使能及換向(圖中的四個key,fliter用于按鍵消抖) ;
對按鍵輸入累加速度(r/s),計算并轉(zhuǎn)化為脈沖定時器count_max的值(module pulse_caculate) ;
speed_ctr|用于最后的脈沖生成、EN和DIR控制。

????????上述三個功能模塊實現(xiàn)過程中,對于新手需要注意的就是pulse_caculate。 我的想法是通過按鍵直接控制轉(zhuǎn)速的加減,所以必然涉及到轉(zhuǎn)速到脈沖頻率的轉(zhuǎn)換。當然這個計算肯定是小問題,問題出在verilog描述上。不同于C/C++等高級語言,verilog在進行數(shù)學運算時大多數(shù)情況是不能直接進行乘除法的運算的。最開始我直接使用下面的計算公式:?
num<=1000_000_000/(2*1600*speed*T)
????????其中num是脈沖定時器的載入值,之后傳給speed_ ctrl模塊進行定時生成脈沖; speed是轉(zhuǎn)速(單位r/s) ; T是時鐘周期; 1600是細分。
編譯后進行modelsim仿真,發(fā)現(xiàn)num[31:0]的值一直處于不定狀態(tài),搜攻略才注意到這個問題是入門很常見的問題。對于--些簡單的乘除法,quatus有 時會自動生成乘法/除法器,這個時候就不需要自己去創(chuàng)建算術(shù)IP核。但大多是時候,保險起見還是需要自行創(chuàng)建除法器。
????????quatus現(xiàn)成的除法器IP核有兩個,分別是LPM_ DIVIDE和ALTEF_ DIV。LPM_ DIVIDE相當于"/ "運算,會生成商和余數(shù); ALTEF_ DIV則是浮點運算,精度會更高。具體了解看以下鏈接。

verilog中浮點數(shù)的表示以及浮點數(shù)除法IP核的使用
https://mbb.eet-china.com/blog/1835172-370138.html
IP核的使用---乘法器和除法器
?https://www.freesion.com/article/5077434666/



下圖是pulse_ caculate的netlist,可以看到生成了名為ip_divider的除法器

????????話不多說,貼上關(guān)鍵module的代碼。通過這個實驗也能發(fā)現(xiàn),給步進電機驅(qū)動器的脈沖過快的直接現(xiàn)象就是,步進電機變成蜂鳴器,只響不轉(zhuǎn)。最開始頻率過高,整的我懷疑程序編錯了。。。。
????????另外一個就是,轉(zhuǎn)速過高時直接進行換向必然會造成丟步,因為這各例子很簡單,不涉
及到加減速曲線,所以都是階梯跳變。
????????后續(xù)上閉環(huán),寫下此帖用于心得記錄和分享。