步进电机是将电脉冲信号转变为角位移或线位移的开环控制元件。在非超载的情况下,电机的转速、停止的位置只取决于脉冲信号的频率和脉冲数,而不受负载变化的影响,即给电机加一个脉冲信号,电机则转过一个步距角。这一线性关系的存在,加上步进电机只有周期性的误差而无累积误差等特点。使得在速度、位置等控制领域用步进电机来控制变的非常的简单。
步进电机的调速一般是改变输入步进电机的脉冲的频率来实现步进电机的调速,因为步进电机每给一个脉冲就转动一个固定的角度,这样就可以通过控制步进电机的一个脉冲到下一个脉冲的时间间隔来改变脉冲的频率,延时的长短来具体控制步进角来改变电机的转速,从而实现步进电机的调速,本文主要介绍基于单片机的步进电机转速控制设计详解,文章最后附上程序。
基于单片机的步进电机转速控制设计详解
本次设计以CPU选用89C5l作为步进电机的控制芯片.89C51的结构简单并可以在编程器上实现闪烁式的电擦写达几万次以上.使用方便等优点,而且完全兼容MCS5l系列单片机的所有功能。AT89C51是一种带4K字节闪烁可编程可擦除只读存储器(FPEROM—FAlsh ProgrAmmABle And ErAsABle ReAd Only Memory)的低电压,高性能CMOS8位微处理器,俗称单片机。该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。由于将多功能8位CPU和闪烁存储器组合在单个芯片中,ATMEL的AT89C51是一种高效微控制器,为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。
显示电路的用8279芯片来驱动,8279芯片分别接两排显示器,每排为4位显示,分别用来显示步进电机的实际转速与给定转速。
8279与CPU的连接框图如4-11所示:
8279芯片的具体介绍如下;
1) DB0~DB7:双向数据总线。在CPU于827数 据与命令的传送。
2) CLK:8279的系统时钟,100KHZ为最佳选择。
3) RESET:复位输入线,高电平有效。当 RESET 输入端出现高电平时,8279被初始复位。
4) /CS:片选信号。低电平使能,使能时可将命令写入8279或读取8279的数据。
5) A0:用于区分信息的特性。当A0=1时,CPU向8279写入命令或读取8279的状态;当A0为0时,读写一数据。
6) /RD:读取控制线。/RD=0,8279会送数据至外部总线。
7) /WR:写入控制线。/WR=0,8279会从外部总线捕捉数据。
8) IRQ:中断请求输出线,高电平有效。当FIFO RAM 缓冲器中存有键盘上闭合键的键码时,IRQ线升高,向CPU请求中断,当CPU将缓冲器中的输入键数的数据全部读取时,中断请求线下降为低电平。
9) L0~SL3:扫描输出线,用于对键盘显示器扫 描。可以是编码模式(16对1)或译码模式(4对1)。
10) ~RL7:反馈输入线,由内部拉高电阻拉成高电平,也可由键盘上按键拉成低电平。
11) FT、CNTL/STB :控制键输入线,由内部拉高电 阻拉成高电平,也可由外部控制按键拉成低电平。
12) TB0~3、OUTA0~3:显示段数据输出线,可分别作为两个半字节输出,也可作为8位段数据输出口,此时OUTB0为最低位, OUTA3位最高位。
13) 消隐输出线,低电平有效。当显示器切换时或使用消隐命令时,将显示消隐。
8279的初始化程序如下:
INIT:MOV DPTR,#7FFFH ;置8279命令/状态口地址
MOV A,#0D1H ;置清显示命令字
MOVX @DPTR,A ;送清显示命令
WEIT:MOVX A,@DPTR ;读状态
JB ACC.7,WEIT ;等待清显示RAM结束
MOV A,#34H ;置分频系数,晶振12MHz
MOVX @DPTR,A ;送分频系数
MOV A,#00H ;置键盘/显示命令
MOVX @DPTR,A ;送键盘/显示命令
MOV IE,#84H ;允许8279中断
RET
显示子程序如下:
DIS:MOV DPTR,#7FFFH ;置8279命令/状态口地址
MOV R0,#30H ;字段码首地址
MOV R7,#08H ;8位显示
MOV A,#90H ;置显示命令字
MOVX @DPTR,A ;送显示命令
MOV DPTR,#7FFEH ;置数据口地址
LP:MOV A,@R0 ;取显示数据
ADD A,#6 ;加偏移量
MOVC A,@A+PC ;查表,取得数据的段码
MOVX @DPTR,A ;送段码显示
INC R0 ;调整数据指针
DJNZ R7,LP ;
RET
SEG:DB 3FH,06H,5BH,4FH,66H,6DH
;字符0、1、2、3、4、5段码
DB 7DH,07H,7EH,6FH,77H,7CH
;字符6、7、8、9、A、B段码
DB 39H,5EH,79H,71H,73H,3EH
;字符C、d、E、F、P、U段码
DB 76H,38H,40H,6EH,FFH,00H
;字符H、L、-、Y、“空”段码
键盘中断子程序如下:
KEY:PUSH PSW
PUSH DPL
PUSH DPH
PUSH ACC
PUSH B
SETB PSW.3
MOV DPTR,#7FFFH ;置状态口地址
MOVX A,@DPTR ;读FIFO状态
ANL A,#0FH ;
JZ PKYR ;
MOV A,#40H ;置读FIFO命令
MOVX @DPTR,A ;送读FIFO命令
MOV DPTR,#7FFEH ;置数据口地址
MOVX A,@DPTR ;读数据
LJMP KEY1 ;转键值处理程序
PKYR: POP B
POP ACC
POP DPH
POP DPL
POP PSW
RETI ;
KEY1: … … ;键值处理程序
键盘程序清单:
KEY1: ACALL KS1 ; 有无键按下子程序
JNZ LK1 ;有键按下,转去抖延时
AJMP KEY1 ;无键按下,继续扫描
LK1: ACALL DELA12 ;12ms延时程序调用
ACALL KS1 ;判断键是否真正按下
JNZ LK2 ;有键按下,转逐列扫描
AJMP KEY1 ;无键按下,继续扫描
LK2: MOV R2,#0FEH ;设置首列扫描字
MOV R4,#00H ;保存首列号
LK4: MOV DPTR,#7F01H;列扫描字送至PA口
MOV A,R2
MOVX @DPTR,A
INC DPTR ;指向PC口
INC DPTR
MOVX A,@DPTR ;读入行状态
JB ACC.0,LONE ;第0行无键按下,转LONE
MOV A,#00H ;有键按下,设置行首键号
AJMP LKP ;转求键号
LONE: JB ACC.1,LTWO ;第1行无键按下,转LTWO
MOV A,#08H ;有键按下,设置行首键号
AJMP LKP ;转求键号
LTWO: JB ACC.2,LTHR ;第2行无键按下,转LTHR
MOV A,#10H ;有键按下,设置行首键?
AJMP LKP ;转求键号
LTHR: JB ACC.3,NEXT ;第3行无键按下,查下一列
MOV A,#18H ;有键按下,设置行首键
LKP: ADD A,R4 ;求键号,键号=行首键号+列号
PUSH ACC ;保护键号
LK3: ACALL KS1 ;等待键释放
JNZ LK3 ;键未释放,继续等待
POP ACC ;键释放,键号送A
AJMP OVER ;键扫描结束
NEXT: INC R4 ;列号加1,指向下一列
MOV A,R2 ;判断8列扫描完否
JNB ACC.7,KND ;8列扫描完,继续
RL A ;扫描字左移一位
MOV R2,A ;送扫描字
AJMP LK4 ;转下一列扫描
KND: AJMP KEY1
OVER: RET ;键扫描结束
KS1: MOV DPTR,#7F01H ;指向PA口
MOV A,#00H ;设置扫描字
MOVX @DPTR,A ;扫描字送PA口
INC DPTR ;指向PC口
INC DPTR
MOVX A,@DPTR ;读入PC口状态
CPL ;以高电平表示有键按下
ANL A,#0FH ;屏蔽高4位
RET
初始化程序如下:
INIT:MOV DPTR,#7FFFH ;置8279命令/状态口地址
MOV A,#0D1H ;置清显示命令字
MOVX @DPTR,A ;送清显示命令
WEIT:MOVX A,@DPTR ;读状态
JB ACC.7,WEIT ;等待清显示RAM结束
MOV A,#34H ;置分频系数,晶振12MHz
MOVX @DPTR,A ;送分频系数
MOV A,#00H ;置键盘/显示命令
MOVX @DPTR,A ;送键盘/显示命令
MOV IE,#84H ;允许8279中断
RET
显示子程序如下:
DIS:MOV DPTR,#7FFFH ;置8279命令/状态口地址
MOV R0,#30H ;字段码首地址
MOV R7,#08H ;8位显示
MOV A,#90H ;置显示命令字
MOVX @DPTR,A ;送显示命令
MOV DPTR,#7FFEH ;置数据口地址
LP:MOV A,@R0 ;取显示数据
ADD A,#6 ;加偏移量
MOVC A,@A+PC ;查表,取得数据的段码
MOVX @DPTR,A ;送段码显示
INC R0 ;调整数据指针
DJNZ R7,LP ;
RET
键盘中断子程序如下:
KEY:PUSH PSW
PUSH DPL
PUSH DPH
PUSH ACC
PUSH B
SETB PSW.3
MOV DPTR,#7FFFH ;置状态口地址
MOVX A,@DPTR ;读FIFO状态
ANL A,#0FH ;
JZ PKYR ;
MOV A,#40H ;置读FIFO命令
MOVX @DPTR,A ;送读FIFO命令
MOV DPTR,#7FFEH ;置数据口地址
MOVX A,@DPTR ;读数据
LJMP KEY1 ;转键值处理程序
PKYR: POP B
POP ACC
POP DPH
POP DPL
POP PSW
RETI ;
驱动电路子程序的设计
PUSH:MOV R3 , # NUM
PUSH A
PUSH PSW
LOOP: SETB P1.0
ACALL DELAY1
CLR P1.0
ACALL DELAY2
DJNZ R3,LOOP
POP PSW
POP A
RET
延时子程序的设计
MOV R2,#18H
LCALL 7FEBH
RET
ORG 7FEBH ;通用延时子程序
(07EBH & 0FEBH & 。。。)
L7FEB: PUSH 02H ;R2(复位后R2即为02H)存放时间常数,进栈保护
L7FED: PUSH 02H ; R2进栈保护
L7FEF: PUSH 02H ; 进栈
L7FF1: DJNZ R2,$ ;R2不为零等待
POP 02H ;出栈
DJNZ R2,L7FEF ; R2不为零转
POP 02H ; 出栈
DJNZ R2,L7FED ; R2不为零转
POP 02H ; 出栈
DJNZ R2,L7FEB ; R2不为零转
RET ;子程序返回
END
图6-4-1 主程序流程图
主程序如下:
CON: MOV R3, # N
MOV TMOD , # 10H
MOV TL1 , # LOW
MOV TH1 , # H IGH
JNB FLAG ,LEFT
MOV R0 , RM
AJMP TIME - S
LEFT: MOV R0 , LM
TIME: SETB EA
SETB ET1
SETB TR1
步进电机控制程序p3.2正转,p3.3反转,p3.4停止 步进电机接p1.0p1.1p1.2p1.3
org 00h
stop: orl p1,#0ffh ; 步进电机停止
loop:jnB p3.2,for2 ; 如果p3.2按下正转
jnB p3.3,rev2 ; 如果p3.3按下反转
jnB p3.4,stop1 ; 如果p3.4按下停止
jmp loop ;反复监测键盘
for: mov r0,#00h ;正转到tAB取码指针初值
for1:mov A,r0 ;取码
mov dptr,#tABle ;
movC A,@A+dptr
jz for ;是否到了结束码00h
Cpl A ;把ACC反向
mov p1,A ;输出到p1开始正转
jnB p3.4,stop1 ; 如果p3.4按下停止
jnB p3.3,rev2 ; 如果p3.3按下反转
CAll delAy ;转动的速度
inC r0 ;取下一个码
jmp for1 ;继续正转
rev:mov r0,#05h ;反转到tAB取码指针初值
rev1:mov A,r0
mov dptr,#tABle ;取码
movC A,@A+tABle
jz rev ;是否到了结束码00h
Cpl A ;把ACC反向
mov p1,A ;输出到p1开始反转
jnB p3.4,stop1 ; 如果p3.4按下停止
jnB p3.3,rev2 ; 如果p3.3按下反转
CAll delAy ;转动的速度
inC r0 ;取下一个码
jmp rev1 ;继续反转
stop1:CAll delAy ; 按p3.4的消除抖动
jnB p3.4,$ ; p3.4放开否?
CAll delAy ;放开消除抖动
jmp stop
for2:CAll delAy ; 按p3.2的消除抖动
jnB p3.2,$ ; p3.2放开否?
CAll delAy ;放开消除抖动
jmp for
rev2:CAll delAy ; 按p3.3的消除抖动
jnB p3.3,$ ; p3.3放开否?
CAll delAy ;放开消除抖动
jmp rev
delAy:mov r1,#40 ;步进电机的转速20ms
d1:mov r2,#248
djnz r2,$
djnz r1,d1
ret
tABle:
dB 03h,09h,0Ch,06h ;正转表
dB 00 ;正转结束
dB 03h,06h,0Ch,09h ;反转
dB 00 ;反转结束
end
步进电机正反快慢程序
org 00h
x1:mov r3,#48 ;一圈48步
stArt:mov r0,#00h ;正转取码初值
stArt1:
mov p1,#0ffh ;先停止
mov A,r0
mov dptr,#tABle
movC A,@A+dptr
jz stArt ;是否到了结束码00?
Cpl A
mov p1,A ;输出运转
CAll delAy ;调用慢速的延时转动
inC r0 ;取码指针加1取下一个码
djnz r3,stArt1 ;是否走了48步?
mov r3,#48 ;是则重新设定48步
stArt2:
mov p1,#0ffh
mov r0,#05 ;逆转的取码初值
stArt3:mov A,r0
mov dptr,#tABle
movC A,@A+dptr
jz stArt2
Cpl A
mov p1,A
CAll delAy2
inC r0
djnz r3,stArt3
jmp x1 ; 重复开始
DELAY: ; 延时程序 (慢速)
MOV R7,#255
D1:MOV R6,#50
D2: DJNZ R6,D2
DJNZ R7,D1
RET
DELAY2: ; 延时程序 (快速)
MOV R5,#255
D3:MOV R2,#25
D4: DJNZ R2,D4
DJNZ R5,D3
RET
tABle:
dB 03h,09h,0Ch,06h ;正转表
dB 00
dB 06h,0Ch,09h,03h ;反转表
dB 00
end
中断服务程序如下:
INTTO: PUSH A
PUSH PSW
MOV A , @R0
MOV P1 ,A
INC R0
MOV A , # 00H
XRL A , @R0
JNZ NEXT
MOV A , R0
CLR C
SUBB A , # 03H
MOV R0 , A
NEXT: DJNZ R3 , RETU
CLR ET1
CLR EA
RETU: POP PSW
POP A
RETI
利用软件形成脉冲序列的程序清单:
PULSE_S: MOV R7,#NUM ;设定脉冲个数
PUSH A ;保护现场
PUSH PSW
LOOP: SETB P1.0 ;输出高电平
ACALL DELAY1 ;延时
CLR P1.0 ;输出低电平
ACALL DELAY2 ;延时
DJNZ R7,LOOP ;R7≠0,继续输出脉冲
POP PSW ;恢复现场
POP A
RET
定时中断子程序
TIME0: CLR EA ;关中断
INC 30H
MOV A,30H
XRL A,#50H ;判断是否到8秒
JZ S_8 ;8秒定时到,转至S_8
AJMP RECOUN ;未到8秒,继续计时
S_8: SETB P3.2 ;触发外部中断0
NOP
CLR P3.2
NOP
RECOUN: MOV TH0,#3CH
MOV TL0,#0B0H ;设定定时器初值
SETB EA ;开中断
RETI ;中断返回
中断子程序
T_CON: PUSH A ;保护现场
PUSH PSW
MOV R7,#N ;设定控制步数
JNB FLAG,LEFT ;判断旋转方向
RIGHT: MOV R0,RM ;正转模型起始地址
AJMP ROTATE
LEFT: MOV R0,LM
ROTATE: MOV A,@R0 ;取第一拍控制模型
MOV P1,A ;输出第一拍控制模型
ACALL DELAY1 ;延时
INC R0
MOV A,@R0 ;取第二拍控制模型
MOV P1,A ;输出第二拍控制模型
ACALL DELAY1 ;延时
INC R0
MOV A,@R0 ;取第三拍控制模型
MOV P1,A ;输出第三拍控制模型
ACALL DELAY1 ;延时
DJNZ R7,ROTATE ;未走完要求的步数,继续
POP PSW ;恢复现场
POP A
RET ;返回
评论
查看更多