Code:
;******************************************************************************
; *
; Filename: WL_Scanner_01 *
; Date: February 2010 *
; *
;******************************************************************************
;******************************************************************************
; *
; Function: Drive two stepper motors with timers/interrupts *
; Files Required: P18F8722.INC *
; *
;******************************************************************************
LIST P=18F8722 ; Directive to define processor
#include <P18F8722.INC> ; Drocessor specific variable definitions
;******************************************************************************
; Configuration bits
CONFIG OSC = HSPLL ; Run at 4X speed
CONFIG CP0=OFF ; Disable code protect
CONFIG PWRT = OFF ; Power up timer off so DEBUG works
CONFIG WDT=OFF ; WDT off
CONFIG LVP = OFF ; LVP off
CONFIG WAIT = OFF ; External bus data wait disabled
;******************************************************************************
; Variable definitions in data memory
WREG_TEMP equ 0x010 ; Variable used for context saving
STATUS_TEMP equ 0x011 ; Variable used for context saving
BSR_TEMP equ 0x012 ; Variable used for context saving
Count_pulse equ 0x013 ; Loop delay in 5 uS pulse to motor driver
X_delay_lb equ 0x014 ; Inter-pulse delay for X axis, high byte
X_delay_hb equ 0x015 ; Inter-pulse delay for X axis, low byte
Y_delay_lb equ 0x016 ; Inter-pulse delay for Y axis, high byte
Y_delay_hb equ 0x017 ; Inter-pulse delay for Y axis, low byte
X_steps_lb equ 0x018 ; Number of steps to do on X axis
X_steps_hb equ 0x019 ; Y steps not needed as Tx.Dx=Ty.Dy
;******************************************************************************
; Reset vector in program memory
ORG 0x0000
goto Main_ASM ; Go to start of main code
;******************************************************************************
; High priority interrupt vector in program memory
ORG 0x0008
goto High_int ; Go to high priority interrupt routine
;******************************************************************************
; Low priority interrupt vector and routine in program memory, when Timer1
; overflows send out stepper drive pulse for Y axis on PORTD.3
ORG 0x0018
movff STATUS,STATUS_TEMP ; save STATUS register
movff WREG,WREG_TEMP ; save working register
movff BSR,BSR_TEMP ; save BSR register
bcf INTCON,7 ; Disable all interrupts
bsf PORTD,3 ; High PORTD.3
call Pulse_out ; Delay for 10 microseconds
bcf PORTD,3 ; High PORTD.3
bcf PIR1,0 ; Clear Timer1 interrupt flag
movff Y_delay_hb,TMR1H ; Load Timer1 with Y_delay
movff Y_delay_lb,TMR1L ; Load timer1 with Y_delay
movff BSR_TEMP,BSR ; restore BSR register
movff WREG_TEMP,WREG ; restore working register
movff STATUS_TEMP,STATUS ; restore STATUS register
bsf INTCON,7 ; Enable interrupts
retfie
;******************************************************************************
; High priority interrupt routine, when Timer0 overflows, send out stepper
; drive pulse for X axis on PORTD.0
High_int:
bcf INTCON,7 ; Disable interrupte
bsf PORTD,0 ; High PORTD.0
call Pulse_out ; Send 5uS pulse on PORTB.0
bcf PORTD,0 ; Low PORTD.0
bcf INTCON,2 ; Clear Timer0 interrupt flag
movff X_delay_hb,TMR0H ; Load timer0 with X_delay
movff X_delay_lb,TMR0L ; Load timer0 with X_delay
decf X_steps_lb ; Decrement X_steps
bsf INTCON,7 ; Enable interrupts
retfie 1
;******************************************************************************
; *
; SUBROUTINES *
; *
;******************************************************************************
Pulse_out: ; Delay = 3.n + 7 [0.1 microseconds]
movlw 0xff ; Load w with n
movwf Count_pulse ; Load Count with n
Pulse_loop:
decfsz Count_pulse ; Decrament the file Count
goto Pulse_loop ; Loop if not zero
return
;******************************************************************************
; *
; MAIN ASM *
; *
;******************************************************************************
Main_ASM:
clrf TRISA ; PORTA is output
clrf TRISB ; PORTB is output
clrf TRISC ; PORTC is output
clrf TRISD ; PORTD is output
clrf TRISE ; PORTE is output
clrf TRISF ; PORTF is output
clrf TRISG ; PORTG is output
clrf TRISH ; PORTH is output
clrf TRISJ ; PORTJ is output
clrf PORTA ; Clear PORTA
clrf PORTB ; Clear PORTB
clrf PORTC ; Clear PORTC
clrf PORTD ; Clear PORTD
clrf PORTE ; Clear PORTE
clrf PORTF ; Clear PORTF
clrf PORTG ; Clear PORTG
clrf PORTH ; Clear PORTH
clrf PORTJ ; Clear PORTJ
movlw 0x0f
movwf ADCON1 ; PORTA is digital I/O
movlw 0x07
movwf CMCON ; Comparator off
; Set up interrupt conditions for Timer0 and Timer1
bsf RCON,7 ; Enable priority levels on interrupts,IPEN=1
bsf INTCON,7 ; Enable all high priority interrupts
bsf INTCON,6 ; Enable all low priority interrupts
bcf INTCON,3 ; Disable PORTB interrupts
bsf INTCON2,2 ; Make Timer0 overflow high priority
bcf IPR1,0 ; Make Timer1 overflow low priority
bsf INTCON,5 ; Enable Timer0 overflow flag
bsf PIE1,0 ; Enable Timer1 overflow flag
; Set up Timer0 conditions
bcf T0CON,6 ; Timer0 uses 16 bits
bcf T0CON,5 ; Timer0 uses internal osc
bcf T0CON,4 ; Timer0 count on rising edge og osc
bsf T0CON,3 ; Timer0 pre-scaler not assigned
clrf TMR0L ; Zero the clock
clrf TMR0H ; Zero the clock
bsf T0CON,7 ; Timer0 on
; Set up Timer1 conditions
bsf T1CON,7 ; Timer1 uses 16 bits
bcf T1CON,1 ; Timer1 uses internal osc
clrf TMR1L ; Zero the clock
clrf TMR1H ; Zero the clock
bsf T1CON,0 ; Timer1 on
; Temp code to simmulate PBP input for the delays
movlw 0x00
movwf X_delay_lb
movlw 0x00
movwf X_delay_hb
movlw 0x00
movwf Y_delay_lb
movlw 0x00
movwf Y_delay_hb
movlw 0xff
movwf X_steps_lb
movlw 0xff
movwf X_steps_hb
; End of Temp code
; Check if X_steps_lb=0 (decremented in high priority interrupt)
; If so, check X_steps_hb and if zero, end
; If not, decrement X_steps_hb, set X_steps_lb and go again
Main_loop:
movff X_steps_hb,PORTC
;comf PORTC,1 ; LEDS active low so invert
movff X_steps_lb,PORTD
;comf PORTD,1
tstfsz X_steps_lb ; Test, skip next if zero
goto Main_loop ; More steps to do, so loop
tstfsz X_steps_hb ; Test, skip next if zero
goto Re_load_lb
goto All_done
Re_load_lb:
decf X_steps_hb,1 ; Decrement hb and then carry to lb
setf X_steps_lb ; Decremented hb, so load ff to lb
goto Main_loop
All_done:
bcf RCON,7 ; Clear IPEN=0, disable priority interrupts
end ; IPEN must be cleared or asm keeps running
Regards Bill Legge
Bookmarks