基于51单片机的步进电机调速系统含完整代码.docx
《基于51单片机的步进电机调速系统含完整代码.docx》由会员分享,可在线阅读,更多相关《基于51单片机的步进电机调速系统含完整代码.docx(32页珍藏版)》请在冰豆网上搜索。
![基于51单片机的步进电机调速系统含完整代码.docx](https://file1.bdocx.com/fileroot1/2023-2/24/24490663-b3b9-4848-8283-59229639d3cb/24490663-b3b9-4848-8283-59229639d3cb1.gif)
基于51单片机的步进电机调速系统含完整代码
课程设计报告
设计题目:
遥控小车
——基于51单片机的步进电机调速系统
学院:
专业:
班级:
学号:
姓名:
电子邮件:
时间:
成绩:
指导教师:
华南农业大学
理学院应用物理系
课程设计(报告)任务书
学生姓名指导教师职称
学生学号
专业电子信息科学与技术
题目基于51单片机的步进电机调速系统(遥控小车)
任务与要求
1.设计并制作电路,利用单片计控制步进电机运转。
2.通过键盘可以不间断地设定改变电机的转速、转向。
3.利用显示器实时显示转速等参数。
4.扩展功能:
可设定转动步数。
开始日期2014年3月完成日期2014年3月
1引言
步进电机是一种将电脉冲转化为角位移的执行机构。
目前,步进机已经广泛应用于领域,例如工业生产中的机械臂的控制,照明装置和监控摄像机转动等。
步进机在装置转动、精确位移方面有很重大的作用。
本系统是基于STC89C51单片机的遥控小车。
采用STC89C51单片机作为控制核心,通过ULN2003A驱动步进机(28BYJ-48)转动,由按键和显示屏1602组成人机交互模块,同时通过315M无线发射和接收模块向单片机输入控制信号,将整个系统固定于简易小车上,最终实现小车测试和远程遥控功能。
基本达到预定的设计要求以及功能的扩展。
2系统的设计与理论分析
2.1系统总体设计
2.2理论分析
本设计分为两种工作模式:
测试模式、遥控模式。
在电路板上有一个带锁的开关进行设置。
测试模式工作时,通过控制小车上的按键进行加速、减速、反转、设置、步数增、步数减等按键,单片机扫描按键,通过软件控制液晶模块显示对应的转速、设置的速度和步数,同时控制步进机模块进行相应的转动。
步进机的是由ULN2003A达林顿管驱动,由单片机控制输入脉冲的频率来控制步进机的转速,单片机是通过程序查表对4个I/O口输出脉冲,本次设计采用的是两相四线减速步进机,步进角为5.625°,减速比为64:
1,程序采用的是8拍查表,具有较好的扭矩。
遥控模式工作时,遥控部分五个按键分别输入前、后、左、右、暂停,单片机扫描按键,通过无线发射模块发射串行编码,小车的无线接收模块接收对应的编码,送至单片机进行解码,从而控制液晶模块的显示和步进机模块的工作,进而完成功能。
设定单通道无线收发模块通信协议为:
下降沿:
1ms的高电平,随后500us的低电平。
起始位:
4ms的高电平,随后4ms的低电平。
数据1:
2ms的高电平,随后500us的低电平。
数据0:
1ms的高电平,随后500us的低电平。
结束位:
4ms的低电平。
发送指令程序为:
{下降沿,起始位,3个数据位,结束位}
发送编码为:
右转:
000
前进:
001
后退:
010
左转:
011
接收程序通过触发外部中断1来接受信号,当P3.3口收到下降沿信号是即开始接收数据。
3硬件系统设计
3.1总体电路图
3.2单片机最小系统
3.3步进机模块
本次设计采用的是两相四线减速步进电机,步进角为5.625°,减速比为64:
1采用ULN2003达林顿管驱动。
3.4液晶显示模块
液晶显示模块采用LCD1602显示屏。
3.5测试按键模块
3.6遥控器部分
4软件系统设计
4.1主函数
4.2遥控模式程序
4.3测试模式程序
4.4键盘扫描程序
5系统运行情况分析
打开小车开关后,按下“测试”按键,小车进入测试模式。
连续按“加速”按键时,小车轮子转速明显变快;连续按“减速”按键时,小车轮子转速逐渐变慢;按“反转”按键轮子转速反向。
按“设置”按键会看到液晶显示屏关标闪烁,按“设置”键使光标移动,按“+”、“-”设置小车速度和步数,再一次按“设置”键,小车会依照这顶要求行驶。
按“测试”按键使其弹起,测试小车进入遥控模式工作时,打开遥控器,分别按下“前”、“后”、“左”、“右”,小车会依照对应的方向行驶,按下“暂停”键时,小车停止。
由此,改系统基本达到设计要求及拓展功能的要求。
不过因为本设计采用的28BYJ-48步进机为减速步进机,转动的上限值比较下,导致小车的行驶效果较慢,这个问题可以通过课后改用其他型号计算机得以解决。
6总结与讨论
经过四个星期的单片机课程设计,终于完成了基于51单片机的步进电机调速系统的设计,基本达到设计要求。
同时自己在该系统上扩展无线收发模块,将该系统拓展为遥控小车。
在本次设计的过程中,我们组成员进行了热烈讨论及反复的斟酌、修改。
首先对需要用到的元器件的参数进行充分的了解,然后在计算机上用Proteus进行了与Keil软件的联动仿真。
确认仿真正确看是硬件的焊接与调试。
在实验过程中,我们也遇到了许多问题,如步进机转动不起来、液晶屏显示乱码等,但是经过不断的探索、思考、验证,我们最终克服了种种困难,解决了所遇到的问题,成功地完成了这个课程设计。
在这个过程中,除了学习到关于本次设计的一些专业知识、电路焊接实践经验外,同时,大家的刻苦耐劳、团队合作的品质也得到了充分的锻炼。
附1:
实物图:
图1遥控小车
图2遥控器
附2:
参考文献
[1]李朝青.单片机原理及接口技术[M].第3版.北京航空航天大学出版社,2005.
[2]杨素行.模拟电子技术基础简明教程[M].第三版.高等教育出版社,2006.
附3:
组内分工:
A.庞明辕:
电路焊接、单片机编程、电路调试、辅助完成设计报告。
B.杜烁:
电路焊接、单片机编程、辅助方案改进、辅助完成设计报告。
C.汤安琪:
电路焊接、数据采集、完成设计报告。
附4:
元器件清单表格
元件
数量
STM89C51
2
1602
2
ULN2003A
2
28BYJ-48
2
315M无线收发模块
2
简易小车
1
其它(开关、电池)
若干
评语:
成绩:
附:
程序代码:
/**********************单片机课程设计C语言程序************************
题目:
基于步进机的小车
成员:
汤安琪、庞明辕、杜烁。
日期:
2014-3-1
******************************************************************/
#include
#defineucharunsignedchar
#defineuintunsignedint
sbita=P1^0;//反向
sbitb=P1^1;//减速
sbitc=P1^2;//加速
sbitd=P1^3;//开关
sbitf=P1^4;//设置
sbitg=P1^5;//加
sbith=P1^6;//减
sbitlcden=P3^7;//1602使能
sbitlcdrs=P3^6;//1602写命令/数据选择端
sbittrans=P3^3;//射频串行输入端
bitn,p;
uintstep,time,flag,flag1,num,snum,setnum,stepnum,count,temp,sum,t,e,j,k,m;
ucharv0,v1,v2,count1,num1,temp1;
ucharcodetable1[]={0x11,0x33,0x22,0x66,0x44,0xcc,0x88,0x99};//左
ucharcodetable2[]={0x11,0x99,0x88,0xcc,0x44,0x66,0x22,0x33};//右
ucharcodetable3[]={0x11,0x93,0x82,0xc6,0x44,0x6c,0x28,0x39};//后
ucharcodetable4[]={0x11,0x39,0x28,0x6c,0x44,0xc6,0x82,0x93};//前
ucharcodetable5[]={"SPEED:
000r/h"};
ucharcodetable6[]={"SET:
000STEP:
000"};
/*------------------------------------------------
延时程序
------------------------------------------------*/
voiddelay(uintz)
{
uintx,y;
for(x=z;x>0;x--)
for(y=10;y>0;y--);
}
voiddelay1(uintz)//10us
{
uchara,b,x;
for(x=0;xfor(b=1;b>0;b--)
for(a=2;a>0;a--);
}
/*------------------------------------------------
LCD1602写命令程序
------------------------------------------------*/
voidwrite_com(ucharcom)
{
lcdrs=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
/*------------------------------------------------
LCD1602写数据程序
------------------------------------------------*/
voidwrite_dat(uchardat)
{
lcdrs=1;
P0=dat;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
/*------------------------------------------------
基于LCD1602的显示程序
------------------------------------------------*/
voiddisplay(ucharadd,uchardat)
{
uintbai,shi,ge;
bai=dat/100;
shi=(dat-(dat/100)*100)/10;
ge=dat%10;
write_com(0x80+add);
write_dat(0x30+bai);
write_dat(0x30+shi);
write_dat(0x30+ge);
}
/*------------------------------------------------
小车速度计算程序
------------------------------------------------*/
voidspeed_dis()
{
doublen;
if(b==0)
{
delay(5);
if(b==0)
{
while(!
b);
time=time+10;
if(time>=300)
time=300;
}
}
if(c==0)
{
delay(5);
if(c==0)
{
while(!
c);
time=time-10;
if(time<=70)
time=70;
}
}
n=15*time/1024;
count=60*n;
}
/*------------------------------------------------
步数执行程序:
进入设置模式设置步数,确认后执行。
------------------------------------------------*/
voidsteprun()
{
uintm;
m=512*stepnum;
while(m--)
{
uchari;
for(i=0;i<8;i++)
{
P2=table4[i];
delay1(time);
}
speed_dis();
display(7,count);
if(f==0)
break;
}
}
/*------------------------------------------------
转速设置程序:
进入设置模式设置转速确认后执行。
------------------------------------------------*/
voidsetrun()
{
while
(1)
{
uchari;
time=(setnum*1024/900);
for(i=0;i<8;i++)
{
P2=table4[i];
delay(time);
}
if(f==0)
break;
}
}
/*------------------------------------------------
无线电接收解码程序
------------------------------------------------*/
voidreceive()
{
if(n==1)
{
while(trans==0);
t=0;
EX1=0;//在第一个下降沿关闭外部中断
while(trans==1);
if(t>35&&t<45)
{
t=0;
while(trans==0);
if(t>35&&t<45)
{
t=0;
while(trans==1);
if(t>5&&t<15)//数据0
v0=0;
if(t>15&&t<25)//数据1
v0=4;
while(trans==0);
t=0;
while(trans==1);
if(t>5&&t<15)//数据0
v1=0;
if(t>15&&t<25)//数据1
v1=2;
while(trans==0);
t=0;
while(trans==1);
if(t>5&&t<15)//数据0
v2=0;
if(t>15&&t<25)//数据1
v2=1;
while(trans==0);
t=0;
count1=v0+v1+v2;
switch(count1)
{
case0:
e=0;j=1;k=1;m=1;break;//000
case1:
e=1;j=0;k=1;m=1;break;//001
case2:
e=1;j=1;k=0;m=1;break;//010
case3:
e=1;j=1;k=1;m=0;break;//011
case4:
e=1;j=1;k=1;m=1;p=0;break;//100
}
}
}
}
n=0;
EX1=1;
}
/*------------------------------------------------
控制小车运行程序(前后左右),运行时显示小车的实时
速度。
------------------------------------------------*/
voidrun()
{
if(flag==0&&flag1==0)
{
if(j==0)
{
uchari,q;
p=1;
while
(1)
{
if(n==1)
break;
for(q=0;q<128;q++)
{
for(i=0;i<8;i++)
{
P2=table4[i];
delay1(time);
}
}
speed_dis();
display(7,count);
}
}
if(m==0)
{
uchari,q;
p=1;
while
(1)
{
if(n==1)
break;
for(q=0;q<128;q++)
{
for(i=0;i<8;i++)
{
P2=table1[i];
delay1(time);
}
}
speed_dis();
display(7,count);
}
}
if(k==0)
{
uchari,q;
p=1;
while
(1)
{
if(n==1)
break;
for(q=0;q<128;q++)
{
for(i=0;i<8;i++)
{
P2=table3[i];
delay1(time);
}
}
speed_dis();
display(7,count);
}
}
if(e==0)
{
uchari,q;
p=1;
while
(1)
{
if(n==1)
break;
for(q=0;q<128;q++)
{
for(i=0;i<8;i++)
{
P2=table2[i];
delay1(time);
}
}
speed_dis();
display(7,count);
}
}
}receive();
}
/*------------------------------------------------
正转程序
------------------------------------------------*/
voidforward()
{
uinti,q;
for(q=0;q<512;q++)
{
if(d==1||a==0)
break;
for(i=0;i<8;i++)
{
P2=table4[i];
delay1(time);
}
speed_dis();
display(7,count);
}
}
/*------------------------------------------------
反转程序
------------------------------------------------*/
voidreverse()
{
uinti,q;
for(q=0;q<512;q++)
{
if(d==1||a==1)
break;
for(i=0;i<8;i++)
{
P2=table3[i];
delay1(time);
}
speed_dis();
display(7,count);
}
}
/*------------------------------------------------
小车停止状态下的测试程序
功能:
b增加步进机脉冲周期
c减少步进机脉冲周期,
d为测试开关,
a为反转开关,
运行状态实时显示步进机速度。
------------------------------------------------*/
voidtestcar()
{
if(flag1==0)
{
if(d==0)
{
flag=1;//测试状态下,保证方向按键无效
if(a==0)
reverse();
else
forward();
}else
{
display(7,0);
flag=0;
}
}
}
/*------------------------------------------------
键盘扫描程序。
功能:
f为设置键,g为加键,h为减键,
按下g键次数:
1:
速度设置
2:
步数设置
3:
确认
按下g键对应数+1
按下h键对应数-1
------------------------------------------------*/
voidkeyscan()
{
if(f==0)
{
delay(5);
if(f==0)
{
while(!
f);
snum++;
flag1=1;
if(snum==1)
{
write_com(0xc6);
write_com(0x0f);
}
if(snum==2)
{
write_com(0xc0+15);
}
if(snum==3)
{
write_com(0x0c);
snum=0;
flag1=0;
time=setnum+40;
display(7,time);
write_com(0x0c);
if(stepnum!
=0)
steprun();
if(setnum!
=0)
setrun();
}
}
}
if(snum!
=0)
{
if(g==0)
{
delay(5);
if(g==0)
{
while(!
g);
if(snum==1)
{