工作原理見書《51單片機應用及原理——基於KeilC和Proteus,陳海宴》P178-180 ...
————————————————————————————————————————————
工作原理見書《51單片機應用及原理——基於KeilC和Proteus,陳海宴》P178-180
————————————————————————————————————————————
步進電機控制應用實例
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
設計要求:
- 採用定時中斷方式控制步進機的轉速,定時單位時長為10ms。
- 速度設置在1/2/3/4四個檔位,1檔最快,依次遞減,能夠控制步進電機的停、轉和方向,同時顯示步進機的當前檔位。
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
設計思路:
- 通過P1控制步進電機的轉動,P1.0->a,P1.1->b,P1.2->c,P1.3->d,ULN2003A作為步進電機驅動
- P2.0-P2.3對應數位管顯示(使用7447晶元對應將BCD碼轉換成7端LED數位管),通過7447簡單驅動數位管(P2只需要發送1/2/3/4即可)
- 通過定時器計數,到達設定值時步進電機轉動1/4圈,計數清零
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
元件清單:
- AT89C51
- BUTTON
- MOTOR-STEPPER
- RESPACK-8
- 7SEG-COM-ANODE
- ULN2003A
- 7447
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
實現代碼:
1 #include <reg52.h> 2 typedef unsigned char uchar; 3 uchar direction = 0; //0為正轉,1為反轉 4 uchar onoff = 0; //關為0,開為1 5 uchar n = 0; //每次定時器中斷觸發時n++,當n==max時電機轉動1/4 6 uchar max = 10; 7 uchar index = 0; //通過index指示電機轉動,AB,BC,CD,DA 8 sbit LED = P3 ^ 7; //當n==max時LED閃爍提示 9 int main() 10 { 11 /* LED */ 12 P2 = 0xff; 13 /* 初始化中斷 */ 14 EA = 1; 15 EX0 = 1; //要用到的中斷是兩個外部中斷和定時器中斷0 16 IT0 = 1; 17 EX1 = 1; 18 IT1 = 1; 19 ET0 = 1; 20 /* 定時器0 */ 21 TMOD = 0x01; //使用定時器0,方式1 22 TH0 = (65536 - 10000) / 256; //12MHz晶振下,定時器為10ms觸發中斷,更方便觀察轉動情況 23 TL0 = (65536 - 10000) % 256; 24 TR0 = 1; 25 while(1) 26 { 27 switch(P0) 28 { 29 case 0xfe: //11111110 30 max = 1; 31 P2 = 1; 32 break; 33 case 0xfd: //11111101 34 max = 10; 35 P2 = 2; 36 break; 37 case 0xfb: //11111011 38 max = 50; 39 P2 = 3; 40 break; 41 case 0xf7: //11110111 42 max = 100; 43 P2 = 4; 44 break; 45 } 46 } 47 } 48 void Stop()interrupt 0 49 { 50 onoff++; 51 if (onoff > 1) 52 onoff = 0; 53 } 54 void int1()interrupt 2 55 { 56 direction++; 57 if (direction > 1) 58 direction = 0; 59 } 60 void delay50ms(void) 61 { 62 unsigned char a, b; 63 for(b = 173; b > 0; b--) 64 for(a = 143; a > 0; a--); 65 } 66 void time()interrupt 1 67 { 68 TH0 = (65536 - 10000) / 256; 69 TL0 = (65536 - 10000) % 256; 70 if (onoff == 1) //在開狀態下 71 { 72 if (n == max) //設定檔位速度,經過了max次中斷後,步進電機轉1/4圈 73 { 74 LED = 0; //每次n==max時LED閃爍 75 delay50ms(); 76 LED = 1; 77 if (direction == 0) 78 { 79 switch(index) //正轉時以AB,BC,CD,DA順序 80 { 81 case 0:P1 = 0x03;break; //00000011 AB高電平 82 case 1:P1 = 0x06;break; //00000110 BC高電平 83 case 2:P1 = 0x0c;break; //00001100 CD高電平 84 case 3:P1 = 0x09;break; //00001001 DA高電平 85 } 86 index ++; 87 if (index == 4) //步進電機轉完一圈時index清零 88 index = 0; 89 n = 0; //到達max,n重置為0 90 } 91 if (direction == 1) 92 { 93 switch(index) //反轉時以DA,CD,BC,AB順序 94 { 95 case 0:P1 = 0x09;break; 96 case 1:P1 = 0x0c;break; 97 case 2:P1 = 0x06;break; 98 case 3:P1 = 0x03;break; 99 } 100 index ++; 101 if (index == 4) 102 index = 0; 103 n = 0; 104 } 105 else n = 0; 106 } 107 n++; //n!=max時,n++ 108 } 109 else n = 0; //在關狀態下,n始終為0,無法觸發電機轉動 110 }