1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
| /\* Main.c file generated by New Project wizard \* \* Created: 周二 6月 28 2022 \* Processor: AT89C51 \* Compiler: Keil for 8051 \*/ /\*----------------------------------------------- 名称:步进电机 内容:本程序用于测试4相步进电机常规驱动 使用1-2相励磁 1-2相激励功率增倍,步进角度减半,抖动减少 顺序如下 a-ab-b-bc-c-cd-d-da 又称4相8拍 数码管显示 40-90速度等级,数字越大,速度越慢 ------------------------------------------------\*/
#include <reg52.h> typedef unsigned char uchar; typedef unsigned int uint; #define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0 替换 #define out\_port (P1) sbit LATCH1=P2^2;//定义锁存使能端口 段锁存 sbit LATCH2=P2^3;// 位锁存 uchar const sequence[8] = {0x02,0x06,0x04,0x0c,0x08,0x09,0x01,0x03}; unsigned char code DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值0~9 unsigned char code WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码 unsigned char TempData[8]; //存储显示值的全局变量
sbit A1=P1^0; //定义步进电机连接端口 sbit B1=P1^1; sbit C1=P1^2; sbit D1=P1^3;
unsigned char Speed;
void Display(unsigned char FirstBit,unsigned char Num); void Init\_Timer0(void);
/\*------------------------------------------------ mS延时函数,含有输入参数 unsigned char t,无返回值 unsigned char 是定义无符号字符变量,其值的范围是 0~255 这里使用晶振12M,精确延时请使用汇编 ------------------------------------------------\*/ void DelayMs(uint j) { uchar i; for(; j>0; j--) { i = 120; while (i--); } } /\*------------------------------------------------ 主函数 ------------------------------------------------\*/ void main() {uchar i; Init\_Timer0(); EA=1; //全局中断开 EX0=1; //外部中断0开 IT0=1; //1表示边沿触发
Speed=40; TempData[0]= DuanMa[Speed/10];//分解显示信息,如要显示68, TempData[1]= DuanMa[Speed%10];//则68/10=6 68%10=8 out_port = 0x03; while(1) { i = i<8 ? i+1 : 0; out_port = sequence[i]; DelayMs(Speed); //改变这个参数可以调整电机转速 , //数字越小,转速越大,力矩越小 } }
/\*------------------------------------------------ 外部中断程序 ------------------------------------------------\*/ void ISR\_INT0(void) interrupt 0 { if(!INT0) { DelayMs(10);//在此处可以添加去抖动程序,防止按键抖动造成错误 if(!INT0) //while(!INT1);//等待按键释放 { Speed +=10; if(Speed==100) Speed=40; TempData[0]= DuanMa[Speed/10];//分解显示信息,如要显示68, TempData[1]= DuanMa[Speed%10];//则68/10=6 68%10=8 } } } /\*------------------------------------------------ 显示函数,用于动态扫描数码管 输入参数 FirstBit 表示需要显示的第一位,如赋值2表示从第三个数码管开始显示 如输入0表示从第一个显示。 Num表示需要显示的位数,如需要显示99两位数值则该值输入2 ------------------------------------------------\*/ void Display(unsigned char FirstBit,unsigned char Num) { static unsigned char i=0;
DataPort=0; //清空数据,防止有交替重影 LATCH1=1; //段锁存 LATCH1=0;
DataPort= WeiMa[i+FirstBit]; //取位码 LATCH2=1; //位锁存 LATCH2=0;
DataPort=TempData[i]; //取显示数据,段码 LATCH1=1; //段锁存 LATCH1=0; i++; if(i==Num) i=0;
} /\*------------------------------------------------ 定时器初始化子程序 ------------------------------------------------\*/ void Init\_Timer0(void) { TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响 //TH0=0x00; //给定初值 //TL0=0x00; EA=1; //总中断打开 ET0=1; //定时器中断打开 TR0=1; //定时器开关打开 PT0=1; //优先级打开 } /\*------------------------------------------------ 定时器中断子程序 ------------------------------------------------\*/ void Timer0\_isr(void) interrupt 1 { TH0=(65536-2000)/256; //重新赋值 2ms TL0=(65536-2000)%256; Display(0,8);
}
|