Full Version : Unipolar Stepper Motor Driver (AVR ASM)
avr >>MOTORS SERVOS & PWM >>Unipolar Stepper Motor Driver (AVR ASM)


AVR_Admin- 04-16-2006
For controlling three stepper-motors which I intend on using to make a cnc machine, together with the program turbocnc.

Chip controls motors with 6 input-pins, 2 for each motor. One for step, and one for direction of step, and 4 outputs per motor.

Edit: I've updated the source alot, very small easy program but does it's job very fast. Made a board in eagle which works as it should.


CODE
;**********************************************************************
; 3 axis stepper motor driver, by Njål Brekke aka Elenhinan
; 01/09-2005 ->
;
; This program is meant for controlling tow stepper-motors used
; in conjunction with TurboCNC
;
;**********************************************************************
; notes
;**********************************************************************
;
; program is made 100 cycles long, and uses all 18 io-ports.
; reset must be disabled and cal-byte written to eeprom adr 0x00
;
;
;**********************************************************************

; port b = stepper motors

; pb0 = motor 1, coil A
; pb1 = motor 1, coil B
; pb2 = motor 1, coil C
; pb3 = motor 1, coil D
; pb4 = motor 2, coil A
; pb5 = motor 2, coil B
; pb6 = motor 2, coil C
; pb7 = motor 2, coil D
;
; port d = input
;
; pd0 = motor1 step
; pd1 = motor1 direction
; pd2 = motor2 step
; pd3 = motor2 direction
; pd4 = n/a
; pd5 = n/a
; pd6 = n/a
; pd7 = n/a

;**********************************************************************

.include "tn2313def.inc"

;**********************************************************************
; register usage
;**********************************************************************

; low registers, 0-15
.def last_input = r0

.def motor1_step = r1
.def motor2_step = r2
.def motor3_step = r3

; high registers, 16-31

.def tmp = r16
.def input = r17

.def motor1_out = r18
.def motor2_out = r19
.def motor3_out = r20

;**********************************************************************
; ports
;**********************************************************************

; bit in register "input"
.equ axis1_step = 0
.equ axis1_dir = 1
.equ axis2_step = 2
.equ axis2_dir = 3
.equ axis3_step = 4
.equ axis3_dir = 5

.equ porta_out = 0b11111000; input: pin 123
.equ portb_out = 0b11111111; ouput: 0123 4567
.equ portd_out = 0b10001111; input: pin 456, output: 0123

.equ coil_1_A = 0
.equ coil_1_B = 1
.equ coil_1_C = 2
.equ coil_1_D = 3
.equ coil_2_A = 4
.equ coil_2_B = 5
.equ coil_2_C = 6
.equ coil_2_D = 7
.equ coil_3_A = 0
.equ coil_3_B = 1
.equ coil_3_C = 2
.equ coil_3_D = 3

;**********************************************************************
; step patterns
;**********************************************************************

.equ step0  = 0b00000001
.equ step1  = 0b00000011
.equ step2  = 0b00000010
.equ step3  = 0b00000110
.equ step4  = 0b00000100
.equ step5  = 0b00001100
.equ step6  = 0b00001000
.equ step7  = 0b00001001

;**********************************************************************
; eeprom memory
;**********************************************************************

.eseg
.org 0x00
eeprom_cal:
.db  0x00

;**********************************************************************
; program segment
;**********************************************************************

.cseg
.org  0x0000
rjmp start ; start/reset
reti  ; int0
reti  ; int1
reti  ; timer1 capture
reti  ; timer1 compare a
reti  ; timer1 overflow
reti  ; timer0 overflow
reti  ; usart
reti  ; usart
reti  ; usart
reti  ; analog comparator
reti  ; pin change interrupt
reti  ; timer1 compare b
reti  ; timer0 compare a
reti  ; timer0 compare b
reti  ; usi
reti  ; usi
reti  ; eeprom ready
reti  ; watchdog overflow

;**********************************************************************
; init
;**********************************************************************
start:
; set calibration
; ldi tmp, eeprom_cal
; out eear, tmp  ; read value
; sbi eecr, eere
; in tmp, eedr  ; read done
; out osccal, tmp  ; write to register

; setup stack
ldi tmp,low(RAMEND); Set initial stack ptr location at ram end
out SPL, tmp

; setup ports
ldi tmp, 0b10000000
out mcucr, tmp ; disable pullup

ldi tmp, porta_out
out ddra, tmp

ldi tmp, portd_out
out ddrd, tmp

ldi tmp, portb_out
out ddrb, tmp

clr tmp
out portb, tmp

ldi motor1_out,step0; set inital step for motors
ldi motor2_out,step0
swap motor2_out
ldi motor3_out,step0


;**********************************************************************
; main
;**********************************************************************
main:
; get input from pinA(0,1,2) & pinD(4,5,6)
in input,pina; read input from port A
in tmp, pind; read input from port D
cbr tmp, 0b10001111; isolate pin 4 5 6
lsr tmp   ; shift to bit 3 4 5
add input, tmp ; add results from portA and portD to input
clr tmp

sbrs input,axis1_step
rjmp main2_1
sbrc last_input,axis1_step
rjmp main2_2

step_1:
sbrc input,axis1_dir; check direction
dec motor1_step
sbrs input,axis1_dir
inc motor1_step
mov tmp, motor1_step; copy step# to param tmp
rcall step_pattern
nop  ; make as many cycles as step_2 with swap
mov motor1_out,tmp
rjmp main2_3

main2_1:
nop; compensate for jump if step isn't high, 2 cycles
nop
main2_2:
nop; compensate for step-change not run, 23 cycles
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop

main2_3:
sbrs input,axis2_step
rjmp main3_1
sbrc last_input,axis2_step
rjmp main3_2

step_2:
sbrc input,axis2_dir; check direction
dec motor2_step
sbrs input,axis2_dir
inc motor2_step
mov tmp, motor2_step; copy step# to param tmp
rcall step_pattern
swap tmp
mov motor2_out,tmp
rjmp main3_3

main3_1:
nop; compensate for jump if step isn't high, 2 cycles
nop
main3_2:
nop; compensate for step-change not run, 23 cycles
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop

main3_3:
sbrs input,axis3_step
rjmp main4_1
sbrc last_input,axis3_step
rjmp main4_2

step_3:
sbrc input,axis3_dir; check direction
dec motor3_step
sbrs input,axis3_dir
inc motor3_step
mov tmp, motor3_step; copy step# to param tmp
rcall step_pattern
nop  ; make as many cycles as step_2 with swap
mov motor3_out,tmp
rjmp main4_3

main4_1:
nop; compensate for jump if step isn't high, 2 cycles
nop
main4_2:
nop; compensate for step-change not run, 23 cycles
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop

main4_3:
mov tmp,motor1_out
add tmp,motor2_out
out portb,tmp  ; update output to motor 1 & 2
out portd,motor3_out; update output to motor 3

mov last_input,input; move last input for checking next run
nop
nop; make entire program 100 cycles long, no matter the input
nop
rjmp main

;**********************************************************************
; step_pattern
;
; input: tmp (previous step
;**********************************************************************
step_pattern:
cbr tmp, 0b11111000 ; use only 0-7
lsl tmp    ; multiply with 2
ldi ZL,low(step_jump)
ldi ZH,high(step_jump)
add ZL,tmp   ; jump to adr (step_jump + step# * 2)
ijmp

step_jump:
ldi tmp,step0
ret
ldi tmp,step1
ret
ldi tmp,step2
ret
ldi tmp,step3
ret
ldi tmp,step4
ret
ldi tmp,step5
ret
ldi tmp,step6
ret
ldi tmp,step7
ret



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