;*************************************************************************** ; ; File Name :'STEPPER.asm" ; Title : ; Date : ; Version : ; Support telephone :765 287 1987 David B. VanHorn ; Support fax :765 287 1989 ; Support Email :dvanhorn@cedar.net ; Target MCU :AT90S8515 ; ;***************************************************************************; ; M O D I F I C A T I O N H I S T O R Y ; ; ; rev. date who why ; ---- -------- --- ------------------------------------------ ; 0.01 98.08.30 dvh Creation ; 0.02 98.09.03 dvh More info on how to electrically drive steppers ; ;******************************************************************** ; ; ;A simple routine to control a stepper motor. ;Full or half-step, outputs designed for unipolar motors. ;Outputs on port A, bits 0-3 ; ;Full stepping ; ;Phase Current ; ;0000 1 (off) ;1000 1 1st state ;0100 1 ;0010 1 ;0001 1 4th state ; ;Half-Stepping ; ;Phase Current ; ;0000 0 (off) ;1000 1 1st state ;1100 0 ;0100 1 ;0110 0 ;0010 1 ;0011 0 ;0001 1 ;1001 0 8th state ; ; ; ULN2003 driver IC (2803 is similar, but one more driver, and 2 more pins) ; ; Inputs Outputs ; ; 1 ----> 16 High input = low output (coil active) ; 2 ----> 15 ; 3 ----> 14 ; 4 ----> 13 ; 5 ----> 12 ; 6 ----> 11 ; 7 ----> 10 ; GND 8 9 Diode ; ; ; ;Each driver sinks current when it's input is at a logic high. Each driver has a ;protection diode, all diodes come to pin 9, which should be connected to the ;stepper's +V supply. ;For this application, connect the AVR stepper output pins to pins 1,2,3,4 of ;the 2003, pin 8 of the IC to the development board's ground, and 16,15,14,13 ;of the 2003 to the stepper's coil leads. Connect the two common leads of the ;stepper to pin 9, and apply a modest voltage (3-6V) from an external power supply. ;Be sure to tie the external supply ground to the development board ground. ; ;This IC uses the stepper's coil resistance to limit the applied current, so be sure ;that your stepper supply voltage does not exceed the current rating of the chip, or ;the thermal limits of the motor. Rare earth magnet steppers can be permanently "cooked" ;by applying too much power for too long. The chip's own voltage limit is 50V, but the ;curent limit and thermal limits are much more important. The IC is rated for 500mA max. ; ;A good treatment on stepper motors is available at: ;http://www.cs.uiowa.edu/~jones/step/circuits.html ; ;Going forward, step up the table, going backward, step back :) ;Up to 1mS per step (or half-step) with a simple control routine based on the 1mS ISR ; ;Ram variables ; ;Step_Dir Forward or reverse (0=Reverse, 1=forward, anything else= no step)? ;Step_Time mS per phase (0-255) ;Step_State Where are we now? A pointer into the stepper output table ;Step_Mode Full or half step (0=full 1=half) ;Step_Speed Reload value for Step_Time. Your application can change this and ; alter the stepper speed. Beware, steppers don't like large changes ; in velocity. ; Step_Motor: ;First, see if we're stepping this time lds TEMP,Step_Time ;Is it time to step? cpi TEMP,$00 ; breq Step_Direction ;If so, then check direction, else ret ;just bail Step_Direction: ;Then determine the direction lds TEMP,Step_Dir ;Get the current direction and TEMP,TEMP ; breq Step_Reverse ; cpi TEMP,$01 ;Is it forward? breq Step_Forward ;Go if so. rjmp Step_Done ;else it's no step Step_Forward: ;Then wether full or half (forward) lds TEMP,Step_Mode ;Full or half and TEMP,TEMP ; breq Step_FF ; rjmp Step_FH ; Step_Reverse: ;Or wether full or half (reverse) lds TEMP,Step_Mode ;Full or half? and TEMP,TEMP ; breq Step_RF ; rjmp Step_RH ; ; ;*************************************************************************************** ; ;Step forard, a full step ; Step_FF: lds TEMP,Step_State ;Get the current state inc TEMP ;advance one step on the full step table cpi TEMP,$04 ; brne Step_FFA ; ldi TEMP,$00 ; Step_FFA: ldi ZL,low(Full_Step_Table*2) ;Make the Z reg point at the table ldi ZH,high(Full_Step_Table*2) ;preparing for the LPM instruction rjmp Step_Output ; ; ;Step forward, a half step ; Step_FH: lds TEMP,Step_State ;Get the current state inc TEMP ;advance one step on the full step table cpi TEMP,$08 ; brne Step_FHA ; ldi TEMP,$00 ; Step_FHA: ldi ZL,low(Half_Step_Table*2) ;Make the Z reg point at the table ldi ZH,high(Half_Step_Table*2) ;preparing for the LPM instruction rjmp Step_Output ; ; ;Step reverse a full step ; Step_RF: lds TEMP,Step_State ;Get the current state dec TEMP ;advance one step on the full step table cpi TEMP,$FF ; brne Step_RFA ; ldi TEMP,$03 ; Step_RFA: ldi ZL,low(Full_Step_Table*2) ;Make the Z reg point at the table ldi ZH,high(Full_Step_Table*2) ;preparing for the LPM instruction rjmp Step_Output ; ; ;Step reverse a half step ; Step_RH: lds TEMP,Step_State ;Get the current state dec TEMP ;advance one step on the full step table cpi TEMP,$FF ; brne Step_RHA ; ldi TEMP,$07 ; Step_RHA: ldi ZL,low(Half_Step_Table*2) ;Make the Z reg point at the table ldi ZH,high(Half_Step_Table*2) ;preparing for the LPM instruction rjmp Step_Output ; ; ;Whichever and how far, output the motor states ; Step_Output: sts Step_State,TEMP ; lsl TEMP ;Mult x 2, because we store words in rom add ZL,TEMP ;Add the calculated offset brcc STO_A ;If no carry, then we're done inc ZH ;Handle carry STO_A: lpm ;look up character mov TEMP,R0 ; andi TEMP,$0F ;Mask off non-stepper bits in TEMP2,PORTA ; andi TEMP2,$F0 ;Kill old stepper bits or TEMP2,TEMP ; out PORTA,TEMP2 ; Step_Done: lds TEMP,Step_Rate ;Restart the timer for the next step sts Step_Time,TEMP ; ret ;