Full Version : Vanhorn's Unipolar Stepper Motor Control (ASM)
avr >>MOTORS SERVOS & PWM >>Vanhorn's Unipolar Stepper Motor Control (ASM)


Admin5- 04-19-2006
David Vanhorn's Stepper.asm

A Stepper motor control for one unipolar motor on port A0-A3

CODE

;***************************************************************************
;
; 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                ;





Forumer™ is Voted #1 Free Forum Hosting provider
Build your own community today with the largest message board hosting company.