您的当前位置:首页单片机控制步进电机正反转的实际应用程序

单片机控制步进电机正反转的实际应用程序

2020-12-09 来源:爱问旅游网
单片机控制步进电机正反转的实际应用程序

/*这是一个控制步进电机正反转的实际应用程序*/

/*选用的是三相步进电机驱动器,p14口线用做步进电机的脉冲控制*/ /*p13口线用做步进电机的方向控制。p15,p16,p17是光耦开关量输入*/ /*信号端,p20,p21,p22,p23与x25045看门狗存储器相连*/ /*k7,k8键是设定步进电机转动速度参数的加减键*/

/*k9是启动运行键,按一下k9,步进电机开始运行,直到p17口线有信号输入才停止*/ /*k10是停止键,任何时候按下k10都将停止步进电机当前的运行*/ /*k11是步进运行键,按一下,步进电机动一下*/

/*k12键是反向运行键,按一下,步进电机开始反向运行,知道p15口线有信号才停止*/ /*如果p16口线有信号输入,则只有k12键才起作用,其它键都没反应。*/ START:do;

$INCLUDE(REG51.DCL)

DECLARE (addrl,n,I,j,ok,ds) byte; /*定义变量*/

declare l(5) byte;

declare (dat,data) byte at (30h); declare delay word;

DECLARE ACO(11) BYTE CONSTANT (05h,9fh,23h,0bh,99h,49h,/*定义LED段码表*/ 41h,1fh,01h,09h,00h);

declare si literally 'p21',sck literally 'p20'; /*X25045囗线定义*/ declare so literally 'p22',cs literally 'p23'; dog:procedure; /* 初始化看门狗x25045 */ cs=1;

call time(1); cs=0;

call time(1); cs=1; end dog;

run:procedure; /*步进电机运行脉冲输出程序*/ if ok=1 then call dog; do; p14=0;

call time(1); p14=1;

call time(1); end; end run;

DISPLAY:PROCEDURE(L0,L10); /*显示子程序*/ DECLARE (L0,L10) BYTE; /*定义显示二位*/ n=L10;

n=aco(n); /*十位数BCD码译成段码*/ sbuf=n; /*十位数送164显示*/ do while ti=0; /*等待发送结束*/ call dog; /*看门狗定时器复位*/ end; n=L0; n=aco(n);

sbuf=n; /*个位数送164显示*/

do while ti=0; call dog; end;

end display;

outbyt: procedure(da); /*向看门狗存储器写入一字节*/ declare (i,da) byte;

j=da; /*将要写入的字节赋给临时变量J */ do i=0 to 7; /*左移8位,送到口线si */ sck=0; j=scl(j,1); si=cy;

sck=1; /*每移一位数据,跟一个时钟信号*/ end;

end outbyt;

inbyt: procedure; /* 从看门狗存储器读出一字节 */ declare (i,di) byte; j=0;

do i=0 to 7; sck=1; sck=0; cy=so;

j=scl(j,1); /*从看门狗存储器读出一字节送入临时变量j*/ end; dat=j; end inbyt;

wrenable: procedure; /* 置看门狗写使能*/ sck=0; cs=0;

; /* write enable command */

call outbyt(06h); /* x25045 写使能指令06h */ cs=1; sck=0;

end wrenable;

wrdisable: procedure; /* 置看门狗写禁止 */ sck=0; cs=0;

; /* write disable command */ call outbyt(04h); sck=0; cs=1;

end wrdisable;

wrregister: procedure; /* 写状态寄存器 */

sck=0; cs=0;

dat=01h; /* write register command */ call outbyt(dat);

; /* 00h--1.4S, 20h--200MS, 10h--600MS, 30h--disable Wdog */ call outbyt(00h); /* 设定看门狗定时时间 */ ;

sck=0; cs=1;

call time(200); /* wait to complete writting cycle */ end wrregister;

rdregister:procedure; /* 读看门狗状态寄存器 */ sck=0; cs=0;

; /* register read command */ call outbyt(05h);

call inbyt; /* status register read in */ sck=0; cs=1;

end rdregister;

wbyte:procedure; /* 看门狗存储器字节写入子程序 */ declare comm byte; sck=0; cs=0;

comm=02h; /* 写指令 02h */

call outbyt(comm); call outbyt(addrl);

call outbyt(dat); /* send one byte data to X25043 */ cs=1; sck=0;

call time(150); end wbyte;

rbyte:procedure; /*看门狗存储器字节读出子程序 */ declare comm byte; sck=0; cs=0;

comm=03h; /* read command */ call outbyt(comm); call outbyt(addrl);

call inbyt; /* read one byte to */ sck=0; cs=1;

end rbyte;

incdata: procedure; /* 参数修改--\"加\"键处理子程序+ */ if p10=0 then /* 如果K7键按下*/

do;

do while p10=0; /* 等待键松开有效 */

call dog; /* 此处必需调用看门狗复位子程序(\"喂狗\"),否则程序将被看门狗复位*/ end;

data=data+1; /* 设定值+1 */

if data>99 then data=1; /* 规定设定值的上限*/

L(1)=data MOD 10; /*将设定值的十位数拆出来送给十位数显示变量L(1) */ L(2)=data/10; /*将设定值的个位数拆出来送给个位数显示变量L(2) */ call display(L(1),L(2)); /* 将改变后的设定值送164显示出来*/ call time(200); /* 延时 */

call dog;

call time(200); call dog;

call wrenable; /* 置存储器写使能 */ addrl=00h; /* 置存储器地址 */

dat=l(1);

call wbyte; /* 将变量L(1)的值写入存储器00h位置 */ call wrenable; addrl=01h; dat=l(2);

call wbyte; /* 将变量L(2)的值写入存储器01h位置 */ end;

end incdata;

decdata: PROCEDURE; /* 参数修改---\"减\"键处理子程序- */ IF p11=0 THEN /* k8 键处理子程序 */ do;

do while p11=0; call dog; end;

DATA=DATA-1; /* 设定值-1 */ if data=0 then data=99; L(1)=data MOD 10; L(2)=data/10;

call display(l(1),l(2)); call dog;

call time(200); call dog;

call time(200); call dog;

call wrenable; addrl=00h; dat=l(1); call wbyte; call wrenable; addrl=01h; dat=l(2); call wbyte; end;

END decdata;

starton: PROCEDURE; /* start */ declare sd byte;

if p12=0 THEN /* K9键处理子程序 */

do;

do while p12=0; call dog; end;

if p17=0 then ok=0; /* 如果p17 口线上有信号输入,则运行标志置0 (停止运行)*/ p13=1; /* 置步进电机正向运转 */

call time(200); call dog;

do while ok=1; /* 当运行标志为1时,执行速度延时操作 */

do sd= 0 to data; /* 根据设定值 data的数值延时来确定步进电机运行时的脉冲给定速度*/

call dog; end; end;

END starton;

step: PROCEDURE; /* step */ declare sd byte;

p13=1; /* 置步进电机正向运转 */ call time(200);

call dog;

IF p33=0 THEN /* k11键处理子程序 */

do;

if p17=0 then ok=0; /* 如果p17上有信号输入,则停止运行*/ do while p33=0;

do sd= 0 to data; /* 调用延时,调整步进电机的运行速度 */ call dog; call time(2); end; call run; call dog; end; end; ok=0; END step;

back: PROCEDURE; /* 反向运行处理子程序 */

declare sd byte; IF p34=0 THEN do;

do while p34=0; call dog; end;

if p15=0 then ok=0; /* 反向运行时,如果遇到p15上有信号输入,则停止步进电机运行 */ p13=0; /* 置步进电机反向运行 */

call time(200); call dog;

do while ok=1;

do sd=0 to data; /*根据设定值调节步进电机的运行速度 */

call dog; call time(2); end; call run;

if (p15=0 or p32=0 ) then ok=0; /* p15 或 p32 口线任意一个有信号输入,停止运行 */ end; end;

END back;

MAIN$PROGRAM: /* 初始化主程序 */ ea=0; /* 关中断 */

SCON=00h; /*置串口方式0 ,串行数据输出模式*/ PCON=00h; tmod=11h;

et0=1;

enable; /* 开中断 (ea=1) */

SCK=0;cs=1; /* 定义存储器口线初始状态 */ call wrenable;

call wrregister; /* 看门狗存储器 初始化 */ call wrenable; call dog;

p2=0ffh; /* 初始化各个口线的状态 */

p1=0ffh;ok=0;

p14=1;p32=1;p33=1;p34=1; p13=1;

ADDRL=00h; /* 上电复位后从存储器中读出设定的速度值 */

CALL rbyte; l(1)=dat; addrl=01h; call rbyte; l(2)=dat;

DATA=L(1)+L(2)*10; /*将读出的值合并成十进制,存入变量data中 */ /* 以下是主循环程序 */

LOOP:

IF p10=0 THEN CALL incdata; /* 检测各个按键是否有按下 */ IF p11=0 THEN CALL decdata; if p12=0 then do; ok=1;

call starton; end;

if p34=0 then do; ok=1; call back; end;

if p33=0 then do; ok=1; call step; end; call dog;

CALL DISPLAY(L(1),L(2)); /* 将设定值送164显示 */ call dog;

CALL TIME(100); call dog; GOTO LOOP; END START;

因篇幅问题不能全部显示,请点此查看更多更全内容