; track.asm by Mark Haun, 12 Mar 97 ; Barn door drive controller .org 0 ; reset interrupt vector ljmp start .org 0x0b ; timer 0 overflow interrupt service routine jbc psw.5,count ; implement a one-bit prescaler to get 1 ms setb psw.5 ; ticks reti count: djnz r4,count1 ; decrement the step timer registers R5:R4 cjne r5,#0,count2 sjmp dostep count1: cjne r4,#0ffh,count2 dec r5 count2: reti dostep: mov a,r7 ; check to make sure we aren't stopped, jz count2 ; and return immediately if so dec r6 ; decrement the auxillary counter R6 dec a ; see if we're going forwards or backwards djnz acc,dostep1 dec r0 ; (going backwards) decrement the step counter cjne r0,#0ffh,ds1 ; R1:R0 dec r1 cjne r1,#0ffh,ds1 ; make sure we don't crank the mount beyond mov r1,#0 ; the intended starting place mov r0,#0 reti ds1: setb c ; prepare to step motor once counterclockwise sjmp dostep2 dostep1: inc r0 ; (going forwards) increment the step counter cjne r0,#0,ds2 ; R1:R0 inc r1 ds2: mov a,r7 ; check if we are in track mode dec a jnz ds4 ; if not, go ahead and step push b ; save B register clr a ; if so, check if DPTR should be movc a,@a+dptr ; incremented and R3:R2 updated mov b,r1 cjne a,b,ds3 mov a,#1 movc a,@a+dptr mov b,r0 cjne a,b,ds3 mov a,#2 ; R1:R0 matches a data table entry, so movc a,@a+dptr ; update R3:R2 with a new interval time mov r3,a mov a,#3 movc a,@a+dptr mov r2,a inc dptr ; move DPTR forward to the next table entry inc dptr inc dptr inc dptr ds3: pop b ; restore B register mov a,r3 ; reload the step timer registers mov r5,a mov a,r2 mov r4,a ds4: clr c ; prepare to step motor once clockwise dostep2: acall step ; step the motor reti .org 0x100 ; stepping interval data .word 0 ; initial value .word 253 data: .word 1474 .word 254 .word 1616 .word 253 .word 2998 .word 254 .word 3153 .word 253 .word 3925 .word 254 .word 4094 .word 253 .word 4642 .word 254 .word 4827 .word 253 .word 5255 .word 254 .word 5459 .word 253 .word 5810 .word 254 .word 6039 .word 253 .word 6336 .word 254 .word 6597 .word 253 .word 6851 .word 254 .word 7160 .word 253 .word 7379 .word 254 .word 7768 .word 253 .word 7957 .word 254 .word 8547 .word 253 .word 8705 .word 254 .word 10133 .word 255 .word 10293 .word 254 .word 10831 .word 255 .word 11031 .word 254 .word 11365 .word 255 .word 11617 .word 254 .word 11866 .word 255 .word 12210 .word 254 .word 12405 .word 255 .word 13096 .word 254 .word 13240 .word 255 .word 13600 .word 256 .word 13744 .word 255 .word 14413 .word 256 .word 14614 .word 255 .word 14931 .word 256 .word 15209 .word 255 .word 15431 .word 256 .word 15918 .word 255 .word 16077 .word 256 .word 16803 .word 257 .word 16963 .word 256 .word 17434 .word 257 .word 17664 .word 256 .word 17922 .word 257 .word 18298 .word 256 .word 18474 .word 257 .word 19442 .word 258 .word 19619 .word 257 .word 19981 .word 258 .word 20254 .word 257 .word 20468 .word 258 .word 21838 .word 259 .word 22057 .word 258 .word 22318 .word 259 .word 22746 .word 258 .word 22905 .word 259 .word 23336 .word 260 .word 23494 .word 259 .word 23917 .word 260 .word 24187 .word 259 .word 24395 .word 260 .word 25432 .word 261 .word 25643 .word 260 .word 25905 .word 261 .word 26455 .word 260 .word 26592 .word 261 .word 26613 .word 262 .word 26757 .word 261 .word 27244 .word 262 .word 27523 .word 261 .word 27721 .word 262 .word 28491 .word 263 .word 28690 .word 262 .word 28963 .word 263 .word 30133 .word 264 .word 30414 .word 263 .word 30605 .word 264 .word 31214 .word 265 .word 31406 .word 264 .word 31682 .word 265 .word 32712 .word 266 .word 32995 .word 265 .word 33180 .word 266 .word 33666 .word 267 .word 33852 .word 266 .word 34131 .word 267 .word 35051 .word 268 .word 35337 .word 267 .word 35517 .word 268 .word 35902 .word 269 .word 36082 .word 268 .word 36364 .word 269 .word 37199 .word 270 .word 37488 .word 269 .word 37662 .word 270 .word 37963 .word 271 .word 38138 .word 270 .word 38424 .word 271 .word 39185 .word 272 .word 39479 .word 271 .word 39648 .word 272 .word 39873 .word 273 .word 40042 .word 272 .word 40335 .word 273 .word 41035 .word 274 .word 41333 .word 273 .word 41497 .word 274 .word 41662 .word 275 .word 41826 .word 274 .word 42122 .word 275 .word 42768 .word 276 .word 43072 .word 275 .word 43231 .word 276 .word 43333 .word 277 .word 43491 .word 276 .word 43797 .word 277 .word 44401 .word 278 .word 44717 .word 277 .word 44870 .word 278 .word 44891 .word 279 .word 45039 .word 278 .word 45369 .word 279 .word 45949 .word 280 .word 46294 .word 279 .word 46436 .word 280 .word 46457 .word 281 .word 46621 .word 280 .word 46899 .word 281 .word 47374 .word 282 .word 47659 .word 281 .word 47817 .word 282 .word 47869 .word 283 .word 48025 .word 282 .word 48314 .word 283 .word 48764 .word 284 .word 49059 .word 283 .word 49211 .word 284 .word 49232 .word 285 .word 49389 .word 284 .word 49670 .word 285 .word 50078 .word 286 .word 50366 .word 285 .word 50518 .word 286 .word 50539 .word 287 .word 50699 .word 286 .word 50967 .word 287 .word 51327 .word 288 .word 51599 .word 287 .word 51754 .word 288 .word 51775 .word 289 .word 51932 .word 288 .word 52199 .word 289 .word 52528 .word 290 .word 52797 .word 289 .word 52951 .word 290 .word 52972 .word 291 .word 53133 .word 290 .word 53385 .word 291 .word 53673 .word 292 .word 53928 .word 291 .word 54086 .word 292 .word 54107 .word 293 .word 54268 .word 292 .word 54517 .word 293 .word 54773 .word 294 .word 55019 .word 293 .word 55179 .word 294 .word 55200 .word 295 .word 55361 .word 294 .word 55603 .word 295 .word 55835 .word 296 .word 56079 .word 295 .word 56238 .word 296 .word 56259 .word 297 .word 56427 .word 296 .word 56655 .word 297 .word 56844 .word 298 .word 57069 .word 297 .word 57236 .word 298 .word 57257 .word 299 .word 57418 .word 298 .word 57651 .word 299 .word 57837 .word 300 .word 58073 .word 299 .word 58231 .word 300 .word 58252 .word 301 .word 58427 .word 300 .word 58636 .word 301 .word 58760 .word 302 .word 58962 .word 301 .word 59140 .word 302 .word 59184 .word 303 .word 59356 .word 302 .word 59565 .word 303 .word 59682 .word 304 .word 59889 .word 303 .word 60061 .word 304 .word 60082 .word 305 .org 0x500 ; about 1kbyte later... start: mov sp,#17h ; allow use of Rn banks 00, 01, and 10 acall init ; initialize hardware stop: mov p1,#0fdh ; turn off all but green LED mov a,r7 jz stop1 ; if already stopped, continue dec a jz stop1 ; if tracking, go ahead and stop acall decel ; otherwise, decelerate first stop1: mov r7,#0 ; set condition code to "stopped" clr tr0 ; turn off the timer to stop interrupts stop2: jnb p1.4,rewind jnb p1.6,track jnb p1.7,ff sjmp stop2 track: mov p1,#0f9h ; turn on green and blue LEDs mov a,r7 ; check current condition jz track1 ; if stopped, go ahead and start acall decel ; otherwise, decelerate first track1: clr tr0 ; stop while we peruse the data table mov dptr,#data-8 ; move pointer to the beginning and start ; searching for the right step range srch1: inc dptr inc dptr inc dptr inc dptr mov a,#4 ; fetch MSB of next datum movc a,@a+dptr mov b,r1 clr c ; test if R1 <= data+1 MSB cjne a,b,srch2 mov a,#5 ; R1 = data+1 MSB, so test if R0 >= data+1 LSB movc a,@a+dptr mov b,r0 setb c cjne a,b,srch2 srch2: jc srch1 ; yes, R0 >= data+1 LSB, or no, R1 > data+1 MSB mov a,#2 ; no, R0 < data+1 LSB, or yes, R1 < data+1 MSB, movc a,@a+dptr ; so set R3:R2 = R5:R4 = data+0 mov r3,a mov r5,a mov a,#3 movc a,@a+dptr mov r2,a mov r4,a inc dptr ; move pointer forward to next data entry inc dptr inc dptr inc dptr mov r7,#1 ; set condition code to "tracking" setb tr0 ; turn on the timer to start interrupts track2: jnb p1.4,rewind ; check switches jnb p1.5,stop jnb p1.7,ff sjmp track2 rewind: mov p1,#0fch ; turn on green and red LEDs mov a,r7 ; check current condition dec a dec a djnz acc,rewind1 ; if stopped, tracking, or already ; rewinding, continue acall decel ; otherwise, decelerate first rewind1: mov r7,#2 ; set condition code to "rewinding" acall accel ; accelerate mov r5,#0 ; set stepping interval to 5 ms mov r4,#5 mov r6,#1 ; use auxillary counter to wait for setb tr0 ; the timer ISR to step rewind2: cjne r6,#0,rewind2 ; wait for the step to happen cjne r1,#0,rewind4 ; check for approach of end of travel clr c ; see if within 25 steps of the end cjne r0,#25,rewind3 rewind3: jnc rewind4 sjmp lstop ; if so, go to the stopped condition rewind4: mov r5,#0 ; set stepping interval to 5 ms mov r4,#5 mov r6,#1 ; do one more step, and so on... jnb p1.5,lstop ; check switches jnb p1.6,track jnb p1.7,ff sjmp rewind2 ff: mov p1,#0fch ; turn on green and red LEDs mov a,r7 ; check current condition dec a djnz acc,ff1 ; if stopped, tracking, or already ; fast forwarding, continue acall decel ; otherwise, decelerate first ff1: mov r7,#3 ; set condition code to "fast forwarding" acall accel ; accelerate mov r5,#0 ; set stepping interval to 5 ms mov r4,#5 mov r6,#1 ; use auxillary counter to wait for setb tr0 ; the timer ISR to step ff2: cjne r6,#0,ff2 ; wait for the step to happen mov r5,#0 ; set stepping interval to 5 ms mov r4,#5 mov r6,#1 ; do one more step, and so on... jnb p1.4,rewind ; check switches jnb p1.5,lstop jnb p1.6,ltrack sjmp ff2 lstop: ajmp stop ltrack: ajmp track ; Accel. Accelerate the motor. accel: clr tr0 ; suspend stepping mov b,#100 ; start at 100 ms between steps mov r5,#0 ; load step timer with this interval mov r4,b mov r6,#1 ; go for just one step setb tr0 ; allow timer ISR to start stepping accel1: cjne r6,#0,accel1 ; wait for the one step to occur dec b ; make next step interval 5 ms shorter dec b dec b dec b dec b mov r5,#0 ; reload step timer with this interval mov r4,b cjne r4,#0,accel2 ; return when interval has reached 5 ms ret accel2: mov r6,#1 ; go for one more step... sjmp accel1 ; Decel. Decelerate the motor. decel: clr tr0 ; suspend stepping mov b,#5 ; start at 5 ms between steps mov r5,#0 ; load step timer with this interval mov r4,b mov r6,#1 ; go for just one step setb tr0 ; allow timer ISR to start stepping decel1: cjne r6,#0,decel1 ; wait for the one step to occur inc b ; make next step interval 5 ms longer inc b inc b inc b inc b mov r5,#0 ; reload step timer with this interval mov r4,b cjne r4,#105,decel2 ; return when interval has reached 150 ms ret decel2: mov r6,#1 ; go for one more step... sjmp decel1 ; Step. Turns the stepper motor by one step, the direction being determined ; by the carry flag: clockwise if C=0, counterclockwise if C=1. step: setb rs0 mov a,r0 jc ccw rl a sjmp write ccw: rr a write: mov p3,a mov r0,a clr rs0 ret ; Init. Initializes registers and hardware at power-up. init: mov ie,#82h ; enable only the timer 0 interrupt mov tmod,#32h ; select timer 0 mode 2 (8 bit auto-reload) mov th0,06h ; set up interrupts every 0.5 ms mov tl0,06h mov tcon,#0h ; keep timers off initially mov p1,#0ffh ; initialize port 1 pins (turn off all LEDs) mov p3,#00010001b ; initialize port 3 pins with motor stepping ; pattern setb rs0 mov r0,#00010001b ; R0 in the second group of Rn registers ; holds the same thing clr rs0 clr psw.5 ; clear the user-defined flag mov dptr,#data-4 ; set data pointer to start of data table clr a movc a,@a+dptr mov r1,a ; R1:R0 keep track of current step number mov a,#1 movc a,@a+dptr mov r0,a mov a,#2 movc a,@a+dptr ; get initial value from data table mov r3,a mov r5,a ; R5:R4 (DOWNCOUNTER!) elapsed time since mov a,#3 ; last step movc a,@a+dptr mov r2,a mov r4,a mov r6,#0 ; zero the auxillary step counter mov r7,#0 ; condition code (0=stopped, 1=tracking, ret ; 2=rewinding, 3=fast-forward)