步进电机实际上产生了一个可旋转的磁场。当旋转磁场依次切换时,转子将旋转相应的角度。当磁场旋转过快或转子上负载的旋转惯性过大时,转子无法跟上步伐失步。
直接到主题,控制步进电机的旋转实际上是控制磁场的方向。通过改变磁场的方向来改变施加和转子的扭矩。以下是五线四相步进电机。原理图如下:
:ULN2003年达林顿结构芯片具有很强的驱动能力。现有的驱动板可用于驱动步进电机。我们只需要选择杜邦线连接驱动板的单片机四个输出端口IN1、IN2、IN3、IN4,然后用外部电源连接驱动板5-12V 接口、电源和单片机的地面(GND)与驱动板的(–)共线即可。
uchar code type_dan[]={0x01,0x02,0x04,0x08}//单相励磁,扭矩大 uchar code type_shuang[]={0x09,0x03,0x06,0x0c};///双向励磁 uchar code type_dan_shuang[]={0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09}
步进电机的旋转由四个独立按钮控制,S1正转,S2反转,S3停转,S4调整速度10级可调,当前速度等级用数字管显示。
#include <REGX52.H> typedef unsigned char uchar; typedef unsigned int uint; uchar code type_dan_shuang_1[]={0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09}//正转相序表 uchar code type_dan_shuang_2[]={0x09,0x08,0x0c,0x04,0x06,0x02,0x03,0x01} uchar code type1[]={ 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xff };//段选 uchar code type2[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};//位选 uchar num1,num2,num3,num4,num5,num6,num7,num8; bit f_2ms; uchar t_2ms,t_200us; uchar GN,HN; uchar speed=4; void Delay10ms() //@11.0592MHz { unsigned char i, j; i = 108; j = 145; do { while (--j); } while (--i); } void Delay(uint num) { while(num--); } ///数字管显示函数 void smg_display(char n1,char n2,char n3,char n4,char n5,char n6,char n7,char n8) { char i; P0=0xff; P2=(P2&0x1f)|0xc0; P0=type2[i]; P2=(P2&0x1f); switch(i) { case 0:P2=(P2&0x1f)|0xe0; P0=type1[n1]; P2=(P2&0x1f);break; case 1:P2=(P2&0x1f)|0xe0; P0=type1[n2]; P2=(P2&0x1f);break; case 2:P2=(P2&0x1f)|0xe0; P0=type1[n3]; P2=(P2&0x1f);break; case 3:P2=(P2&0x1f)|0xe0; P0=type1[n4]; P2=(P2&0x1f);break; case 4:P2=(P2&0x1f)|0xe0; P0=type1[n5]; P2=(P2&0x1f);break; case 5:P2=(P2&0x1f)|0xe0; P0=type1[n6]; P2=(P2&0x1f);break; case 6:P2=(P2&0x1f)|0xe0; P0=type1[n7]; P2=(P2&0x1f);break; case 7:P2=(P2&0x1f)|0xe0; P0=type1[n8]; P2=(P2&0x1f);break; } if( i==1) i=0; } 独立按键 uchar key_scan() { uchar temp; temp=(~P3)&0x0f; if(temp==0) return 0; Delay10ms(); temp=(~P3)&0x0f; if(temp==0) return 0; return temp; } void key_change() { uchar D; D=key_scan(); switch(D) { case 8:GN=4;break; case 4:GN=5;break; case 2:GN=6;break; case 1:HN=7;break; case 0:HN=0;break; } } //配置定时器1 void time1_int1() { EA=1; ET1=1; TR1=1; TMOD=(TMOD&0x0f)|0x10; TH1=(65536-200)/256; TL1=(65536-200)%6; } ///所有外设的初始化 void initial_all() { P2=(P2&0x1f)|0xa0; P0=0x00; P2=(P2&0x1f); P2=(P2&0x1f)|0x80; P0=0xff; P2=(P2&0x1f); P2=(P2&0x1f)|0xc0; P0=0xff; P2=(P2&0x1f); P2=(P2&0x1f)|0xe0; P0=0xff; P2=(P2&0x1f); } void main() { char i; initial_all(); ///初始化外设 time1_int1(); ///初始化定时器 num1=num2=num3=num4=num5=num6=num7=num8=10.//关闭所有数字管显示器 while(1) { if(f_2ms==1) { f_2ms=0; key_change(); num1=speed-4; if(GN==4) ///步进电机正传 { EA=0; P2=(P2&0x1f)|0xa0; //打开锁存器 P0=(type_dan_shuang_1[i] & 0x0f)|type_dan_shuang_1[i]; //输入旋转相续数 if( t_200us == speed) ///速度调节 { t_200us=0; i(++i==8)
i=0;
}
P2=(P2&0x1f); //关闭锁存器
EA=1;
}
if(GN==5) //步进电机反转
{
EA=0;
P2=(P2&0x1f)|0xa0;
P0=(type_dan_shuang_2[i] & 0x0f)|type_dan_shuang_2[i];
if(++t_200us == speed)
{
t_200us=0;
if(++i==8)
i=0;
}
P2=(P2&0x1f);
EA=1;
}
if(GN==6) //步进电机停止
{
EA=0;
P2=(P2&0x1f)|0xa0;
P0=0000;
P2=(P2&0x1f);
EA=1;
}
if(HN==7) //速度调节
{
if(++speed==14)
speed=4;
while(key_scan());
}
}//f_2ms
}
}
void cl_time1_int1() interrupt 3 //定时器中断1处理函数
{
TH1=(65536-200)/256;
TL1=(65536-200)%256;
smg_display(num1,num2,num3,num4,num5,num6,num7,num8);
f_2ms=1;
}
给个小爱心吧,谢谢!