————————————————————————————————————————————
工作原理见书《51单片机应用及原理——基于KeilC和Proteus,陈海宴》P178-180
————————————————————————————————————————————
步进电机控制应用实例
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
设计要求:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
设计思路:
- 通过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 }