步进电机是机电控制中一种常用的执行机构,它的用途是将电脉冲转化为角位移,通俗地说:当步进驱动器接收到一个脉冲信号,它就驱动步进电机按设定的方向转动一个固定的角度(及步进角)。通过控制脉冲个数即可以控制角位移量,从而达到准确定位的目的;同时通过控制脉冲频率来控制电机转动的速度和加速度,从而达到调速的目的。
t89c2051单片机驱动步进电机的电路和源码
程序
stepper.c
stepper.hex
/*
* stepper.c
* sweeping stepper‘’s rotor cw and cww 400 steps
* copyright (c) 1999 by w.sirichote
*/
#include c:mc518051io.h /* include i/o header file */
#include c:mc518051reg.h
register unsigned char j,flag1,temp;
register unsigned int cw_n,ccw_n;
unsigned char step[8]={0x80,0xc0,0x40,0x60,0x20,0x30,0x10,0x90}
#define n 400
/* flag1 mask byte
0x01 run cw()
0x02 run ccw()
*/
main()
{
flag1=0;
serinit(9600);
disable(); /* no need timer interrupt */
cw_n = n; /* initial step number for cw */
flag1 |=0x01; /* initial enable cw() */
while(1){
{
tick_wait(); /* wait for 10ms elapsed */
energize(); /* round-robin execution the following tasks every 10ms */
cw();
ccw();
}
}
}
cw(){
if((flag1&0x01)!=0)
{
cw_n--; /* decrement cw step number */
if (cw_n !=0)
j++; /* if not zero increment index j */
else
{flag1&=~0x01; /* disable cw() execution */
ccw_n = n; /* reload step number to ccw counter */
flag1 |=0x02; /* enable cww() execution */
}
}
}
ccw(){
if((flag1&0x02)!=0)
{
ccw_n--; /* decremnent ccw step number */
if (ccw_n !=0)
j--; /* if not zero decrement index j */
else
{flag1&=~0x02; /* disable ccw() execution */
cw_n = n; /* reload step number to cw counter */
flag1 |=0x01; /* enable cw() execution */
}
}
}
tick_wait(){ /* cputick was replaced by simpler asm code 10ms wait */
asm“ jnb tcon.5,*”; /* wait for tf0 set */
asm“ clr tcon.5”; /* clear tf0 for further set */
asm“ orl th0,#$dc”; /* reload th0 with $dc, tl0 = 0 */
}
energize(){
p1 = step[(j&0x07)]; /* only step 0-7 needed */
}
一、步进电机常识
常见的步进电机分三种:永磁式(pm),反应式(vr)和混合式(hb),永磁式步进一般为两相,转矩和体积较小,步进角一般为7.5度 或15度;反应式步进一般为三相,可实现大转矩输出,步进角一般为1.5度,但噪声和振动都很大。在欧美等发达国家80年代已被淘汰;混合式步进是指混合了永磁式和反应式的优点。它又分为两相和五相:两相步进角一般为1.8度而五相步进角一般为 0.72度。这种步进电机的应用最为广泛。
二、永磁式步进电机的控制
下面以电子爱好者业余制作中常用的永磁式步进电机为例,来介绍如何用单片机控制步进电机。
图1是35by型永磁步进电机的外形图,图2是该电机的接线图,从图中可以看出,电机共有四组线圈,四组线圈的一个端点连在一起引出,这样一共有5根引出线。要使用步进电机转动,只要轮流给各引出端通电即可。将com端标识为c,只要ac、 c、bc、 c,轮流加电就能驱动步进电机运转,加电的方式可以有多种,如果将com端接正电源,那么只要用开关元件(如三极管),将a、 、b、 轮流接地。
下表列出了该电机的一些典型参数:
表1 35by48s03型步机电机参数
型号 步距角 相数 电压 电流 电阻 最大静转距 定位转距 转动惯量
35by48s03 7.5 4 12 0.26 47 180 65 2.5
有了这些参数,不难设计出控制电路,因其工作电压为12v,最大电流为0.26a,因此用一块开路输出达林顿驱动器(uln2003)来作为驱动,通过 p1.4~p1.7来控制各线圈的接通与切断,电路如图3所示。开机时,p1.4~p1.7均为高电平,依次将p1.4~p1.7切换为低电平即可驱动步进电机运行,注意在切换之前将前一个输出引脚变为高电平。如果要改变电机的转动速度只要改变两次接通之间的时间,而要改变电机的转动方向,只要改变各线圈接通的顺序。
图1 35by48s03型步进电机外形图
图2 35by48s03型步进电机的接线图
图3 单片机控制35by48s03型步进电机的电路原理图
三、步进电机的驱动实例
要求:控制电路如图3所示,开机后,电机不转,按下启动键,电机旋转,速度为25转/分,按下加1键,速度增加,按下减1键,速度降低,最高速度为100转/分,最低转带为25转/分,按下停止键,电机停转。速度值要求在数码管上显示出来。
1.要求分析
按上面的分析,改变转速,只要改变p1.0~p1.3轮流变低电平的时间即可达到要求,这个时间不应采用延时来实现,因为会影响到其他功能的实现。这里以定时的方式来实现。下面首先计算一下定时时间。
按要求,最低转速为25转/分,而上述步进电机的步距角为7.5,即每48个脉冲为1周,即在最低转速时,要求为1200脉冲/分,相当于50ms/脉冲。而在最高转速时,要求为100转/分,即48000脉冲/分,相当于12.5ms/脉冲。可以列出下表
表1 步进电机转速与定时器定时常数关系
速度 单步时间(us) th1 tl1 实际定时(us)
25 50000 76 0 49996.8
26 48077 82 236 48074.18
27 46296 89 86 46292.61
28 44643 95 73 44640.155
… … … … …
100 12500 211 0 12499.2
表中不仅计算出了th1和tl1,而且还计算出了在这个定时常数下,真实的定时时间,可以根据这个计算值来估算真实速度与理论速度的误差值。
表中th1和tl1是根据定时时间算出来的定时初值,这里用到的晶振是11.0592m。有了上述表格,程序就不难实现了,使用定时/计数器t1为定时器,定时时间到后切换输出脚即可。
2.程序实现
定义dsb-1a实验板的s1为启动键,s2为停止键,s3为加1键,s4为减1键,程序如下:
startend bit 01h ;起动及停止标志
minspd equ 25 ;起始转动速度
maxspd equ 100 ;最高转动速度
speed data 23h ;流动速度计数
djcount data 24h ;控制电机输出的一个值,初始为11110 111
hidden equ 10h ;消隐码
counter data 57h ;显示计数器
dispbuf data 58h ;显示缓冲区
org 0000h
ajmp main
org 000bh
jmp disp
org 001bh
jmp djzd
org 30h
main:
mov sp,#5fh
mov p1,#0ffh
mov a,#hidden
mov dispbuf,a
mov dispbuf+1,a
mov dispbuf+2,a
mov djcount,#11110111b
mov speed,#minspd ;起始转动速度送入计数器
clr startend ;停转状态
mov tmod,#00010001b ;
mov th0,#high(65536-3000)
mov tl0,#low(65536-3000)
mov th1,#0ffh;
mov tl1,#0ffh
setb tr0
setb ea
setb et0
setb et1
loop: acall key ;键盘程序
jnb f0,m_next1 ;无键继续
acall keyproc ;否则调用键盘处理程序
m_next1:
mov a,speed
mov b,#10
div ab
mov dispbuf+5,b ;最低位
mov b,#10
div ab
mov dispbuf+4,b
mov dispbuf+3,a
jb startend,m_next2
clr tr1 ;关闭电机
jmp loop
orl p1,#11110000b
m_next2:
setb tr1 ;启动电机
ajmp loop ;主程序结束
;---------------------------------------
d10ms:
……
;---------延时程序,键盘处理中调用
keyproc:
mov a,b ;获取键值
jb acc.2,startstop ;分析键的代码,某位被按下,则该位为1
jb acc.3,keysty
jb acc.4,upspd
jb acc.5,dowspd
ajmp key_ret
startstop:
setb startend ;启动
ajmp key_ret
keysty:
clr startend; ;停止
ajmp key_ret
upspd:
inc speed;
mov a,speed
cjne a,#maxspd,k1 ;到了最多的次数?
dec speed ;是则减去1,保证下次仍为该值
k1:
ajmp key_ret
dowspd:
dec speed
mov a,speed
cjne a,#maxspd,key_ret ;不等(未到最大值),返回
mov speed,#minspd;
key_ret:
ret
key:
……获取键值的程序
ret
djzd: ;定时器t1用于电机转速控制
push acc
push psw
mov a,speed
subb a,#minspd ;减基准数
mov dptr,#djh
movc a,@a+dptr
mov th1,a
mov a,speed
subb a,#minspd
mov dptr,#djl
movc a,@a+dptr
mov tl1,a
mov a,djcount
cpl a
orl p1,a
mov a,djcount
jnb acc.7,d_next1
jmp d_next2
d_next1:
mov djcount,#11110111b
d_next2:
mov a,djcount
rl a
mov djcount,a ;回存
anl p1,a
pop psw
pop acc
reti
djh: db 76,82,89,95,100,106,110,115,119,123,12……
djl: db 0,236,86,73,212,0,214,96,163,165
……
disp: ;显示程序
pop psw
pop acc
……
reti
bittab: db 7fh,0bfh,0dfh,0efh,0f7h,0fbh
disptab:db 0c0h,0f9h,0a4h,0b0h,99h,92h,82h,0f8h,80h,90h,88h,83h,0c6h,0a1h,86h,8eh,0ffh
end
3.程序分析
本程序主要由键盘程序、显示器程序、步进电机驱动程序三部份组成,主程序首先初始化各变量,将显示器的高3位消隐,步进电机驱动的各引脚均输出高电平,然后调用键盘程序,并作判断,如果有键按下,则调用键盘处理程序,否则直接转下一步。下一步是将当前的转速值转换为bcd码,送入显示缓冲区;接着判断 startend这个位变量,是“1”还是“0”,如果是“1”,则开启定时器t1,否则关闭定时器t1,为防止关闭时某一相线圈长期通电,因此,在关闭定时器t1时,将p1.0~p1.3均置高。至此,主程序的工作即结束。这里为简便起见,这里没有做高位“0”消隐的工作,即如果速度为10转/分,则显示值“010”,读者可以自行加入相关的代码来处理这一工作。
步进电机的驱动工作是在定时器t1的中断服务程序中实现的,由前述分析,每次的定时时间到达以后,需要将p1.0~p1.3依次接通,程度中用了一个变量djcntr来实现这一功能,在主程序初始化时,该变量被赋予初值 11110111b,进入到定时中断以后,将该变量取出送acc累加器,并在累加器中进行左移,这样,该数值就变为1110 1111,然后将该数与p1 相“与”,此时,p1.4即输出低电平,第二次进入中断时,先将该数取反,成为 0001 0000,然后将该数与p1相“或”,这样,p1.4即输出高电平,关断了相应的线圈,然后将该数重新取出,并作左移,即 1110,1111右移成为1101 1111,将该数与p1相“与”,这样p1.5即输出低电平,依次类推,p1.7~p1.4即循环输出低电平。当这一数据变为0111 1111后,需要作适当的改动,将数据重新变回 1111 0111,进行第二次循环,相关代码,请读者自行分析。
定时时间又是如何确定的呢?这里用的是查表的方法,首先用excel计算得出在每一种转速下的th值和tl值,然后,分别放入djh和djl表中,在进入t1中断程序之后,将速度值变量speed送入累加器acc,然后减去基数25,使其基数从 0开始计数,然后分别查表,送入th1和tl1,实现重置定时初值的目的。
看完这一部份内容以后,请读者自行完成以下工作:
1. 更改程序,将s1定义为“启动/停止”,而s2定义为“方向”,按下s2,切换电机旋转方向。
2. 更改程序,要求转速从1到100。
3. 更改程序,实现首位无效零消隐
借力5G和全息技术 全球首次全息影像国际长途通话成功上演
基于多模态语义SLAM框架
双极性码,什么是双极性码
三星note8最新消息:三星Note8尚未发售就已经成为2017最值得买的手机?
光电传感器在机场物流行业的设计应用
使用单片机控制步进电机的资料和代码详细说明
高精准度仪表放大器LTC2053
什么是硬件防火墙高防服务器,它有什么作用
人机交互的发展为触控应用领域带来新机遇
MIUI 12新功能:小窗胶囊多任务处理方便至极
按功能分集成电路有哪些类型 集成电路的工作速度主要取决于什么
平台稳定性里程碑 | Android 14 Beta 3 发布
华为在欧注册“方舟操作系统”商标
Speech2Face模型主要是为了研究语音与相貌之间的关联性?
cam350使用教程_cam350使用注意事项
进行PLC通讯和变频器的简洁结合设计
PPLN晶体详解,如何使用PPLN晶体
iGameRTX2080TiVulcanXOC评测 最强做工性能以及个性集于一身
国外牛人制作特斯拉炮:可以发射闪电
英特尔联合微软发布全新SGX指令集保护敏感数据