51单片机控制四相步进电机
拿到步进电机,根据以前看书对四相步进电机的了解,我对它进行了初步的测试,就是将5伏电源的正端接上最边上两根褐色的线,然后用5伏电源的地线分别和另外四根线(红、兰、白、橙)依次接触,发现每接触一下,步进电机便转动一个角度,来回五次,电机刚好转一圈,说明此步进电机的步进角度为360/(4×5)=18度。地线与四线接触的顺序相反,电机的转向也相反。
如果用单片机来控制此步进电机,则只需分别依次给四线一定时间的脉冲电流,电机便可连续转动起来。通过改变脉冲电流的时间间隔,就可以实现对转速的控制;通过改变给四线脉冲电流的顺序,则可实现对转向的控制。所以,设计了如下电路图:
C51程序代码为:
代码一
#include
static unsigned intcount;
static unsigned intendcount;
voiddelay();
voidmain(void)
{
count = 0;
P1_0 = 0;
P1_1 = 0;
P1_2 = 0;
P1_3 = 0;
EA = 1;//允许CPU中断
TMOD = 0x11;//设定时器0和1为16位模式1
ET0 = 1;//定时器0中断允许
TH0 = 0xFC;
TL0 = 0x18;//设定时每隔1ms中断一次
TR0 = 1; //开始计数
startrun:
P1_3 = 0;
P1_0 = 1;
delay();
P1_0 = 0;
P1_1 = 1;
delay();
P1_1 = 0;
P1_2 = 1;
delay();
P1_2 = 0;
P1_3 = 1;
delay();
gotostartrun;
}
//定时器0中断处理
voidtimeint(void)interrupt1
{
TH0=0xFC;
TL0=0x18;//设定时每隔1ms中断一次
count++;
}
voiddelay()
{
endcount=2;
count=0;
do{}while(count
将上面的程序编译,用ISP下载线下载至单片机运行,步进电机便转动起来了,初步告捷!
不过,上面的程序还只是实现了步进电机的初步控制,速度和方向的控制还不够灵活,另外,由于没有利用步进电机内线圈之间的“中间状态”,步进电机的步进角度为18度。所以,我将程序代码改进了一下,如下:
代码二
#include
static unsigned intcount;
static intstep_index;
voiddelay(unsigned intendcount);
voidgorun(bitturn,unsigned intspeedlevel);
voidmain(void)
{
count = 0;
step_index = 0;
P1_0 = 0;
P1_1 = 0;
P1_2 = 0;
P1_3 = 0;
EA = 1;//允许CPU中断
TMOD = 0x11;//设定时器0和1为16位模式1
ET0 = 1;//定时器0中断允许
TH0 = 0xFE;
TL0 = 0x0C;//设定时每隔0.5ms中断一次
TR0 = 1;//开始计数
do{
gorun(1,60);
}while(1);
}
//定时器0中断处理
voidtimeint(void)interrupt1
{
TH0=0xFE;
TL0=0x0C;//设定时每隔0.5ms中断一次
count++;
}
voiddelay(unsigned intendcount)
{
count=0;
do{}while(count
voidgorun(bitturn,unsigned intspeedlevel)
{
switch(step_index)
{
case0:
P1_0 = 1;
P1_1 = 0;
P1_2 = 0;
P1_3 = 0;
break;
case1:
P1_0 = 1;
P1_1 = 1;
P1_2 = 0;
P1_3 = 0;
break;
case2:
P1_0 = 0;
P1_1 = 1;
P1_2 = 0;
P1_3 = 0;
break;
case3:
P1_0 = 0;
P1_1 = 1;
P1_2 = 1;
P1_3 = 0;
break;
case4:
P1_0 = 0;
P1_1 = 0;
P1_2 = 1;
P1_3 = 0;
break;
case5:
P1_0 = 0;
P1_1 = 0;
P1_2 = 1;
P1_3 = 1;
break;
case6:
P1_0 = 0;
P1_1 = 0;
P1_2 = 0;
P1_3 = 1;
break;
case7:
P1_0 = 1;
P1_1 = 0;
P1_2 = 0;
P1_3 = 1;
}
delay(speedlevel);
if(turn==0)
{
step_index++;
if(step_index>7)
step_index=0;
}
else
{
step_index--;
if(step_index<0)
step_index=7;
}
}
改进的代码能实现速度和方向的控制,而且,通过step_index静态全局变量能“记住”步进电机的步进位置,下次调用 gorun()函数时则可直接从上次步进位置继续转动,从而实现精确步进;另外,由于利用了步进电机内线圈之间的“中间状态”,步进角度减小了一半,只为9度,低速运转也相对稳定一些了。
但是,在代码二中,步进电机的运转控制是在主函数中,如果程序还需执行其它任务,则有可能使步进电机的运转收到影响,另外还有其它方面的不便,总之不是很完美的控制。所以我又将代码再次改进:
代码三
#include
static unsigned intcount;//计数
static intstep_index;//步进索引数,值为0-7
static bitturn;//步进电机转动方向
static bitstop_flag;//步进电机停止标志
static intspeedlevel;//步进电机转速参数,数值越大速度越慢,最小值为1,速度最快
static intspcount;//步进电机转速参数计数
voiddelay(unsigned intendcount);//延时函数,延时为endcount*0.5毫秒
voidgorun();//
51单片机控制四相步进电 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)