Practical application of single chip microcomputer to control the forward and reverse rotation of stepper motor[Copy link]
/*This is a practical application to control the forward and reverse rotation of a stepper motor*/ /*A three-phase stepper motor driver is selected, and the p14 line is used for pulse control of the stepper motor*/ /*The p13 line is used for direction control of the stepper motor. p15, p16, p17 are optocoupler switch inputs*/ /*Signal terminals, p20, p21, p22, p23 are connected to the x25045 watchdog memory*/ /*k7, k8 keys are the plus and minus keys for setting the speed parameters of the stepper motor*/ /*k9 is the start key. Press k9 once and the stepper motor starts running until there is a signal input from the p17 line*/ /*k10 is the stop key. Pressing k10 at any time will stop the current operation of the stepper motor*/ /*k11 is the stepper run key. Press it once and the stepper motor moves*/ /*k12 is the reverse run key. Press it once and the stepper motor starts running in reverse until there is a signal input from the p15 line*/ /*If there is a signal input from the p16 line, only the k12 key will work and the other keys will not respond. */ START:do; $INCLUDE(REG51.DCL) DECLARE (addrl,n,I,j,ok,ds) byte; /*define variables*/ declare l(5) byte; declare (dat,data) byte at (30h); declare delay word; DECLARE ACO(11) BYTE CONSTANT (05h,9fh,23h,0bh,99h,49h,/*define LED segment code table*/ 41h,1fh,01h,09h,00h); declare si literally 'p21',sck literally 'p20'; /*define X25045 line*/ declare so literally 'p22',cs literally 'p23'; dog:procedure; /* initialize watchdog x25045 */ cs=1; call time(1); cs=0; call time(1); cs=1; end dog;
run:procedure; /*Stepper motor pulse output program*/ if ok=1 then call dog; do; p14=0; call time(1); p14=1; call time(1); end; end run;
DISPLAY:PROCEDURE(L0,L10); /*Display subroutine*/ DECLARE (L0,L10) BYTE; /*Define display of two digits*/ n=L10; n=aco(n); /*Translate the ten-digit BCD code into segment code*/ sbuf=n; /*Send 164 to display the ten-digit code*/ do while ti=0; /*Wait for the end of sending*/ call dog; /*Reset the watchdog timer*/ end; n=L0; n=aco(n); sbuf=n; /*Send 164 to display the one-digit code*/ do while ti=0; call dog; end; end display; outbyt: procedure(da); /*Write one byte to the watchdog memory*/ declare (i,da) byte; j=da; /* assign the byte to be written to the temporary variable J */ do i=0 to 7; /* shift left 8 bits and send to the port line si */ sck=0; j=scl(j,1); si=cy; sck=1; /* each shift of data follows a clock signal*/ end; end outbyt;
inbyt: procedure; /* read a byte from the watchdog memory */ declare (i,di) byte; j=0; do i=0 to 7; sck=1; sck=0; cy=so; j=scl(j,1); /* read a byte from the watchdog memory and send it to the temporary variable j*/ end; dat=j; end inbyt;
rdregister:procedure; /* read watchdog status register */ sck=0; cs=0; ; /* register read command */ call outbyt(05h); call inbyt; /* status register read in */ sck=0; cs=1; end rdregister;
wbyte:procedure; /* Watchdog memory byte write subroutine */ declare comm byte; sck=0; cs=0; comm=02h; /* write command 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; /* Watchdog memory byte read subroutine */ 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; /* Parameter modification--"add" key processing subroutine + */ if p10=0 then /* If the K7 key is pressed */ do; do while p10=0; /* Wait for the key to be released to take effect */ call dog; /* The watchdog reset subroutine ("feed the dog") must be called here, otherwise the program will be reset by the watchdog */ end; data=data+1; /* Set value +1 */ if data>99 then data=1; /* Specify the upper limit of the set value */ L(1)=data MOD 10; /* Split the tens digit of the set value and send it to the tens digit display variable L(1) */ L(2)=data/10; /* Split the ones digit of the set value and send it to the ones digit display variable L(2) */ call display(L(1),L(2)); /* Send the changed set value to 164 for display */ call time(200); /* Delay */ call dog; call time(200); call dog; call wrenable; /* Set memory write enable */ addrl=00h; /* Set memory address */ dat=l(1); call wbyte; /* Write the value of variable L(1) to memory 00h */ call wrenable; addrl=01h; dat=l(2); call wbyte; /* Write the value of variable L(2) to memory 01h */ end; end incdata; decdata: PROCEDURE; /* Parameter modification---"minus" key processing subroutine- */ IF p11=0 THEN /* k8 key processing subroutine */ do; do while p11=0; call dog; end; DATA=DATA-1; /* Set value -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 key processing subroutine */ do; do while p12=0; call dog; end; if p17=0 then ok=0; /* If there is a signal input on the p17 line, the run flag is set to 0 (stop running) */ p13=1; /* Set the stepper motor to run forward */ call time(200); call dog; do while ok=1; /* When the run flag is 1, execute the speed delay operation */ do sd= 0 to data; /* Determine the pulse given speed of the stepper motor when running according to the numerical delay of the set value data*/ call dog; end; end; END starton;
step: PROCEDURE; /* step */ declare sd byte; p13=1; /* Set the stepper motor to run forward */ call time(200); call dog; IF p33=0 THEN /* k11 key processing subroutine */ do; if p17=0 then ok=0; /* If there is a signal input on p17, then stop running*/ do while p33=0; do sd= 0 to data; /* Call delay and adjust the running speed of the stepper motor */ call dog; call time(2); end; call run; call dog; end; end; ok=0; END step;
back: PROCEDURE; /* Reverse operation processing subroutine */ declare sd byte; IF p34=0 THEN do; do while p34=0; call dog; end; if p15=0 then ok=0; /* When running in reverse direction, if there is a signal input on p15, the stepper motor will stop running */ p13=0; /* Set the stepper motor to run in reverse direction */ call time(200); call dog; do while ok=1; do sd=0 to data; /* Adjust the running speed of the stepper motor according to the set value */ call dog; call time(2); end; call run; if (p15=0 or p32=0 ) then ok=0; /* If there is a signal input on either p15 or p32, stop running */ end;
end; END back;
MAIN$PROGRAM: /* Initialize the main program */ ea=0; /* Disable interrupt */ SCON=00h; /* Set serial port mode 0, serial data output mode */ PCON=00h; tmod=11h; et0=1; enable; /* Enable interrupt (ea=1) */ SCK=0;cs=1; /* Define the initial state of the memory port line */ call wrenable; call wrregister; /* Initialize the watchdog memory */ call wrenable; call dog; p2=0ffh; /* Initialize the status of each port line */ p1=0ffh;ok=0; p14=1;p32=1;p33=1;p34=1; p13=1; ADDRL=00h; /* Read the set speed value from the memory after power-on reset */ CALL rbyte; l(1)=dat; addrl=01h; call rbyte; l(2)=dat; DATA=L(1)+L(2)*10; /* Combine the read values into decimal and store them in variable data */ /* The following is the main loop program */ LOOP: IF p10=0 THEN CALL incdata; /* Check whether each button is pressed */ 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)); /* Send the set value to 164 for display */ call dog; CALL TIME(100); call dog; GOTO LOOP; END START;