📄 motor.c
字号:
单片机AT89C2051控制步进电动机(PX245-01A)下位机程序
--------------------------------------------------------------------------------
作者:-
[code]/***********************************************************************
* 项目:单片机AT89C2051控制步进电动机(PX245-01A )下位机程序 *
* Func: 该程序通过串口从主机获得控制信号——电动机选择信号,电动机转动 *
* 方向以及电动机所需要运行的步数信号,并根据获得的相应的信号做 *
* 出相应 *
* 说明:该程序已经经过验证正确 *
***********************************************************************/
#include
#include
#define uchar unsigned char
#define uint unsigned int
#define Maxsteplen 20000
#define delaytime 56
data uint stepno=0;
#define Npnum 8
data uchar pnum0[Npnum]={0x90,0x10,0x30,0x20,0x60,0x40,0xc0,0x80 }; //电动机0的相序
data uchar pnum1[Npnum]={0x09,0x01,0x03,0x02,0x06,0x04,0x0c,0x08 }; //电动机1的相序
data uint byte[5]={0,0,0,0,0};
data uint MaxlenFDR=0;
data uint MaxlenLDR=0;
data uchar motorselect=0xff;//=0slecct motor:FDR;=1slect motorDR
data uchar run_direct=0xff; //=0正转,=1反转
bit rready;
sbit P35=P3^5;
void delayMs(uint);
void motor_drive(uchar,uchar);
void data_deal(void);
/************************************************************************
* 串口通信程序,用于接收主机传送过来的控制信息
* 通信协议说明:
* ①YS1123电动机控制模块串口通信说明:以中断方式工作
* ②波特率(可以修改):9600 。
* ③串口工作方式:工作方式3,允许多机通信,允许接收控制。
* ④主机(W78E516B)向从机(AT89C2051)发送字节byte[0],byte[1]
* byte[2],byte[3],byte[0].
* ⑤byte[0]高字节选择FDR的方向,低字节选择LDR的方向
* ⑥byte[3]、byte[2]为FDR的步数,byte[5]、byte[4]为LDR的步数
* ⑦每收到一个数据后应答返回1个字节0aah
* ⑧如果需要校验,重发1次
************************************************************************/
void serilcomm(void) interrupt 4
{
uchar i;
ES=0; //关中断
rready=0;
for(i=0;i<5;i++)
{
while(RI!=1);RI=0;
byte=SBUF; //电极控制参数接收
_nop_();
SBUF=0xaa; //正确接收返回0xaa
while(TI!=1);TI=0;
}
ES=1;
}
void main(void)
{
uint i,a=0;
/*****************完成对串口通信的初始化,晶振频率22.1184M******************/
TMOD=0x20; //0010 0000 计数器定时器1工作于方式2重复计数
TL1=0xfa; //波特率9600
TH1=0xfa;
PCON=0; //波特率9600
TR1=1;
SCON=0x50; //11110000工作方式3,允许多机通信,允许接收控制,
ES=1; //开中断
EA=1; //??????????????????????????
/************************************************************************
控制电动机转动
*************************************************************************/
while(1)
{
P1=0;
delayMs(20);
P35=0; //??????????????????????
if((MaxlenFDR if(byte[1]||byte[2]||byte[3]||byte[4])
{
data_deal(); //参数处理子程序
for(i=0;i motor_drive(motorselect,run_direct);
}
rready=1; //运行完,置接收准备好标志
P35=1; //??????????????????????
}
}
/************************************************************************
************************************************************************/
void motor_drive(uchar select,uchar direct)
{uint a;
if(select==0)//=0slecct motor:FDR;
{
if(direct==0)
{P1=pnum0[a++]; //正转
MaxlenFDR++;}
else if(direct==1)
{P1=pnum0[a--];//反转
MaxlenFDR--;}
}
if(select==1)//=1slecct motorDR;
{
if(direct==0)
{P1=pnum1[a++]; //正转
MaxlenLDR++;}
else if(direct==1)
{P1=pnum1[a--];//反转
MaxlenLDR--;}
}
delayMs(delaytime);
a%=Npnum ;
}
/************************************************************************/
/************************************************************************
对参数进行处理以决定程序的下一步处理
************************************************************************/
void data_deal(void)
{if(byte[1]||byte[2]) //FDR
{
stepno=byte[1]*256+byte[2];
motorselect=0;
if(byte[0]&0xf0)run_direct=1; //电动机反转
else run_direct=0;
byte[2]=0;
byte[1]=0;
goto reti;}
else if(byte[3]||byte[4])//LDR
{
stepno=byte[3]*256+byte[4];
motorselect=1;
if(byte[0]&0x0f)run_direct=1;
else run_direct=0;
byte[4]=0;
byte[3]=0;}
reti: _nop_();
}
/************************************************************************
************************************************************************/
void delayMs(uint n)
{int i;
for(i=0;i {_nop_();
_nop_();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -