#include <reg52.h> /********IO引腳定義***********************************************************/ sbit SW1=P1^0; //四個(gè)獨(dú)立按鍵定義 sbit SW2=P1^1; sbit SW3=P1^2; sbit SW4=P1^3; sbit SMG1 = P1^4; //數(shù)碼管第一位定義 sbit SMG2 = P1^5; //數(shù)碼管第二位定義 sbit SMG3 = P1^6; //數(shù)碼管第三位定義 sbit SMG4 = P1^7; //數(shù)碼管第四位定義 int table[]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x40}; //共陰極數(shù)碼管段值 unsigned char flag; //right(lhj[i+1],lhj[i+2]); //正轉(zhuǎn),兩個(gè)參數(shù)代表步進(jìn)量和轉(zhuǎn)速 /********數(shù)據(jù)定義***********************************************************/ // 512個(gè)脈沖 90度 unsigned char dataout[8]={0xf1,0xf2,0xf4,0xf8}; //這里我們定義4組數(shù),分別對(duì)應(yīng)四拍:A-B-C-D 從板上設(shè)計(jì)來分配,選擇P2口的低四位輸出 //P2。0為A相,P2。1為B相,P2。2為C相,P2。3為D相,將高四位都置1,也就是F。 //我們用索引的方式輸出,比如正轉(zhuǎn),元素由0到3這樣的循環(huán),反轉(zhuǎn)則由3到0的循環(huán) //程序中我們保存索引號(hào),比如上次轉(zhuǎn)在第2元素停下,則下次的正轉(zhuǎn)由3開始向后計(jì)數(shù),反轉(zhuǎn)則由1開始向前計(jì)數(shù) //這樣,電機(jī)的轉(zhuǎn)角度就會(huì)很精確 unsigned char datac=0; //存放索引號(hào)(元素號(hào)) unsigned int gStep = 0; unsigned long gMainchong = 0; unsigned int gJd = 0; unsigned int gKey_flag = 0; unsigned int b1,b2,b3; //臨時(shí)變量 void delayms(xms); void Timer0_Init(); void Display(); void rightAll(); void leftAll(); void stepAll(); void Ang(); void KeyScan(); /********函數(shù)聲明*************************************************************/ void right(unsigned int Speed,unsigned int road); //正轉(zhuǎn) void left(unsigned int Speed,unsigned int road); //反轉(zhuǎn) void mDelay(unsigned int DelayTime); //延時(shí)函數(shù) /***********主函數(shù)開始********************************************************/ void main() { unsigned char i=0; P2&=0XF0; //因ULN2003A直接驅(qū)動(dòng),為高電平輸出,初始時(shí)為低電平,這里一定不能少了 mDelay(100); Timer0_Init(); while(1) { KeyScan(); Ang(); } } /****************************************************************************** * 名稱: Timer0_Init() * 功能: 定時(shí)器0初始化 * 輸入: 無 * 輸出: 無 * 說明: ******************************************************************************/ void Timer0_Init() { TMOD=0x01; //定時(shí)器方式一 TH0=(65536-500)/256; //定義高字節(jié) TL0=(65536-500)%256; //定義低字節(jié) ET0=1; //計(jì)數(shù)器中斷 EA=1; //開總中斷 // TR0 = 1; } /****************************************************************************** /****************************************************************************** * 名稱: Set_Display() * 功能: 數(shù)碼管顯示函數(shù) * 輸入: 無 * 輸出: 無 * 說明: ******************************************************************************/ void Display() { //以下把num值區(qū)分開 以便數(shù)碼管顯示 b1=gJd%1000/100; //百位 b2=gJd%1000%100/10; //十位 b3=gJd%1000%100%10; //個(gè)位 P0=0x40; SMG1=0; //顯示"-" delayms(3); SMG1=1; P0=table[b1]; SMG2=0; //顯示百位 delayms(3); SMG2=1; P0=table[b2]; SMG3=0; //顯示十位 delayms(3); SMG3=1; P0=table[b3]; SMG4=0; delayms(3); //顯示個(gè)位 SMG4=1; } /***********左轉(zhuǎn),兩個(gè)參數(shù)代表步進(jìn)量和轉(zhuǎn)速*************************************/ void right(unsigned int Speed,unsigned int road) { //步進(jìn)節(jié)拍:A-B-C-D do{ if(datac==3) //索引號(hào)超出3回到0 datac=0; else datac++; P2=dataout[datac]; //這里就在P2口輸出我們定義好的相序步進(jìn),P2。0為A相,P2。1為B相,P2。2為C相,P2。3為D相 //這里我們不考慮P2的高四位,直接賦值 mDelay(road); //這里的延時(shí)就可控制轉(zhuǎn)速 Speed--; } while(Speed); P2&=0XF0; //將四個(gè)腳復(fù)位0 } /***********右轉(zhuǎn),兩個(gè)參數(shù)代表步進(jìn)量和轉(zhuǎn)速*************************************/ void rightAll() { if(gStep == 3) gStep = 0; else gStep++; P2=dataout[gStep]; if(gMainchong == 2048) gMainchong = 0; else gMainchong++; } /***********整體左轉(zhuǎn)*************************************/ void leftAll() { if(gStep == 0) gStep = 3; else gStep--; P2=dataout[gStep]; if(gMainchong == 0) // gMainchong = 4096; gMainchong = 2048; else gMainchong--; } /***********固定動(dòng)作*************************************/ void stepAll() { right(512, 50); left(1024, 50); right(215, 50); } /***********計(jì)算并顯示角度*************************************/ void Ang() // 計(jì)算角度 { unsigned int i; // gJd = gMainchong*5.625/32.0; gJd = gMainchong*11.25/64.0; b1=gJd%1000/100; //將得到的數(shù)據(jù)拆分,以便數(shù)碼管顯示 百位 b2=gJd%1000%100/10; //十位4 b3=gJd%1000%100%10; //個(gè)位 for(i=0;i<20;i++) Display(); //顯示20遍,防止顯示數(shù)據(jù)抖動(dòng),變化太快 } /***********反轉(zhuǎn),兩個(gè)參數(shù)代表步進(jìn)量和轉(zhuǎn)速*************************************/ void left(unsigned int Speed,unsigned int road) { //步進(jìn)節(jié)拍A-D-C-B do{ if(datac==0) //索引號(hào)超出0回到3 datac=3; else datac--; P2=dataout[datac]; //這里就在P2口輸出我們定義好的相序步進(jìn),P2。0為A相,P2。1為B相,P2。2為C相,P2。3為D相 //這里我們不考虛P2的低四位,直接賦值 mDelay(road); //這里的延時(shí)就可控制轉(zhuǎn)速 Speed--; } while(Speed); P2&=0XF0; //將四個(gè)腳復(fù)位0 } /***********延時(shí)函數(shù)*******************************************************/ void mDelay(unsigned int DelayTime) // 10ms { unsigned char j=0; while(DelayTime--) { for(j=0;j<10;j++){} } } // 延時(shí)函數(shù) void delayms(xms) { unsigned int x,y; for(x=xms;x>0;x--) for(y=110;y>0;y--) ; } /***********按鍵掃描函數(shù)*************************************/ void KeyScan() { if(SW1 == 0) { delayms(10); if(SW1 == 0) // 正傳 { TR0 = 0; gKey_flag = 1; // Timer0_Init(); TR0 = 1; } } if(SW2 == 0) { delayms(10); if(SW2 == 0) // 反傳 { TR0 = 0; gKey_flag = 2; Timer0_Init(); TR0 = 1; } } if(SW3 == 0) { delayms(10); if(SW3 == 0) // 自定義動(dòng)作 { TR0 = 0; gKey_flag = 3; Timer0_Init(); TR0 = 1; } } if(SW4 == 0) { delayms(10); if(SW4 == 0) // 停止 { TR0 = 0; gKey_flag = 0; Timer0_Init(); TR0 = 1; } } } /****************************************************************************** * 名稱: T0_int() interrupt 1 * 功能: 定時(shí)器0 中斷函數(shù) * 輸入: 無 * 輸出: 無 * 說明: ******************************************************************************/ void T0_int() interrupt 1 { // flag=1; //標(biāo)志位之一 TR0 = 0; switch(gKey_flag) { case 0x00: P2&=0XF0; break; case 0x01: rightAll(); TH0=(65536-10000)/256; //定義高字節(jié) TL0=(65536-10000)%256; //定義低字節(jié) TR0 = 1; break; case 0x02: leftAll(); TH0=(65536-10000)/256; //定義高字節(jié) TL0=(65536-10000)%256; //定義低字節(jié) TR0 = 1; break; case 0x03: stepAll(); break; default: break; } }
|