51單片機(jī)控制四相步進(jìn)電機(jī)作者:易勁松 QQ:371719025 Email:yijingsong@ 接觸單片機(jī)快兩年了,不過只是非常業(yè)余的興趣,實(shí)踐卻不多,到現(xiàn)在還算是個初學(xué)者吧這幾天給自己的任務(wù)就是搞定步進(jìn)電機(jī)的單片機(jī)控制以前曾看過有關(guān)步進(jìn)電機(jī)原理和控制的資料,畢竟自己沒有做過,對其具體原理還不是很清楚今天從淘寶網(wǎng)買了一個EPSON的UMX-1型步進(jìn)電機(jī),此步進(jìn)電機(jī)為雙極性四相,接線共有六根,外形如下圖所示: 拿到步進(jìn)電機(jī),根據(jù)以前看書對四相步進(jìn)電機(jī)的了解,我對它進(jìn)行了初步的測試,就是將5伏電源的正端接上最邊上兩根褐色的線,然后用5伏電源的地線分別和另外四根線(紅、蘭、白、橙)依次接觸,發(fā)現(xiàn)每接觸一下,步進(jìn)電機(jī)便轉(zhuǎn)動一個角度,來回五次,電機(jī)剛好轉(zhuǎn)一圈,說明此步進(jìn)電機(jī)的步進(jìn)角度為360/(4×5)=18度地線與四線接觸的順序相反,電機(jī)的轉(zhuǎn)向也相反 如果用單片機(jī)來控制此步進(jìn)電機(jī),則只需分別依次給四線一定時間的脈沖電流,電機(jī)便可連續(xù)轉(zhuǎn)動起來通過改變脈沖電流的時間間隔,就可以實(shí)現(xiàn)對轉(zhuǎn)速的控制;通過改變給四線脈沖電流的順序,則可實(shí)現(xiàn)對轉(zhuǎn)向的控制所以,設(shè)計了如下電路圖: 制作的實(shí)物圖如下: C51程序代碼為:代碼一#include static unsigned int count;static unsigned int endcount;void delay();void main(void) {? count = 0;? P1_0 = 0;? P1_1 = 0;? P1_2 = 0;? P1_3 = 0; EA = 1;????????????? //允許CPU中斷 ? TMOD = 0x11;? //設(shè)定時器0和1為16位模式1 ? ET0 = 1;???????????? //定時器0中斷允許 TH0 = 0xFC; ? TL0 = 0x18;????? //設(shè)定時每隔1ms中斷一次? ? TR0 = 1;?????????? //開始計數(shù)startrun:? ? P1_3 = 0;? P1_0 = 1;? delay();? P1_0 = 0;? P1_1 = 1;? delay();? P1_1 = 0;? P1_2 = 1;? delay();? P1_2 = 0;? P1_3 = 1;? delay();? goto startrun;} //定時器0中斷處理 void timeint(void) interrupt 1 { ? TH0=0xFC; ? TL0=0x18; //設(shè)定時每隔1ms中斷一次? count++;}void delay(){? endcount=2;? count=0;? do{}while(count
所以,我將程序代碼改進(jìn)了一下,如下:代碼二#include static unsigned int count;static int step_index;void delay(unsigned int endcount);void gorun(bit turn, unsigned int speedlevel);void main(void) {? count = 0;? step_index = 0;? P1_0 = 0;? P1_1 = 0;? P1_2 = 0;? P1_3 = 0;? EA = 1;???????????? //允許CPU中斷 ? TMOD = 0x11; //設(shè)定時器0和1為16位模式1 ? ET0 = 1;??????????? //定時器0中斷允許 TH0 = 0xFE; ? TL0 = 0x0C;? //設(shè)定時每隔0.5ms中斷一次? ? TR0 = 1;???????? //開始計數(shù)? do{??? gorun(1,60);? }while(1);} //定時器0中斷處理 void timeint(void) interrupt 1 { ? TH0=0xFE; ? TL0=0x0C; //設(shè)定時每隔0.5ms中斷一次? count++;}void delay(unsigned int endcount){? count=0;? do{}while(count7)????? step_index=0;? }? else? {??? step_index--;??? if (step_index<0)????? step_index=7;? }??? } 改進(jìn)的代碼能實(shí)現(xiàn)速度和方向的控制,而且,通過step_index靜態(tài)全局變量能“記住”步進(jìn)電機(jī)的步進(jìn)位置,下次調(diào)用 gorun()函數(shù)時則可直接從上次步進(jìn)位置繼續(xù)轉(zhuǎn)動,從而實(shí)現(xiàn)精確步進(jìn);另外,由于利用了步進(jìn)電機(jī)內(nèi)線圈之間的“中間狀態(tài)”,步進(jìn)角度減小了一半,只為9度,低速運(yùn)轉(zhuǎn)也相對穩(wěn)定一些了。
但是,在代碼二中,步進(jìn)電機(jī)的運(yùn)轉(zhuǎn)控制是在主函數(shù)中,如果程序還需執(zhí)行其它任務(wù),則有可能使步進(jìn)電機(jī)的運(yùn)轉(zhuǎn)收到影響,另外還有其它方面的不便,總之不是很完美的控制所以我又將代碼再次改進(jìn):代碼三#include static unsigned int count;? //計數(shù)static int step_index;? //步進(jìn)索引數(shù),值為0-7static bit turn;? //步進(jìn)電機(jī)轉(zhuǎn)動方向static bit stop_flag;? //步進(jìn)電機(jī)停止標(biāo)志static int speedlevel; //步進(jìn)電機(jī)轉(zhuǎn)速參數(shù),數(shù)值越大速度越慢,最小值為1,速度最快static int spcount;??? //步進(jìn)電機(jī)轉(zhuǎn)速參數(shù)計數(shù)void delay(unsigned int endcount);?//延時函數(shù),延時為endcount*0.5毫秒void gorun();????????? //步進(jìn)電機(jī)控制步進(jìn)函數(shù)void main(void) {? count = 0;? step_index = 0;? spcount = 0;? stop_flag = 0;P1_0 = 0;? P1_1 = 0;? P1_2 = 0;? P1_3 = 0;EA = 1;??????????? ?//允許CPU中斷 ? TMOD = 0x11; //設(shè)定時器0和1為16位模式1 ? ET0 = 1;?????????? //定時器0中斷允許 TH0 = 0xFE;? TL0 = 0x0C;?? //設(shè)定時每隔0.5ms中斷一次? TR0 = 1;???????? //開始計數(shù)?turn = 0;speedlevel = 2;? delay(10000);? speedlevel = 1;? do{??? speedlevel = 2;??? delay(10000);??? speedlevel = 1;??? delay(10000);??? stop_flag=1;??? delay(10000);??? stop_flag=0;? }while(1);} //定時器0中斷處理 void timeint(void) interrupt 1 { ? TH0=0xFE;? TL0=0x0C; //設(shè)定時每隔0.5ms中斷一次? count++;? spcount--;? if(spcount<=0)? {??? spcount = speedlevel;??? gorun();? }}void delay(unsigned int endcount){? count=0;? do{}while(count