步进电机
步进电机控制器
1. 课题名称
基于51单片机设计并实现步进电机的控制
2. 内容介绍
① 用51单片机实现28BYJ48型四相八拍步进电机的控制。
② 使用单片机输出四路脉冲信号送到驱动电路ULN2003,驱动步进电机的相
应绕组得电,即步进电机获得脉冲,而产生一定的角位移。单片机循序不断的输出时序脉冲,就可以实现步进电机的旋转。
③ 步进电机的控制主要通过6个按键来实现,这6个按键分别表示“正转”、
“反转”、“加速”、“减速”、“消铃”和“停止”,从而实现电机的转向,转速,停止,报警的控制。
④ 通过加减速按键,对电机的转速进行控制,数码管显示转速的等级,一
共有8个转速等级。
⑤ 当电机转速超过最高等级时,蜂鸣器鸣叫,发出超速报警信号,同时自
动停止电机。再按下减速键调节时,电机又可以按设定转速自动转动。 ⑥ 当电机正转时,按下反转键,电机可以自动切换到反转状态,无需按下
停止键。
3. 国内外现状
随着计算机技术和数字控制技术的发展,步进电机的应用也日益广泛。目前,步进电机应用于磁盘驱动器、数控机床、轧钢机、机器人、以及自动化仪表等方面。
近10多年来我国微电机市场一直吸引国内外企业投资。国内巨大的市场潜力和丰富的资源、廉价的劳动力等优势,吸引了众多跨国公司和国内上市公司的目光。
步进电机
步进电动机国外早已发展高性能的混合式结构,我国混合式步进电机90年代才开始发展,混合式电机的使用量近年也在不断增长。
近年来,为克服步进电机低速转动时振动和噪声大的缺点,通过步进电机通过改变减速比等机械传动避开共振区;采用带有细分功能的驱动器;换成步距角更小的步进电机,如三相或五相步进电机;换成交流伺服电机,几乎可以完全克服震动和噪声;在电机轴上加磁性阻尼器,市场上已有这种产品,但机械结构改变较大,使得步进电机的发展更有前途。
近年,又采用步进电机的细分技术,减弱或消除步进电机的低频振动,更有利于减小噪声,同时提高电机的运转精度,使步进电机的控制更为精确。
步进电机因其特有的工作方式,还是有很大市场的,尤其在精度比较高的仪器上,做开环闭环控制上很实用,但是控制部分很少用到51单片机了,51的资源和速度只足以做简单的控制。
本设计只是为了实现低速的电机控制,51单片机足以实现所需功能,考虑到价格合理,设计简单,操作方便,接线简单等优势,由于经费问题,仍然选用51芯片控制。
4. 创新之处
可以直接在正反转之间进行切换,不需要中间按停止键,而且正反转之间切换时间很短。
当电机超速时,电机自动停止,发出报警信号,便于操作者进行降速的调节,同时当转速调整后,电机可以恢复到原来的运转方向和状态。
通过数码管显示转速的等级。
采用ULN2003控制电路,基本原理如下:
单片机输出四路脉冲信号,经过非门和限流电阻,送到ULN2003A。由ULN2003A放大后分给相应的绕组,步进电机的每相绕组并上一个二极管,目的是防止在三极管瞬间截止时,绕组电感所产生很高的感应电动势击穿三极管。当通电状态的改变完成一个循环时,转子转过一个齿距,此次采用八拍控制,实现电机的转动控制。
步进电机
步进电机28BYJ48型四相八拍电机,电压为DC5V。当对步进电机施加一系列连续不断的控制脉冲时,它可以连续不断地转动。每一个脉冲信号对应步进电机的某一相或两相绕组的通电状态改变一次,也就对应转子转过一定的角度(一个步距角)。当通电状态的改变完成一个循环时,转子转过一个齿距。 四相步进电机可以在不同的通电方式下运行,常见的通电方式有单(单相绕组通电)四拍(A-B-C-D-A),双(双相绕组通电)四拍(AB-BC- CD-DA-AB),八拍(A-AB-B-BC-C-CD-D-DA-A);此次设计采用八拍控制,控制时序如下表。
表3-1 步进电机正转的旋转相序:
反转的旋转相序正好与之相反。
5. 具体过程 5.1 硬件电路设计
5.1.1 单片机的最小系统
1.单片机:本次设计使用单片机芯片
STC89C51
·内含4KB的FLASH存储器檫写次数1000
STC89C51
步进电机
次;
·内含128字节的RAM; ·具有32根可编程I/O线; ·具有2个16位编程定时器 STC89C51的工作特性:
·具有6个中断源,5个中断矢量,2级优先权的中断结构; ·具有1个全双工的可编程串行通信接口; ·具有1个数据指针DPTR; ·具有可编程3级程序锁定位;
·STC89C51的工作电源为5(1±0.2)V且典型值为5V; ·STC89C51最高工作频率为24MHZ;
·STC89C51的编程频率为3~24MHZ,编程启动电流和启动电压 分别为1mA、5或12V。
2.晶振:本次设计采用的是12M的晶振,电路图如下:
两只电容在20pF~100pF之间取值,其取值在60pF~70pF时振荡器频率稳定性较高,按照一般经验,外接晶体时两个电容的取值为30pF;外接陶瓷振荡器是两电容的典型值是47pF。
3.复位电路:
在时钟电路工作后,只要在单片机的RST引脚上出现24个时钟振荡脉冲(
2
图5—1—2 晶振电路
步进电机
个机器周期)以上的高电平,单片机便可实现初始化状态服务。为保证应用系统可靠的复位在设计复位电路时,通常使RST引脚保持4ms以上的高电平,只要RST保持高电平,MCS-51单片机就会循环复位;当RST从高电平变为低电平时,MCS-51单片机就从0000H地址开始执行程序,在单片机复位的有效期间,ALE、PSEN 引脚输出高电平。
本次设计采用的是手动复位,其电路图如下:
4.电源电路:
以USB接口作为电源接口
图5—1—3 复位电路
5.1.2 步进电机驱动电路:
由于单片机接口信号不够大需要通过ULN2003放大再连接到相应的电机接口,对电流进行放大,从而增加驱动力。
由于ULN2003不仅有放大信号作用,同时有将信号取反的功能,所以加74LS04反相器,使得输入的脉冲信号与电机正反转所需的时序信号一致,便于控制。
从单片机输出四路脉冲信号,经过非门和限流电阻,送到ULN2003A。由ULN2003A放大后分给相应的绕组,步进电机的每相绕组并上一个二极管,目的是防止在三极管瞬间截止时,绕组电感所产生很高的感应电动势击穿三极管。
非
步进电机
门采用74LS04芯片,其内部共有六个独立的非门,这里只用了其中的四个。
ULN2003驱动器的管脚图:
图5—1—4 ULN2003驱动器的管脚图
步进电机驱动电路:
图5—1—5 步进电机驱动电路
步进电机
5.1.3 键盘电路设计
键盘含有16个键,有9个数字键,分为四行四列,四列分别对应P0.0,P0.1,P0.2,P0.3口,二行分别对应P0.4,P0.5,P0.6,P0.7口。
键盘连接电路图如下所示:
图5—1—6 键盘电路图
按键分配为:
KEY0:电机正转启动; KEY1:电机反转启动; KEY2:电机转动停止; KEY3:电机转动加速; KEY4:电机转动减速;
KEY5:消铃键,当电机转速超过最高等级时,喇叭处于常响的状态,电机
停止转动,此时按此键停止喇叭的蜂鸣。
5.1.4 蜂鸣器电路设计
蜂鸣器电路由单片机芯片的P1.0口驱动。
步进电机
蜂鸣器电路图如下:
图5—1—7 蜂鸣器电路
当电机的转速已经达到最高等级,而此时仍然按动加速键,则蜂鸣器响,提醒超速转动,发出警报,并停止电机的转动。
5.1.5 转速等级显示电路
图5—1—8 数码管显示电路
步进电机
利用74HC164芯片作为位码的移位控制,AB端输入1,而使位选信号流水移动,确保每次只有一位选通,同时通过ULN2803芯片对驱动信号放大,确保数码管有足够大的驱动电流。
利用74HC574锁存器进行数码管段码的锁存。
74HC164是8位串入、并出移位寄存器。74HC164是高速硅门CMOS器件,与低功耗肖特基型 TTL (LSTTL) 器件的引脚兼容;是8位边沿触发式移位寄存器,串行输入数据,然后并行输出。数据通过两个输入端(DSA 或 DSB)之一
串行输入;任一输入端可以用作高电平使能端,控制另一输入端的数据输入。两个输入端或者连接在一起,或者把不用的输入端接高电平,一定不要悬空。时钟(CP) 每次由低变高时,数据右移一位,输入到Q0,Q0是两个数据输入端(DSA和DSB)的逻辑与,它将上升时钟沿之前保持一个建立时间的长度。主复位(MR)输入端上的一个低电平将使
图5—1—9
74HC164
其它所有输入端都无效,同时非同步地清除寄存器,强制所有的输出为低电平。
当直接利用74HC164的输出信号直接驱动数码管时,由于电流比较小,数码管数值显示亮度不够,加ULN2803芯片将信号放大。ULN2803是高压、大电流达林顿阵列,每一个包含8个开漏的集电极达林顿对,它们之间共发射极。每一通道额定电流为500mA,能够承受的最大漏电流为600 mA,内部集成抑制二极管用以感性负载,输入端接相反的输出端以简化电路板布局,输出电流(单输出)最大500mA。
利用数码管显示电路显示电机转速的等级。
步进电机
5.1.6 总体硬件电路
5.1.7 实物图:
步进电机
5.2 软件设计
5.2.1 主程序流程图:
图5—2—1 主程序流程图
步进电机
5.2.2 软件程序清单:
# include <reg51.h> //包含头文件 # define DataPort P0 //定义数据端口 # define zqd 0 // 设正向启动 # define fqd 1 // 设反向启动 # define stop 2 // 电机停止转动 # define jiasu 3 // 电机加速键值 # define jiansu 4 // 电机减速键值 # define xiaoling 5 // 喇叭提醒消铃键值
sbit LATCH1=P1^6; // 定义锁存使能端口 段锁存 sbit LATCH2=P1^5; // 位锁存 sbit HC164AB=P0^7; sbit laba=P1^0;
sbit A1=P2^0; //定义步进电机连接端口 sbit B1=P2^1; sbit C1=P2^2; sbit D1=P2^3;
#define Coil_AB1 {A1=0; B1=0;C1=1;D1=1;} //AB相通电,其他相断电 #define Coil_BC1 {A1=1; B1=0;C1=0;D1=1;} //BC相通电,其他相断电 #define Coil_CD1 {A1=1; B1=1;C1=0;D1=0;} //CD相通电,其他相断电 #define Coil_DA1 {A1=0;B1=1;C1=1;D1=0;} //DA相通电,其他相断电 #define Coil_A1 {A1=0;B1=1;C1=1;D1=1;} //A相通电,其他相断电 #define Coil_B1 {A1=1;B1=0;C1=1;D1=1;} //B相通电,其他相断电 #define Coil_C1 {A1=1;B1=1;C1=0;D1=1;} //C相通电,其他相断电 #define Coil_D1 {A1=1;B1=1;C1=1;D1=0;} //D相通电,其他相断电 #define Coil_OFF {A1=1;B1=1;C1=1;D1=1;} //全部断电
unsigned char code DuanMa[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f, 0x77,0x7c,0x39,0x5e,0x79,0x71};// 共阴,显示段码值0~F
unsigned char dengji=0; //速度等级 unsigned char speed=24; unsigned char keyval; //键盘扫描的键值 unsigned char zflag; //正向转动的标志
static unsigned char times,i;
void DelayUs2x(unsigned char t); //us级延时函数声明
步进电机
void DelayMs(unsigned char t); //ms级延时 void Display(unsigned char disval); //数码管显示函数 unsigned char KeyScan(void); //键盘扫描 unsigned char readkey(void); void baojing(void) ;
//转速过高的提醒
/*------------------------------------------------ 主函数 ------------------------------------------------*/ void main (void) { laba=1; //关扬声器
P2=0xff;
//停止电机
TH0=0x1e; TL0=0x0c; TMOD=0x10; ET0=1;
ET1=1; EA=1;
HC164AB=1;
LATCH2=1;
LATCH2=1; //锁存第一个数码管
LATCH2=0; times=0; i=0;
while (1) //主循环 {
Display(dengji); keyval=readkey(); if(keyval!=0xff) {
switch (keyval) { case zqd: { TR1=1 ; zflag=1; TH1=(65536-1000)/256;
TL1=(65536-1000)%256;
break; } case fqd: { TR1=1 ;
zflag=0;
TH1=(65536-1000)/256;
TL1=(65536-1000)%256;
break;} case stop:{ TR1=0;
//重新赋值 1ms
//重新赋值 1ms
步进电机
P2=0xff; times=0; i=0;
break; } case jiasu:{
if(dengji<8) {dengji++;
speed=speed-3; }
else baojing(); break;
} case jiansu:{
if(dengji>0) {dengji--;
speed=speed+3;} break; }
default: break; }
} }
}
/*------------------------------------------------
uS延时函数,含有输入参数 unsigned char t,无返回值 unsigned char 是定义无符号字符变量,其值的范围是
0~255 这里使用晶振12M,精确延时请使用汇编,大致延时 长度如下 T=tx2+5 uS
------------------------------------------------*/ void DelayUs2x(unsigned char t) { while(--t); }
/*------------------------------------------------
mS延时函数,含有输入参数 unsigned char t,无返回值 unsigned char 是定义无符号字符变量,其值的范围是 0~255 这里使用晶振12M,精确延时请使用汇编 ------------------------------------------------*/ void DelayMs(unsigned char t) {
步进电机
while(t--)
{
//大致延时1mS DelayUs2x(245); DelayUs2x(245); } }
/*------------------------------------------------ 显示函数,用于动态扫描数码管
Num表示需要显示的位数,如需要显示99两位数值则该值输入2 ------------------------------------------------*/ void Display(unsigned char disval)
{
DataPort=DuanMa[disval%10]; // LATCH1=1; LATCH1=1; //段锁存 LATCH1=0; }
/*------------------------------------------------ 按键扫描函数,返回扫描键值
------------------------------------------------*/
unsigned char KeyScan(void) //键盘扫描函数,使用行列逐级扫描法 {
unsigned char Val,keyport,tempkey,row,cow; DataPort=0x0f;//高四位置高,低四位拉低 if(DataPort!=0x0f)//表示有按键按下 {
DelayMs(10); //去抖
取显示的个位
if(DataPort!=0x0f) { row=0;
cow=0; keyport=0xef;
DataPort=keyport;
tempkey=DataPort|0xf0;
while(tempkey==0xff) //检测按键所在行
{ row++;
keyport=keyport<<1;
keyport=keyport|0x01; DataPort=keyport; tempkey=DataPort|0xf0; }
步进电机
if(tempkey!=0xff) { if(tempkey==0xfe) cow=0; else if(tempkey==0xfd) cow=1;
else if(tempkey==0xfb) cow=2;
else cow=3; // 检测按键所在列
} Val=row*4+cow;
} } else Val=0xff; return Val; }
/*----------------------------------------------- 读取键值函数 ------------------------------------------------*/ unsigned char readkey(void) {
unsigned keynum; keynum=KeyScan(); if(keynum!=0xff)
{
while((KeyScan())!=0xff); //等待按键松开 }
return keynum; }
/*---------------------------------------------------------- 转速过高的报警子程序 -------------------------------------------------------*/ void baojing(void) {
P2=0xff;
TR1=0; //关闭电机
times=0; i=0;
TR0=1;
while((readkey())!=xiaoling); TR0=0;