单片机课程设计报告单片机控制步进电机.docx
《单片机课程设计报告单片机控制步进电机.docx》由会员分享,可在线阅读,更多相关《单片机课程设计报告单片机控制步进电机.docx(26页珍藏版)》请在冰豆网上搜索。
单片机课程设计报告单片机控制步进电机
江西农大
单片机原理及应用
课程设计报告
设计课题:
单片机控制步进电机
专业班级:
信工091班
学生姓名:
崔**
指导教师:
何老师
2012年5月
1设计任务书
1.1基本设计要求
(1)用万能板、主芯片AT89S52、35BYJ412步进电机、BLN2003以及其他周围原件芯片完成实验设计。
(2)程序的首地址应使目标机可以直接运行,即从0000H开端。
在主程序的开端部分必须设置一个合适的栈底。
程序放置的地址须持续且靠前,不要在中间留下大批的空间地址,以使目标机可以应用较少的硬件资源。
(3)采用单片机控制一个三相单三拍的步进电机工作。
步进电机的旋转方向由正反转控制信号控制。
步进电机的步数由键盘输入,可输入的步数分别为3、6、9、12、15、18、21、24和27步,且键盘具有键盘锁功能,当键盘上锁时,步进电机不接受输入步数,也不会运转。
只有当键盘锁打开并输入步数时,步进电机才开始工作。
(4)电机运转的时候有正转和反转指示灯指示。
(5)电机在运转过程中,如果过热,则电机停止运转,同时红色指示灯亮,同时警报响。
本题目的关键之处是:
如何生成控制步进电机的脉冲序列。
1.2选作项目
1、用单片机(AT89S52)为主芯片设计电路来控制步进电机。
2、设三个自锁按键,分别作开关键盘、左转、右转控制。
3、设9个触电按键分别控制输入的步数为3、6、9、12、15、18、21、24和27步。
4、设置一片LCD12864显示器实时显示步进电机工作状态,并提示用户步操作。
2设计阐明
2.1设计内容
用ZY15MCU12BD型综合单片机实验箱仿真实现控制步进电机集采问过程。
2.2设计要求
(1)采用单片机控制一个三相单三拍的步进电机工作。
步进电机的旋转方向由正反转控制信号控制。
步进电机的步数由键盘输入,可输入的步数分别为3、6、9、12、15、18、21、24和27步,且键盘具有键盘锁功能,当键盘上锁时,步进电机不接受输入步数,也不会运转。
只有当键盘锁打开并输入步数时,步进电机才开始工作。
(2)电机运转的时候有正转和反转指示灯指示。
(3)电机在运转过程中,如果过热,则电机停止运转,同时红色指示灯亮,同时警报响。
(4)上机调试程序。
(5)写出设计报告。
2.3设备及工作环境
(1)硬件:
AT89S52单片机一片、35BYJ412步进电机一台、ISP下载器一个、LCD12864显示器、温度传感器18B20芯片。
(2)软件:
Windows操纵系统、KeilC51软件。
3系统方案整体设计
3.1设计思路
步进电机的不同驱动方式,都是在工作时,脉冲信号按一定顺序轮流加到三相绕组上,从而实现不同的工作状态。
由于通电顺序不同,其运行方式有三相单三相拍、三相双三拍和三相单、双六拍三种(注意:
上面“三相单三拍”中的“三相”指定子有三相绕组;“拍”是指定子绕组改变一次通电方式;“三拍”表示通电三次完成一个循环。
“三相双三拍”中的“双”是指同时有两相绕组通电)。
(1)三相单三拍运行方式:
下页图所示为反应式步进电动机工作原理图,若通过脉冲分配器输出的第一个脉冲使A相绕组通电,B,C相绕组不通电,在A相绕组通电后产生的磁场将使转子上产生反应转矩,转子的1、3齿将与定子磁极对齐,如果图(a)所示。
第二个脉冲到来,使B相绕组通电,而A、C相绕组不通电;B相绕组产生的磁场将使转子的2、4齿与B相磁极对齐,如图(b)所示,与图(a)相比,转子逆时针方向转动了一个角度。
第三个脉冲到来后,是C相绕组通电,而A、B相不通电,这时转子的1、3齿会与C组对齐,转子的位置如图(c)所示,与图(b)比较,又逆时针转过了一个角度。
图反应式步进电机工作原理图
当脉冲不断到来时,通过分配器使定子的绕组按着A相--B相--C相--A相……的规律不断地接通与断开,这时步进电动机的转子就连续不停地一步步的逆时针方向转动。
如果改变步进电动机的转动方向,只要将定子各绕组通电的顺序改为A相--C相--B相--A相,转子转动方向即改为顺时针方向。
单三拍分配方式时,步进电动机由A相通电转换到B相同点,步进电动机的转子转过一个角度,称为一步。
这时转子转过的角度是30度。
步进电动机每一步转过的角度称为步距角。
(2)三相双三拍运行方式三相双三拍运行方式:
每次都有两个绕组通电,通电方式是AB--BC--CA--AB……,如果通电顺序改为AB--CA--BC--AB……则步进电机反转。
双三拍分配方式时,步进电动机的步距角也是30度
(3)三相单,双六拍运行方式:
三相六拍分配方式就是每个周期内有六个通电状态。
这六中通电状态的顺序可以使A--AB--B--BC--C--CA--A……或者A--CA--C--BC--B--AB--A……六拍通电方式中,有一个时刻两个绕组同时通电,这是转子齿的位置将位于通电的两相的中间位置。
在三相六拍分配方式下,转子每一步转过的角度只是三相三拍方式下的一半,步距角是15度。
单三拍运行的突出问题是每次只有一相绕组通电,在转换过程中,一相绕组断电,另一相绕组通电,容易发生失步;另外单靠一相绕组通电吸引转子,稳定性不好,容易在平衡位置附近震荡,故用的较少。
双三拍运行的特点是每次都有两相绕组通电,且在转换过程中始终有一相绕组保持通电状态,因此工作稳定,且步距角与单三拍相同。
六拍运行方式转换时始终有一相绕组通电,且步距角较小,故工作稳定性好,但电源较复杂,实际应用较多。
4硬件设计
4.1系统硬件设计
4.1.1最小单片机系统
5V电源:
给系统供电。
复位电路:
程序跑飞时复位电路可以使程序从新执行,相当于电脑的重启。
晶振:
给单片机运行提供时钟。
比如电脑的2.2GHz频率。
EA接高电平:
表示运行内部程序存储器下载的程序。
P0口接排阻:
P0口开漏结构,使用时一般接排阻拉高电平。
4.1.2键盘设计
该电路中采用独立键盘工作方式,共设有12个按键,分别提供3、6、9、12、15、18、21、24布局选择功能、键盘锁功能以及步进电机转动方向选择功能。
其中有程序决定起作用。
4.2系统工作原理论述
该系统的工作核心CPU为ATMEL公司生产的AT89S52芯片将多种功能的8位CPU与FPEROM(快闪可编程/擦除只读存储器)结合在一个芯片上,是一种低功耗、高性能的CMOS控制器,为很多嵌入式控制应用提供了非常灵活而又价格适宜的方案,其性能价格比远高于同类芯片。
它与MCS-51指令系统兼容,片内FPEROM允许对程序存储器在线重复编程,也可用常规的EPROM编程器编程,可循环写入/擦除1000次。
89S52内含4KB的FPEROM,一般的EEPROM的字节擦除时间和写入时间基本上均为10ms,对于任一个实时控制系统来说,这样长的时间是不可能在线修改程序的。
●CPU为Atmel公司生产的89C51/89C52/89C55等。
出厂所配晶振频率为11.0592MH,每个机器周期为1.085us,用户更换晶振以提高速度;
●存贮器为64K,前4K/8K20K在CPU内部,其它程序在EPR0M27512中;
●数据存贮器为32K(62256),地址为8000—FFFFH;
●Ⅰ/O扩展8155,片内RAM地址∶200O-20FFH;
●8155命令口地址为∶2100H;
●A口地址∶21O1HB口地址:
2102HC口地址:
2103H;
●T低八位∶2104HT高八位∶2105H;
●多路模拟开关的使用∶
IN0∶P1=0F8HIN4:
P1=0FCHIN1∶P1=0F9HIN5:
P1=OFDH
IN2∶P1=0FAHIN5:
P1=0FEHIN3∶P1=0FBHIN7:
P1=0FFH
●不掉电数据存贮器为∶500EH-507FH;
●控制板∶160x1O9(mm)供电∶+5V300mA+12V100mA-12V100mA;
●AT89C51是一种低功耗、高性能的片内含有4KB快闪可编程/擦除只读存储器(FPEROM-FlashProgrammableandEraseableReadOnlyMemory)的8位CMOS微控制器,使用高密度、非易失存储技术制造,并且与80C51引脚和指令系统完全兼容;
●主要性能:
与MCS-51微控制器产品系列兼容;
片内有4KB可在线重复编程的快闪擦写存储器。
引脚简介:
整体介绍:
该系统采用的芯片还有:
DS18B20温度传感器、ULN2003A以及MP28GA四相五线步进电机,并且步进电机在双八拍的方式下工作,步矩为5.625°,步进电机的旋转方向由正反转控制信号控制。
步进电机的步数由键盘输入,可通过独立键盘S1~S9输入的步数分别为3、6、9、12、15、18、21、24和27步对应的角度为16.875°、33.725°、……、151.875°,且键盘S10具有键盘锁功能,当键盘上锁时,步进电机不接受输入步数,也不会运转。
只有当键盘锁打开,选择运转方向并且输入步数时,步进电机才开始工作。
电机运转的时候有正转指示灯D2和反转指示灯D3指示。
电机在运转过程中用温度传感器采集步进电机外表温度(可设置),如果过热,则电机停止运转,同时红色指示灯亮,同时蜂鸣器警报响。
5软件设计
5.1分析论证
此步进电机控制电路设计与实现,主要采用了ULN2003A驱动芯片,温度传感器芯片DS18B20芯片,独立键盘等,包含步进电机运行驱动,温度采集,主函数三大功效模块。
5.1.1步进电机运行驱动模块
由于该系统中没有完全使用I/O端口,所以采用了独立键盘的工作方式,系统工作时,键盘控制的I/O口处于高电平状态,当按键按下时触发低电平,驱动程序实时监测并立即响应执行相应工作。
5.1.2温度采集模块
该模块的重要功效是对步进电机的外表采集温度,并且对已设定好的数值进行比较,从而确定机身温度是否过高,正常时电机正常转动,当温度过高时电机不再转动,并且蜂鸣器报警,红灯点亮。
5.1.3主函数模块
该模块重要功效是调动温度采集函数、步进电机函数中函数,实现模块化编程。
5.1.4整体功效
AT89S52芯片控制ULN2003A芯片驱动步进电机,扫描键盘输入运行状态以及运转步数,当电机外表温度超过32℃是电机停止转动,并且报警!
5.2程序流程图
主程序流程图如图所示:
是
否
是
否
否
图2程序流程图
5.3程序清单
步进电机驱动函数:
//BJDJ.h
#ifndef_BJDJ_H_
#define_BJDJ_H_
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitk1=P1^0;
sbitk2=P1^1;
sbitk3=P1^2;
sbitk4=P1^3;
sbitk5=P1^4;
sbitk6=P1^5;
sbitk7=P1^6;
sbitk8=P1^7;
sbitk9=P0^0;
sbitk10=P0^1;
sbitk11=P0^2;
sbitk12=P0^3;
voidkey_scan();
voidmotor_turn();
voidmotor_stop();
#endif
//BJDJ.c
#include"BJDJ.h"
ucharcodeFFW[8]={0xfe,0xfc,0xfd,0xf9,0xfb,0xf3,0xf7,0xf6};
ucharcodeREV[8]={0xf6,0xf7,0xf3,0xfb,0xf9,0xfd,0xfc,0xfe};
ucharrate;
externuchari=0;
/********************************************************/
/*延时
/********************************************************/
voiddelay(ucharx)
{
uchari,j;
for(i=0;ifor(j=0;j<110;j++);
}
/********************************************************/
/*步进电机正转
/********************************************************/
voidmotor_ffw(ucharx)
{
uchari,j;
for(j=0;j{
for(i=0;i<8;i++)//一个周期转45度
{
P2=FFW[i];//取数据
delay(150);//调节转速
}
}
}
/********************************************************/
/*
/*步进电机反转
/********************************************************/
voidmotor_rev(ucharx)
{
uchari,j;
for(j=0;j{
//退出此循环程序
for(i=0;i<8;i++)//一个周期转45度
{
P2=REV[i];//取数据
delay(150);//调节转速
}
}
}
/*******************************************************
*键盘扫描
******************************************************/
voidkey_scan()
{
i=0;
if(k1==0)
{
delay(5);
if(k1==0)i=24;
}
if(k2==0)
{
delay(5);
if(k2==0)i=46;
}
if(k3==0)
{
delay(5);
if(k3==0)i=72;
}
if(k4==0)
{
delay(5);
if(k4==0)i=96;
}
if(k5==0)
{
delay(5);
if(k5==0)i=120;
}
if(k6==0)
{
delay(5);
if(k6==0)i=144;
}
if(k7==0)
{
delay(5);
if(k7==0)i=168;
}
if(k8==0)
{
delay(5);
if(k8==0)i=192;
}
if(k9==0)
{
delay(5);
if(k9==0)i=216;
}
}
/********************************************************
*电机转动
********************************************************/
voidmotor_turn()
{
if(k10==0)
{
delay(5);
if(k10==0)P2=P2&0xf0;
}
if(k11==0&&k12==1&&k10==1)
{
delay(5);
if(k11==0&&k12==1&&k10==1)
motor_ffw(i);
}
if(k12==0&&k11==1&&k10==1)
{
delay(5);
if(k12==0&&k11==1&&k10==1)
motor_rev(i);
}
}
voidmotor_stop()
{
motor_rev(0);
}
温度传感器18B20驱动函数:
//DS18B20.h
#ifndef__DS18B20_H__
#define__DS18B20_H__
#include
#include
#defineuintunsignedint
#defineucharunsignedchar
externucharT;
sbitDQ=P2^7;//温度输入口
sbitbell=P0^4;
sbitled1=P0^7;
voiddelay2(uintt);
voidow_reset(void);
voidwrite_byte(ucharval);
voidread_temp();
voidwork_temp();
#endif
//DS18B20.c
#include"DS18B20.h"
externuchardatatemp_data[2]={0x00,0x00};
ucharflag;
charpresence=1;
ucharT;
/***********11微秒延时函数**********/
voiddelay2(uintt)
{
for(;t>0;t--);
}
/***********18B20复位函数**********/
voidow_reset(void)
{
presence=1;
while(presence)
{
while(presence)
{
DQ=1;_nop_();_nop_();
DQ=0;//
delay2(50);//550us
DQ=1;//
delay2(6);//66us
presence=DQ;//presence=0继续下一步
}
delay2(45);//延时500us
presence=~DQ;
}
DQ=1;
}
/**********18B20写命令函数*********/
voidwrite_byte(ucharval)
{
uchari;
for(i=8;i>0;i--)
{
DQ=1;
_nop_();_nop_();
DQ=0;
_nop_();_nop_();_nop_();_nop_();_nop_();//5us
DQ=val&0x01;//最低位移出
delay2(6);//66us
val=val/2;//右移一位
}
DQ=1;
delay2
(1);
}
/*********18B20读1个字节函数********/
ucharread_byte(void)
{
uchari;
ucharvalue=0;
for(i=8;i>0;i--)
{
DQ=1;
_nop_();_nop_();
value>>=1;
DQ=0;//
_nop_();_nop_();_nop_();_nop_();//4us
DQ=1;
_nop_();_nop_();_nop_();_nop_();//4us
if(DQ)value|=0x80;
delay2(6);//66us
}
DQ=1;
return(value);
}
/***********读出温度函数**********/
voidread_temp()
{
ow_reset();//总线复位
write_byte(0xCC);//发SkipROM命令
write_byte(0xBE);//发读命令
temp_data[0]=read_byte();//温度低8位
temp_data[1]=read_byte();//温度高8位
ow_reset();
write_byte(0xCC);//SkipROM
write_byte(0x44);//发转换命令
}
/***********温度数据处理函数**********/
voidwork_temp()
{
T=((temp_data[0]&0xf0)>>4)|((temp_data[1]&0x07)<<4);
}
主函数:
//main.c
#include"DS18B20.h"
#include"BJDJ.h"
voidmain()
{
while
(1)
{
T=0;
P1=0xff;
P0=0x0f;
led1=1;
ow_reset();//开机先转换一次
write_byte(0xCC);//SkipROM
write_byte(0x44);//发转换命令
read_temp();//读出18B20温度数据
work_temp();//处理温度数据
key_scan();
if(T>31)
{
motor_stop();
led1=0;
bell=1;
delay2(1000);
}
else
{
led1=1;
bell=0;
motor_turn();
}
}
}
6调试过程及分析
编写好的源程序在Keil编译后呈现很多错误,这些错误有很多时平时的实验碰到过的,例如:
字母开头忘加0,零和字母O弄混杂了,有些标号用了几次,CJNE写成了CJNZ等等,幸好这些错误在平时的实验中碰到了,所以改错误很轻易,。
除了常见的错误外,还有几条错误时在前几次实验都没有出现过,如:
AJMP跳转指令跳不回指定的地位,是由于跳转的长度大于AJMP跳转的长度,最后只好用LJMP跳转后才跳到指定的地位。
在前期的程序编写和几天的上机调试,使我又获得了很多新的知识,由于前期编写程序时查了很多材料学到了很多知识,这几天的调试更时获得很新的知识,由于程序中又很多的错误,为了修正错误必须看书或向别人请教,在这个过程中无意识的获得了很多知识。
同时也使我对单片机更感兴趣了,这点我感到很重要,相信这会对以后的学习有所帮助。
7设计总结
本次课程设计是用ZY15MCU12BD综合单片机实验箱及串口电路设计单片机驱动步进电机电路,经过两个星期的调试,成果满足基本设计请求,验证无误。
设计重要用到了多种芯片,程序也比较长,比较麻烦,同时也碰到了不少艰苦,尤其是关于校时模块和时钟与秒表之间切换的设计实现。
关于显示模块,在以前的实验中做过,所以题目很轻易解决