基于51单片机的步进电机控制系统(步数,方向,拍,数码管)原理图、流程图、物料清单、仿真图、源代码
基于51单片机的步进电机(步数,方向,拍,数码管)
基于单片机的步进电机控制系统设计
用单片机来控制步进电机的运行,要求有启动控制、换向控制、电机停止、正转和反转状态均由不同颜色指示灯来指示。此外还要求电机的通电方式由按键进行切换。电机的步数可通过按键设定来确定,电机转动过程要显示剩余步数。
显示驱动方式,4拍或8拍
#include "reg51.h"
#define uchar unsigned char
#define uint unsigned int
sbit L1=P1^0;//电机
sbit L2=P1^1;
sbit L3=P1^2;
sbit L4=P1^3;
sbit led1=P2^6;//led
sbit led2=P2^7;
sbit k1=P3^1;//按钮
sbit k2=P3^0;
sbit k3=P3^2;
sbit k4=P3^3;
sbit smg1=P2^2;//数码管
sbit smg2=P2^3;
sbit smg3=P2^4;
uchar code smgduan0[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//显示0~9,无小数点
uchar code smgduan1[10]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};//显示0~9,有小数点
uint step=100,step_set=100,start=0;//电机控制
uchar mode=0,moshi=1;
uchar fang=0;//方向
uchar cixu=0;
void delay(uint i)//延时
{
while(i--);
}
void disp()//显示
{
if(mode==1)
{
P0=0;//显示步数
smg3=1;smg2=1;smg1=1;
P0=smgduan1[step_set/1000];
delay(100);
P0=0;
smg3=1;smg2=1;smg1=0;
P0=smgduan1[step_set%1000/100];
delay(100);
P0=0;
smg3=1;smg2=0;smg1=1;
P0=smgduan1[step_set%100/10];
delay(100);
P0=0;
smg3=1;smg2=0;smg1=0;
P0=smgduan1[step_set%10];
delay(100);
}
else
{
P0=0;//显示步数
smg3=1;smg2=1;smg1=1;
P0=smgduan0[step/1000];
delay(100);
P0=0;
smg3=1;smg2=1;smg1=0;
P0=smgduan0[step%1000/100];
delay(100);
P0=0;
smg3=1;smg2=0;smg1=1;
P0=smgduan0[step%100/10];
delay(100);
P0=0;
smg3=1;smg2=0;smg1=0;
P0=smgduan0[step%10];
delay(100);
}
if(mode==2)
{
P0=0;//通电方式
smg3=0;smg2=1;smg1=0;
P0=smgduan1[moshi];
delay(100);
}
else
{
P0=0;//通电方式
smg3=0;smg2=1;smg1=0;
P0=smgduan0[moshi];
delay(100);
}
if(mode==3)
{
P0=0;//显示方向
smg3=0;smg2=0;smg1=0;
if(fang)//左
P0=0xb8;
else//右
P0=0x8e;
delay(100);
}
else
{
P0=0;//显示方向
smg3=0;smg2=0;smg1=0;
if(fang)//左
P0=0x38;
else//右
P0=0x0e;
delay(100);
}
}
//主函数
void main()
{
uchar k=0;
P1=0x01;
TMOD|=0X01;
TH0=0XD8;
TL0=0XF0;
ET0=1;//打开定时器0中断允许
EA=1;//打开总中断
TR0=1;//打开定时器
while(1)
{
//显示
disp();
if(fang==0)//方向指示
led2=0;
else
led2=1;
if(start)
led1=0;
else
led1=1;
if(!k1 &&(k!=1))//启停
{
k=1;
start=!start;
if(start==1)
{
step=step_set;
}
else
{
step=0;
}
}
if(!k2 &&(k!=2))//设置
{
k=2;
if(mode<3)
mode++;
else
mode=0;
}
if(!k3 &&(k!=3))//加
{
k=3;
if(mode==1)//步数
{
if(step_set<9999)
step_set+=10;
step=step_set;
}
if(mode==2)//通电方式
{
moshi=1;
}
if(mode==3)//方向
{
fang=0;
}
}
if(!k4 &&(k!=4))//减
{
k=4;
if(mode==1)//步数
{
if(step_set>10)
step_set-=10;
step=step_set;
}
if(mode==2)//通电方式
{
moshi=0;
}
if(mode==3)//方向
{
fang=1;
}
}
if(k1 && k2 && k3 && k4)
k=0;
}
}
void Timer0() interrupt 1
{
if(start)//电机驱动
{
if(moshi==1)//8拍
{
if(fang)//方向
{
switch(cixu)
{
case 0:L2=1;break;
case 1:L1=0;break;
case 2:L3=1;break;
case 3:L2=0;break;
case 4:L4=1;break;
case 5:L3=0;break;
case 6:L1=1;break;
case 7:L4=0;
}
}
else
{
switch(cixu)
{
case 0:L4=1;break;
case 1:L1=0;break;
case 2:L3=1;break;
case 3:L4=0;break;
case 4:L2=1;break;
case 5:L3=0;break;
case 6:L1=1;break;
case 7:L2=0;
}
}
if(cixu<7)
cixu++;
else
{
cixu=0;
if((step>0))
{
step--;
}
else
{
step=0; //停止
start=0;
step=step_set;
}
}
}
else//4拍
{
if(fang)//方向
{
switch(cixu)
{
case 0:L1=1;L4=0;break;
case 1:L2=1;L1=0;break;
case 2:L3=1;L2=0;break;
case 3:L4=1;L3=0;
}
}
else
{
switch(cixu)
{
case 0:L4=1;L1=0;break;
case 1:L3=1;L4=0;break;
case 2:L2=1;L3=0;break;
case 3:L1=1;L2=0;
}
}
if(cixu<3)
cixu++;
else
{
cixu=0;
if((step>0))
{
step--;
}
else
{
step=0; //停止
start=0;
step=step_set;
}
}
}
}
TH0=0XD8;
TL0=0XF0;
}