摘要
本设计详细介绍了基于单片机的四相步进电机控制系统。步进电机通过输入脉冲信号进行控制,即电机的总转动角度由输入脉冲总数决定,因此,单片机通过向步进电机发送控制信号就能实现对步进电机的控制。
单片机实现的步进电机控制系统具有成本低、使用灵活的特点,该系统采用80C51单片机作为主控芯片,来完成对步进电机转动及LED 显示的控制。 本设计主要由单片机80C51,4相步进电机,7段数码管及一些其他相关元件设计而成,分为按键选择工作状态模块、步进电机工作模块、LED 二极管显示工作状态模块以及4位数码管显示步数模块。可以通过开关来控制系统的启/停工作,当系统运转时,用开关来控制方向,并使相应的指示灯亮起,同样由开关来选择工作模式。运转时,用4位7段数码管来输出步数。最后根据思路所设计出来的硬件图设计相适应的软件。
电路结构简单,设计思路清晰,同时利用KEIL 和Proteus 进行联调仿真,结果比较直观。仿真结果收到了预期的效果。 关键字:四相步进电机、单片机、PROTEUS 仿真
1设计任务及要求
设计一个四相步进电机控制系统,要求系统具有如下功能:用SW11-SW13作为通电方式选择键,SW11为四相单四拍, SW12为四相双四拍,SW13为四相八拍;SW14为启动/停止控制、SW1方向控制;用4位LED 数码管显示工作步数。用3个发光二极管显示状态;正转时红灯亮,反转时黄灯亮,不转时绿灯亮。
2方案论证
2.1 设计思路与方案
本次设计是一个对于四相步进电机的控制系统,而单片机实现的步进电机控制系统具有成本低、使用灵活的特点,此系统选用51单片机即可。 根据要求整个设计大体可分为四块:
一是5个按键SW11-SW13将用户所需来选择步进电机的工作状态。我们将开关连入单片机的P1口,通过按键开关的高低电平状态来读入我们所需的控制信号。硬件上直接把开关分别接在单片机的接口上,通过查询端口信号来动作,将控制信号处理。
二是3个LED 发光二极管的显示步进电机工作状态模块。在设计要求中步进电机正转是红灯亮,反转是黄灯亮,停止不转是绿灯亮。设计中将3个发光二极管分别接到单片机P3口受到单片机的输出信号控制。 三是步进电机的工作模块。要想步进电机按照我们想要的方式运转,将步进电机一端接到+12V的电源,一端接到单片机P3口,受单片机的输出信号控制。 四是4位数码管显示步数的模块。设计中主要是利用软件编程的算法来实现步数的累计和显示,同样,4位数码管接到单片机的P0口和P2口受单片机输出信号的控制,在硬件上使用的是动态显示的接法。
由此可知所需要设计一个系统,可以通过不同按键来选择步进电机的工作方式,且有LED 发光二极管来显示电机对应的工作状态,除此之外还能在数码管上显示出步进电机转动的步数。
2.2总体设计框图
此系统主要由单片机、步进电机、步数显示模块、工作状态控制与显示模块组成。整体框图如图1:
图1 系统整体框图
3系统实现的原理说明
3.1 步进电机控制工作原理
3.1.1步进电机的工作原理
步进电机通过输入脉冲信号进行控制,即电机的总转动角度由输入脉冲总数决定,而电机的转速由脉冲信号频率决定。步进电机的驱动电路是根据单片机产生的控制信号进行工作。因此,单片机通过向步进电机驱动电路发送控制信号就能实现对步进电机的控制。
如图2所示,开始时,开关SB 接通电源,SA 、SC 、SD 断开,B 相磁极和转子0、3号齿对齐,同时,转子的1、4号齿就和C 、D 相绕组磁极产生错齿,2、5号齿就和D 、A 相绕组磁极产生错齿。
当开关SC 接通电源,SB 、SA 、SD 断开时,由于C 相绕组的磁力线和1、4号齿之间磁力线的作用,使转子转动,1、4号齿和C 相绕组的磁极对齐。而0、3号齿和A 、B 相绕组产生错齿,2、5号齿就和A 、D 相绕组磁极产生错齿。依次类推 A 、B 、C 、D 四相绕组轮流供电 则转子会沿着A 、B 、C 、D 方向转动。
四相步进电机按照通电顺序的不同,可分为单四拍、双四拍、八拍三种工作方式。单四拍与双四拍的步距角相等,但单四拍的转动力矩小。八拍工作方式的步距角是单四拍与双四拍的一半,因此,八拍工作方式既可以保持较高的转动力矩又可以提高控制精度。
图2 步进电机工作原理图
3.1.2 步进电机的启停控制
步进电机由于其电气特性, 运转时会有步进感 ,即振动感。为了使电机转动平滑 ,减小振动 ,可在步进电机控制脉冲的上升沿和下降沿采用细分的梯形波 ,可以减小步进电机的步进角 ,提高电机运行的平稳性。在步进电机停转时 ,为了防止因惯性而使电机轴产生顺滑,则需采用合适的锁定波形,产生锁定磁力矩 ,锁定步进电机的转轴,使步进电机的转轴不能自由转动。 3.1.3 步进电机的转向控制
如果给定工作方式正序换相通电,步进电机正转。若步进电机的励磁方式为四相八拍,即 A-AB-B-BC-C-CD-D-DA-A。如果按反序通电换相 ,即则电机就反转。其他方式情况类似。
3.2步数显示模块原理
步数显示模块和工作状态显示模块,都是通过单片机输出信号控制发光二极管LED 的亮灭。其中步数显示模块中LED 构成数码管,要求显示4位十进制数故用到4位数码管。要控制多位的显示电路,需要有字段控制和字位控制。控制方式分为静态显示方式和动态显示方式。静态显示方式,每一位的显示器都需要配一个8位输出口来输出该字位的七段码,需要片外扩展输出口。
而动态显示方式
将各数码管的对应字段的引脚都并联在一起,线路简单,减少接口,不需片外扩展。这里选用动态显示方式。
4硬件设计
4.1系统总原理图
图3 系统总原理图
根据设计要求用PROTEUS 所做的硬件连线图如图3。
4.2各部分硬件原理图设计
4.2.1 单片机控制模块
单片机选用最经典的80C51,其4个I/O口都要用到,P3接步进电机驱动电
路及工作状态显示模块,P0和P2分别接步数显示中对数码管的字段控制及数码管片选,P1接工作状态控制电路,时钟用内部方式需外接晶体振荡器。硬件图如图4所示。
图4 单片机模块原理图
此设计中接的是12MHZ 的晶振,故一个机器周期为1/12us。根据经验数据,与晶振一起的两个电容设为15PF 。单片机的VCC 和GROUD 都隐藏了, 已自动接好,VCC 应设为+5V。 4.2.2按键选择工作状态模块
5个按键开关一端通过电阻接高电平,另一端全部接到地,其中接高电平的一端对应也接到单片机的P1口分别为P1.0~P1.4。当开关断开,就是输入到单片机对应端口高电平,而开关闭合,是使端口接地,输入低电平。所以这个设计中开关断开时才是有效的。各按键功能:
(1)SW11~SW13为工作模式控制开关,SW11接电时,为步进电机单四拍工作模式;SW12接电时,为步进电机双四拍工作模式;SW13接电时,步进电机工作模式为四相八拍。
(2)SW14为启/停控制开关,控制整个系统的开启和关闭。 (3)SW1为正/反转控制开关,控制步进电机的转向。
图5 按键模块原理图
4.2.3步进电机工作模块
将四相步进电机四个端口直接接到单片机P3.0~P3.3即可,另两个端口接到+12V的高电平给步进电机供电。只需在软件编写上控制算法便可以调节这四个端口的高低电平来控制步进电机的开启与停止,正反转以及工作模式。步进电机硬件接线图如图6所示。
图6 步进电机模块原理图
4.2.4工作状态显示模块
LED 发光二极管显示步进电机的工作状态,它们分别接到单片机的P3.5~P3.7。
图7 工作状态显示模块原理图
4.2.5 4位数码管显示步数模块
LED 数码管实际上是由七个发光管组成8字形构成的,加上小数点就是8个。这些段分别由字母a,b,c,d,e,f,g,dp 来表示。当数码管特定的段加上电压后,这些特定的段就会发亮 以形成我们眼睛看到的字样了。通过分时轮流控制各个LED 数码管的COM 端,就使各个数码管轮流受控显示,这就是动态驱动。 P0口和P2口的前四个分别接步数显示中对数码管的字段控制及数码管片选,如图8所示,这里主要是由软件算法来实现单片机输出的控制。
图8 数码管显示模块原理图
5软件设计
5.1系统总体设计
图9 系统总流程图
设计说明:首先是数码管显示清零,单片机再读入P1口输入的按键状态,先判断是否启动,如果没有启动则是绿灯亮并再判断,如果启动了,就接着判断所需的电机工作模式,再读入P1口状态判断电机的转向,输出控制信号为正转红灯亮,反转黄灯亮,由此可以让步进电机按照指定的方式运转,并且累计步数再显示到数码管上。最后检验P1口,是否状态改变,如果改变则步数清零重新开始判断,不改变则继续转动。
5.2步进电机工作模块
5.2.1步进电机的工作方式说明 (1)四相单四拍工作方式
在这种工作方式下,A 、B 、C 、D 三相轮流通电,电流切换三次,磁场旋转一周, 转子向前转过一个齿距角。因此这种通电方式叫做三相单三拍工作方式。这时步距角θ(度)为:
θ=360/mz
式中:m 为定子相数;z 为转子齿数
表1 单四拍的相位控制
(2) 四相双四拍工作方式
这种工作方式每次都是有两相导通,两相绕组处在相同电压之下,以AB ─BC ─CD ─DA —AB(或反之) 方式通电,故称为双四拍工作方式。以这种方式通电, 转子齿所处的位置相当于八拍控制方式中去掉单四拍后的四个位置。它的步距角计算公式与单四拍时的公式相同。
表2 双四拍的相位控制
(3) 四相八拍工作方式
在这种工作方式下,绕组以A —AB —B —BC —C —CD —D —DA —A 时序(或反时序) 转换8次,磁场旋转一周,转子前进一个齿距每次切换均使转子转动0.9°,故这种通电方式称为四相八柏工作方式。其步距角θ(度)为:
θ=360/2mz=180/mz 表3 八拍的数学模型
5.2.2设计说明及流程图
设计说明:在此设计中,采用的是四相步进电机,对于步进电机模块的程序设计采用循环程序设计方法。先把正反转向的控制模型存放在内存单元中,然后再逐
一从单元中取出控制模块并输出。首先启动,通过P1口读入所需的工作方式,即选择步进电机的拍数,然后读入正反转的控制,再来输出对应的控制模型来驱动步进电机转动。
5.3数码管步数显示模块
设计说明:步数显示模块是整个程序里的一个子程序。其是用4位八段数码管来显示工作步数。先将要显示的数化为10进制数,每位分别储存,从P0口输出显示码,P2口输入位选码,需要一定的延时,让此位数字显示闪烁出来。然后修改数组地址,求下一位位选码继续显示,直至输出四位数。这个扫描过程重复50次,保证人眼能观察到步数显示。流程图如图11:
图11 数码管显示模块流程图
6仿真调试记录
如图12所示,当选择电机工作在单四拍,正转的模式下,SW11、SW1接高电平,SW12、SW13接低电平,系统启动,SW14接高电平,电机开始转动。LED 四位显示屏显示工作步数,LED 指示灯红灯亮显示电机正转的状态。
7心得体会
计算机控制技术是一门应用性很强综合性很强的学科,在这次课设中,我充分感受到了这一点。在老师给的课题之中,是来自于各个方面各个领域的应用,不得不说,计算机控制很强大,确实改变了我们的生活。
本次课设收获就是关于软件的使用了。PROTEUS,KEIL51,以前好像也用过 但是平时较少接触,这次的课设让我比较熟练的掌握了这两个学习软件强大的功能,而且发现从PROTEUS 里导出来的电路图特别漂亮和清晰。
计算机控制技术一直是自己比较喜欢的一门学科,拿到课程设计的题目也想着可以好好检验自己的学习成果,一直认为,期末考试是所谓的应试教育,而课程设计似乎更加地考验所学的知识,所谓实践与理论相结合就是这个道理吧。课程设计总能让我有一种我站在山面前的感觉,看上去比较陌生高大,但是攀登的技巧早已在平时的学习中习得,不断地去攀登,不断地在回味课堂上老师讲的东西,书本上的东西,这是一种奇妙的体验。
我明白遇到的电路或者课题并不一定在你的知识范围之内,而面对新的东西我们要冷静地去寻求解决之道,去搜寻网络资源,图书馆资源以及和同学们的讨论之中,再结合自己所学过的知识来吃透理解那些未知的东西,扩宽知识面,这样就会觉得学到了远远超过课堂的东西,但是却源于课堂,想必这就是课设的意义吧,很有收获。
附录一程序清单
#include "reg52.h"
//Motor sbit F1 = P3^0; sbit F2 = P3^1; sbit F3 = P3^2; sbit F4 = P3^3; //sbit TIM=P3^4; #define m 500
/////////////////////////////////////// //步进电机驱动
unsigned char MotorStep=0; unsignedintMotorTimer = 0;
unsignedint TIM,CT,STEP=0,TIM1,num; voidInitMotor() {
F1 = 1; F2 = 1; F3 = 1; F4 = 1; }
voidSetMotor() {
// if(Speed == 0) return; if(P1&0x01)//单四 {
if(P1&0x10)// 正 switch(MotorStep) { case 0: if(TIM) {
P3=0xb1;//F1 = 0; F2 = 0; F3 = 0;F4 = 1;
MotorStep = 1; TIM=0; } break; case 1: if(TIM) {
P3=0xb2;//F1 = 1; F2 = 0;F3 = 0; F4 = 0; MotorStep = 2; TIM=0; } break; case 2: if(TIM) {
P3=0xb4;//F1 = 0; F2 = 1; F3 = 0; F4 = 0; MotorStep = 3;
TIM=0; } break; case 3: if(TIM) {
P3=0xb8;//F1 = 0; F2 = 0; F3 = 1; F4 = 0; MotorStep = 0; TIM=0; } break; } else //单四反 switch(MotorStep) { case 0: if(TIM)
{
P3=0x71;//F1 = 0; F2 = 0; F3 = 0;F4 = 1; MotorStep = 1; TIM=0; } break; case 1: if(TIM) {
P3=0x78;//F1 = 0; F2 = 0;F3 = 1; F4 = 0; MotorStep = 2; TIM=0; } break; case 2: if(TIM)
{
P3=0x74;//F1 = 0; F2 = 1; F3 = 0; F4 = 0; MotorStep = 3;
TIM=0; } break; case 3: if(TIM) { STEP++;
P3=0x72;//F1 = 1; F2 = 0; F3 = 0; F4 = 0; MotorStep = 0; TIM=0; } break; } }
else if(P1&0x02) //双四正转 {
if(P1&0x10)//则正转
switch(MotorStep) { case 0: if(TIM) {
P3=0xb3;//F1 = 0; F2 = 0; F3 = 1;F4 = 1; MotorStep = 1; TIM=0; } break; case 1: if(TIM) {
P3=0xb6;//F1 = 0; F2 = 1;F3 = 1; F4 = 0; MotorStep = 2; TIM=0; } break; case 2: if(TIM) {
P3=0xbc;//F1 = 1; F2 = 1; F3 = 0; F4 = 0; MotorStep = 3; TIM=0; } break; case 3: if(TIM) {
P3=0xb9; //F1 = 1; F2 = 0; F3 = 0; F4 = 1; MotorStep = 0; TIM=0; }
break; } else //双四反 switch(MotorStep) { case 0: if(TIM) {
P3=0x73;//F1 = 0; F2 = 0;F3 = 1;F4 = 1;
MotorStep = 1; TIM=0; } break; case 1: if(TIM) {
P3=0x79;// F1 = 1; F2 = 0; F3 = 0;F4 = 1; MotorStep = 2; TIM=0; } break; case 2: if(TIM) {
P3=0x7c;//F1 = 1; F2 = 1;F3 = 0;F4 = 0; MotorStep = 3; TIM=0; } break; case 3: if(TIM) {
P3=0x76;//F1 = 0; F2 = 1; F3 = 1; F4 = 0;
MotorStep = 0; TIM=0; } break; }}
else if(P1&0x04)//八拍 { if(P1&0x10)//则正转 switch(MotorStep) { case 0: if(TIM) {
P3=0xb1;//F1 = 0; F2 = 0; F3 = 0;F4 = 1; MotorStep = 1; TIM=0; } break;
case 1: if(TIM) {
P3=0xb3;//F1 = 1; F2 = 0;F3 = 0; F4 = 1; MotorStep = 2; TIM=0; } break; case 2: if(TIM)
{
P3=0xb2;//F1 = 1; F2 = 0; F3 = 0; F4 = 0; MotorStep = 3; TIM=0; } break; case 3:
if(TIM) {
P3=0xb6;//F1 = 1; F2 = 1; F3 = 0; F4 = 0; MotorStep = 4; TIM=0; } break; case 4: if(TIM) {
P3=0xb4;// F1 = 0; F2 = 1; F3 = 0; F4 = 0; MotorStep = 5; TIM=0; } break; case 5: if(TIM) {
P3=0xbc;//F1 = 0; F2 = 1; F3 = 1; F4 = 0; MotorStep = 6; TIM=0; } break; case 6: if(TIM) {
P3=0xb8;//F1 = 0; F2 = 0; F3 = 1; F4 = 0; MotorStep = 7; TIM=0; } break; case 7: if(TIM) {
P3=0xb9;//F1 = 0; F2 = 0; F3 = 1; F4 = 1; MotorStep = 0; TIM=0; } break; } else //八拍反 switch(MotorStep) { case 0: if(TIM) {
P3=0x71;// F1 = 0; F2 = 0; F3 = 0;F4 = 1; MotorStep = 1; TIM=0; } break; case 1: if(TIM) {
P3=0x79;// F1 = 0; F2 = 0;F3 = 1; F4 = 1; MotorStep = 2; TIM=0; } break; case 2: if(TIM) {
P3=0x78;//P3=0x78;F1 = 0; F2 = 0; F3 = 1; F4 = 0; MotorStep = 3; TIM=0; } break; case 3:
if(TIM) {
P3=0x7c;//F1 = 0; F2 = 1; F3 = 1; F4 = 0; MotorStep = 4; TIM=0; } break; case 4: if(TIM) {
P3=0x74;// F1 = 0; F2 = 1; F3 = 0; F4 = 0; MotorStep = 5; TIM=0; } break; case 5: if(TIM) {
P3=0x76;// F1 = 1; F2 = 1; F3 = 0; F4 = 0; MotorStep = 6; TIM=0; } break; case 6: if(TIM) {
P3=0x72;//F1 = 1; F2 = 0; F3 = 0; F4 = 0; MotorStep = 7; TIM=0; } break; case 7: if(TIM) {
P3=0x73;//F1 = 1; F2 = 0; F3 = 0; F4 = 1; MotorStep = 0; TIM=0; } break; }} }
void delay2() //延时50us 子程序 { inti,j; for(i=0;i
TMOD|= 0x11;//00010001 TH0=0xDC; //11.0592M TL0=0x00; IE = 0x8A; TR0 = 1; }
void display(int n) {unsigned char
tab[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsigned char i,k,t,num[4];
num[0]=(m-n)%10; //将总步数的各位分别存在num 数组中 num[1]=((m-n)/10)%10; num[2]=((m-n)/100)%10; num[3]=((m-n)/1000)%10;
for(t=0;t
{ k=0x08; //位选码指向最左一位, 第四位 for(i=0;i
{ P2=k; //从P2口输入位选码
P0=~(tab[num[i]]); //取出显示码 并从P0口输出显示码
k=k>>1; //求下一个位选码 delay2(); } } } main()
{system_Ini(); InitMotor(); while(1) {
while(!(P1&0x08)) //判断是否启动 若没启动则重新判断 P3=0xc0;//停止灯亮 SetMotor(); if(STEP==m) { P3=0xdf; while(1); }
display(STEP); } }
/************************************* [ t1 (1ms)中断] 中断中做 PWM 输出 *************************************/ voidTzd(void) interrupt 1 {
TH0 = (65536-917)/256; //11.0592 定时1ms TL0 = (65536-917)%256; //CT++;
if( CT++==20) //20ms后中断 {
TIM=1; STEP++; CT=0;
}
附录二 电路原理图
摘要
本设计详细介绍了基于单片机的四相步进电机控制系统。步进电机通过输入脉冲信号进行控制,即电机的总转动角度由输入脉冲总数决定,因此,单片机通过向步进电机发送控制信号就能实现对步进电机的控制。
单片机实现的步进电机控制系统具有成本低、使用灵活的特点,该系统采用80C51单片机作为主控芯片,来完成对步进电机转动及LED 显示的控制。 本设计主要由单片机80C51,4相步进电机,7段数码管及一些其他相关元件设计而成,分为按键选择工作状态模块、步进电机工作模块、LED 二极管显示工作状态模块以及4位数码管显示步数模块。可以通过开关来控制系统的启/停工作,当系统运转时,用开关来控制方向,并使相应的指示灯亮起,同样由开关来选择工作模式。运转时,用4位7段数码管来输出步数。最后根据思路所设计出来的硬件图设计相适应的软件。
电路结构简单,设计思路清晰,同时利用KEIL 和Proteus 进行联调仿真,结果比较直观。仿真结果收到了预期的效果。 关键字:四相步进电机、单片机、PROTEUS 仿真
1设计任务及要求
设计一个四相步进电机控制系统,要求系统具有如下功能:用SW11-SW13作为通电方式选择键,SW11为四相单四拍, SW12为四相双四拍,SW13为四相八拍;SW14为启动/停止控制、SW1方向控制;用4位LED 数码管显示工作步数。用3个发光二极管显示状态;正转时红灯亮,反转时黄灯亮,不转时绿灯亮。
2方案论证
2.1 设计思路与方案
本次设计是一个对于四相步进电机的控制系统,而单片机实现的步进电机控制系统具有成本低、使用灵活的特点,此系统选用51单片机即可。 根据要求整个设计大体可分为四块:
一是5个按键SW11-SW13将用户所需来选择步进电机的工作状态。我们将开关连入单片机的P1口,通过按键开关的高低电平状态来读入我们所需的控制信号。硬件上直接把开关分别接在单片机的接口上,通过查询端口信号来动作,将控制信号处理。
二是3个LED 发光二极管的显示步进电机工作状态模块。在设计要求中步进电机正转是红灯亮,反转是黄灯亮,停止不转是绿灯亮。设计中将3个发光二极管分别接到单片机P3口受到单片机的输出信号控制。 三是步进电机的工作模块。要想步进电机按照我们想要的方式运转,将步进电机一端接到+12V的电源,一端接到单片机P3口,受单片机的输出信号控制。 四是4位数码管显示步数的模块。设计中主要是利用软件编程的算法来实现步数的累计和显示,同样,4位数码管接到单片机的P0口和P2口受单片机输出信号的控制,在硬件上使用的是动态显示的接法。
由此可知所需要设计一个系统,可以通过不同按键来选择步进电机的工作方式,且有LED 发光二极管来显示电机对应的工作状态,除此之外还能在数码管上显示出步进电机转动的步数。
2.2总体设计框图
此系统主要由单片机、步进电机、步数显示模块、工作状态控制与显示模块组成。整体框图如图1:
图1 系统整体框图
3系统实现的原理说明
3.1 步进电机控制工作原理
3.1.1步进电机的工作原理
步进电机通过输入脉冲信号进行控制,即电机的总转动角度由输入脉冲总数决定,而电机的转速由脉冲信号频率决定。步进电机的驱动电路是根据单片机产生的控制信号进行工作。因此,单片机通过向步进电机驱动电路发送控制信号就能实现对步进电机的控制。
如图2所示,开始时,开关SB 接通电源,SA 、SC 、SD 断开,B 相磁极和转子0、3号齿对齐,同时,转子的1、4号齿就和C 、D 相绕组磁极产生错齿,2、5号齿就和D 、A 相绕组磁极产生错齿。
当开关SC 接通电源,SB 、SA 、SD 断开时,由于C 相绕组的磁力线和1、4号齿之间磁力线的作用,使转子转动,1、4号齿和C 相绕组的磁极对齐。而0、3号齿和A 、B 相绕组产生错齿,2、5号齿就和A 、D 相绕组磁极产生错齿。依次类推 A 、B 、C 、D 四相绕组轮流供电 则转子会沿着A 、B 、C 、D 方向转动。
四相步进电机按照通电顺序的不同,可分为单四拍、双四拍、八拍三种工作方式。单四拍与双四拍的步距角相等,但单四拍的转动力矩小。八拍工作方式的步距角是单四拍与双四拍的一半,因此,八拍工作方式既可以保持较高的转动力矩又可以提高控制精度。
图2 步进电机工作原理图
3.1.2 步进电机的启停控制
步进电机由于其电气特性, 运转时会有步进感 ,即振动感。为了使电机转动平滑 ,减小振动 ,可在步进电机控制脉冲的上升沿和下降沿采用细分的梯形波 ,可以减小步进电机的步进角 ,提高电机运行的平稳性。在步进电机停转时 ,为了防止因惯性而使电机轴产生顺滑,则需采用合适的锁定波形,产生锁定磁力矩 ,锁定步进电机的转轴,使步进电机的转轴不能自由转动。 3.1.3 步进电机的转向控制
如果给定工作方式正序换相通电,步进电机正转。若步进电机的励磁方式为四相八拍,即 A-AB-B-BC-C-CD-D-DA-A。如果按反序通电换相 ,即则电机就反转。其他方式情况类似。
3.2步数显示模块原理
步数显示模块和工作状态显示模块,都是通过单片机输出信号控制发光二极管LED 的亮灭。其中步数显示模块中LED 构成数码管,要求显示4位十进制数故用到4位数码管。要控制多位的显示电路,需要有字段控制和字位控制。控制方式分为静态显示方式和动态显示方式。静态显示方式,每一位的显示器都需要配一个8位输出口来输出该字位的七段码,需要片外扩展输出口。
而动态显示方式
将各数码管的对应字段的引脚都并联在一起,线路简单,减少接口,不需片外扩展。这里选用动态显示方式。
4硬件设计
4.1系统总原理图
图3 系统总原理图
根据设计要求用PROTEUS 所做的硬件连线图如图3。
4.2各部分硬件原理图设计
4.2.1 单片机控制模块
单片机选用最经典的80C51,其4个I/O口都要用到,P3接步进电机驱动电
路及工作状态显示模块,P0和P2分别接步数显示中对数码管的字段控制及数码管片选,P1接工作状态控制电路,时钟用内部方式需外接晶体振荡器。硬件图如图4所示。
图4 单片机模块原理图
此设计中接的是12MHZ 的晶振,故一个机器周期为1/12us。根据经验数据,与晶振一起的两个电容设为15PF 。单片机的VCC 和GROUD 都隐藏了, 已自动接好,VCC 应设为+5V。 4.2.2按键选择工作状态模块
5个按键开关一端通过电阻接高电平,另一端全部接到地,其中接高电平的一端对应也接到单片机的P1口分别为P1.0~P1.4。当开关断开,就是输入到单片机对应端口高电平,而开关闭合,是使端口接地,输入低电平。所以这个设计中开关断开时才是有效的。各按键功能:
(1)SW11~SW13为工作模式控制开关,SW11接电时,为步进电机单四拍工作模式;SW12接电时,为步进电机双四拍工作模式;SW13接电时,步进电机工作模式为四相八拍。
(2)SW14为启/停控制开关,控制整个系统的开启和关闭。 (3)SW1为正/反转控制开关,控制步进电机的转向。
图5 按键模块原理图
4.2.3步进电机工作模块
将四相步进电机四个端口直接接到单片机P3.0~P3.3即可,另两个端口接到+12V的高电平给步进电机供电。只需在软件编写上控制算法便可以调节这四个端口的高低电平来控制步进电机的开启与停止,正反转以及工作模式。步进电机硬件接线图如图6所示。
图6 步进电机模块原理图
4.2.4工作状态显示模块
LED 发光二极管显示步进电机的工作状态,它们分别接到单片机的P3.5~P3.7。
图7 工作状态显示模块原理图
4.2.5 4位数码管显示步数模块
LED 数码管实际上是由七个发光管组成8字形构成的,加上小数点就是8个。这些段分别由字母a,b,c,d,e,f,g,dp 来表示。当数码管特定的段加上电压后,这些特定的段就会发亮 以形成我们眼睛看到的字样了。通过分时轮流控制各个LED 数码管的COM 端,就使各个数码管轮流受控显示,这就是动态驱动。 P0口和P2口的前四个分别接步数显示中对数码管的字段控制及数码管片选,如图8所示,这里主要是由软件算法来实现单片机输出的控制。
图8 数码管显示模块原理图
5软件设计
5.1系统总体设计
图9 系统总流程图
设计说明:首先是数码管显示清零,单片机再读入P1口输入的按键状态,先判断是否启动,如果没有启动则是绿灯亮并再判断,如果启动了,就接着判断所需的电机工作模式,再读入P1口状态判断电机的转向,输出控制信号为正转红灯亮,反转黄灯亮,由此可以让步进电机按照指定的方式运转,并且累计步数再显示到数码管上。最后检验P1口,是否状态改变,如果改变则步数清零重新开始判断,不改变则继续转动。
5.2步进电机工作模块
5.2.1步进电机的工作方式说明 (1)四相单四拍工作方式
在这种工作方式下,A 、B 、C 、D 三相轮流通电,电流切换三次,磁场旋转一周, 转子向前转过一个齿距角。因此这种通电方式叫做三相单三拍工作方式。这时步距角θ(度)为:
θ=360/mz
式中:m 为定子相数;z 为转子齿数
表1 单四拍的相位控制
(2) 四相双四拍工作方式
这种工作方式每次都是有两相导通,两相绕组处在相同电压之下,以AB ─BC ─CD ─DA —AB(或反之) 方式通电,故称为双四拍工作方式。以这种方式通电, 转子齿所处的位置相当于八拍控制方式中去掉单四拍后的四个位置。它的步距角计算公式与单四拍时的公式相同。
表2 双四拍的相位控制
(3) 四相八拍工作方式
在这种工作方式下,绕组以A —AB —B —BC —C —CD —D —DA —A 时序(或反时序) 转换8次,磁场旋转一周,转子前进一个齿距每次切换均使转子转动0.9°,故这种通电方式称为四相八柏工作方式。其步距角θ(度)为:
θ=360/2mz=180/mz 表3 八拍的数学模型
5.2.2设计说明及流程图
设计说明:在此设计中,采用的是四相步进电机,对于步进电机模块的程序设计采用循环程序设计方法。先把正反转向的控制模型存放在内存单元中,然后再逐
一从单元中取出控制模块并输出。首先启动,通过P1口读入所需的工作方式,即选择步进电机的拍数,然后读入正反转的控制,再来输出对应的控制模型来驱动步进电机转动。
5.3数码管步数显示模块
设计说明:步数显示模块是整个程序里的一个子程序。其是用4位八段数码管来显示工作步数。先将要显示的数化为10进制数,每位分别储存,从P0口输出显示码,P2口输入位选码,需要一定的延时,让此位数字显示闪烁出来。然后修改数组地址,求下一位位选码继续显示,直至输出四位数。这个扫描过程重复50次,保证人眼能观察到步数显示。流程图如图11:
图11 数码管显示模块流程图
6仿真调试记录
如图12所示,当选择电机工作在单四拍,正转的模式下,SW11、SW1接高电平,SW12、SW13接低电平,系统启动,SW14接高电平,电机开始转动。LED 四位显示屏显示工作步数,LED 指示灯红灯亮显示电机正转的状态。
7心得体会
计算机控制技术是一门应用性很强综合性很强的学科,在这次课设中,我充分感受到了这一点。在老师给的课题之中,是来自于各个方面各个领域的应用,不得不说,计算机控制很强大,确实改变了我们的生活。
本次课设收获就是关于软件的使用了。PROTEUS,KEIL51,以前好像也用过 但是平时较少接触,这次的课设让我比较熟练的掌握了这两个学习软件强大的功能,而且发现从PROTEUS 里导出来的电路图特别漂亮和清晰。
计算机控制技术一直是自己比较喜欢的一门学科,拿到课程设计的题目也想着可以好好检验自己的学习成果,一直认为,期末考试是所谓的应试教育,而课程设计似乎更加地考验所学的知识,所谓实践与理论相结合就是这个道理吧。课程设计总能让我有一种我站在山面前的感觉,看上去比较陌生高大,但是攀登的技巧早已在平时的学习中习得,不断地去攀登,不断地在回味课堂上老师讲的东西,书本上的东西,这是一种奇妙的体验。
我明白遇到的电路或者课题并不一定在你的知识范围之内,而面对新的东西我们要冷静地去寻求解决之道,去搜寻网络资源,图书馆资源以及和同学们的讨论之中,再结合自己所学过的知识来吃透理解那些未知的东西,扩宽知识面,这样就会觉得学到了远远超过课堂的东西,但是却源于课堂,想必这就是课设的意义吧,很有收获。
附录一程序清单
#include "reg52.h"
//Motor sbit F1 = P3^0; sbit F2 = P3^1; sbit F3 = P3^2; sbit F4 = P3^3; //sbit TIM=P3^4; #define m 500
/////////////////////////////////////// //步进电机驱动
unsigned char MotorStep=0; unsignedintMotorTimer = 0;
unsignedint TIM,CT,STEP=0,TIM1,num; voidInitMotor() {
F1 = 1; F2 = 1; F3 = 1; F4 = 1; }
voidSetMotor() {
// if(Speed == 0) return; if(P1&0x01)//单四 {
if(P1&0x10)// 正 switch(MotorStep) { case 0: if(TIM) {
P3=0xb1;//F1 = 0; F2 = 0; F3 = 0;F4 = 1;
MotorStep = 1; TIM=0; } break; case 1: if(TIM) {
P3=0xb2;//F1 = 1; F2 = 0;F3 = 0; F4 = 0; MotorStep = 2; TIM=0; } break; case 2: if(TIM) {
P3=0xb4;//F1 = 0; F2 = 1; F3 = 0; F4 = 0; MotorStep = 3;
TIM=0; } break; case 3: if(TIM) {
P3=0xb8;//F1 = 0; F2 = 0; F3 = 1; F4 = 0; MotorStep = 0; TIM=0; } break; } else //单四反 switch(MotorStep) { case 0: if(TIM)
{
P3=0x71;//F1 = 0; F2 = 0; F3 = 0;F4 = 1; MotorStep = 1; TIM=0; } break; case 1: if(TIM) {
P3=0x78;//F1 = 0; F2 = 0;F3 = 1; F4 = 0; MotorStep = 2; TIM=0; } break; case 2: if(TIM)
{
P3=0x74;//F1 = 0; F2 = 1; F3 = 0; F4 = 0; MotorStep = 3;
TIM=0; } break; case 3: if(TIM) { STEP++;
P3=0x72;//F1 = 1; F2 = 0; F3 = 0; F4 = 0; MotorStep = 0; TIM=0; } break; } }
else if(P1&0x02) //双四正转 {
if(P1&0x10)//则正转
switch(MotorStep) { case 0: if(TIM) {
P3=0xb3;//F1 = 0; F2 = 0; F3 = 1;F4 = 1; MotorStep = 1; TIM=0; } break; case 1: if(TIM) {
P3=0xb6;//F1 = 0; F2 = 1;F3 = 1; F4 = 0; MotorStep = 2; TIM=0; } break; case 2: if(TIM) {
P3=0xbc;//F1 = 1; F2 = 1; F3 = 0; F4 = 0; MotorStep = 3; TIM=0; } break; case 3: if(TIM) {
P3=0xb9; //F1 = 1; F2 = 0; F3 = 0; F4 = 1; MotorStep = 0; TIM=0; }
break; } else //双四反 switch(MotorStep) { case 0: if(TIM) {
P3=0x73;//F1 = 0; F2 = 0;F3 = 1;F4 = 1;
MotorStep = 1; TIM=0; } break; case 1: if(TIM) {
P3=0x79;// F1 = 1; F2 = 0; F3 = 0;F4 = 1; MotorStep = 2; TIM=0; } break; case 2: if(TIM) {
P3=0x7c;//F1 = 1; F2 = 1;F3 = 0;F4 = 0; MotorStep = 3; TIM=0; } break; case 3: if(TIM) {
P3=0x76;//F1 = 0; F2 = 1; F3 = 1; F4 = 0;
MotorStep = 0; TIM=0; } break; }}
else if(P1&0x04)//八拍 { if(P1&0x10)//则正转 switch(MotorStep) { case 0: if(TIM) {
P3=0xb1;//F1 = 0; F2 = 0; F3 = 0;F4 = 1; MotorStep = 1; TIM=0; } break;
case 1: if(TIM) {
P3=0xb3;//F1 = 1; F2 = 0;F3 = 0; F4 = 1; MotorStep = 2; TIM=0; } break; case 2: if(TIM)
{
P3=0xb2;//F1 = 1; F2 = 0; F3 = 0; F4 = 0; MotorStep = 3; TIM=0; } break; case 3:
if(TIM) {
P3=0xb6;//F1 = 1; F2 = 1; F3 = 0; F4 = 0; MotorStep = 4; TIM=0; } break; case 4: if(TIM) {
P3=0xb4;// F1 = 0; F2 = 1; F3 = 0; F4 = 0; MotorStep = 5; TIM=0; } break; case 5: if(TIM) {
P3=0xbc;//F1 = 0; F2 = 1; F3 = 1; F4 = 0; MotorStep = 6; TIM=0; } break; case 6: if(TIM) {
P3=0xb8;//F1 = 0; F2 = 0; F3 = 1; F4 = 0; MotorStep = 7; TIM=0; } break; case 7: if(TIM) {
P3=0xb9;//F1 = 0; F2 = 0; F3 = 1; F4 = 1; MotorStep = 0; TIM=0; } break; } else //八拍反 switch(MotorStep) { case 0: if(TIM) {
P3=0x71;// F1 = 0; F2 = 0; F3 = 0;F4 = 1; MotorStep = 1; TIM=0; } break; case 1: if(TIM) {
P3=0x79;// F1 = 0; F2 = 0;F3 = 1; F4 = 1; MotorStep = 2; TIM=0; } break; case 2: if(TIM) {
P3=0x78;//P3=0x78;F1 = 0; F2 = 0; F3 = 1; F4 = 0; MotorStep = 3; TIM=0; } break; case 3:
if(TIM) {
P3=0x7c;//F1 = 0; F2 = 1; F3 = 1; F4 = 0; MotorStep = 4; TIM=0; } break; case 4: if(TIM) {
P3=0x74;// F1 = 0; F2 = 1; F3 = 0; F4 = 0; MotorStep = 5; TIM=0; } break; case 5: if(TIM) {
P3=0x76;// F1 = 1; F2 = 1; F3 = 0; F4 = 0; MotorStep = 6; TIM=0; } break; case 6: if(TIM) {
P3=0x72;//F1 = 1; F2 = 0; F3 = 0; F4 = 0; MotorStep = 7; TIM=0; } break; case 7: if(TIM) {
P3=0x73;//F1 = 1; F2 = 0; F3 = 0; F4 = 1; MotorStep = 0; TIM=0; } break; }} }
void delay2() //延时50us 子程序 { inti,j; for(i=0;i
TMOD|= 0x11;//00010001 TH0=0xDC; //11.0592M TL0=0x00; IE = 0x8A; TR0 = 1; }
void display(int n) {unsigned char
tab[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsigned char i,k,t,num[4];
num[0]=(m-n)%10; //将总步数的各位分别存在num 数组中 num[1]=((m-n)/10)%10; num[2]=((m-n)/100)%10; num[3]=((m-n)/1000)%10;
for(t=0;t
{ k=0x08; //位选码指向最左一位, 第四位 for(i=0;i
{ P2=k; //从P2口输入位选码
P0=~(tab[num[i]]); //取出显示码 并从P0口输出显示码
k=k>>1; //求下一个位选码 delay2(); } } } main()
{system_Ini(); InitMotor(); while(1) {
while(!(P1&0x08)) //判断是否启动 若没启动则重新判断 P3=0xc0;//停止灯亮 SetMotor(); if(STEP==m) { P3=0xdf; while(1); }
display(STEP); } }
/************************************* [ t1 (1ms)中断] 中断中做 PWM 输出 *************************************/ voidTzd(void) interrupt 1 {
TH0 = (65536-917)/256; //11.0592 定时1ms TL0 = (65536-917)%256; //CT++;
if( CT++==20) //20ms后中断 {
TIM=1; STEP++; CT=0;
}
附录二 电路原理图