Code:
;******************************************************************************
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
CBLOCK 0x0000 ; all in ACCESS RAM
Count_pulse ; Loop delay in 5 uS pulse to motor driver
X_delay : 2 ; Inter-pulse delay for X axis, 2 bytes
Y_delay : 2 ; Inter-pulse delay for Y axis, 2 bytes
X_steps : 2 ; Number of steps to do on X axis, 2 bytes
ENDC
;******************************************************************************
; Reset vector in program memory
ORG 0x0000
goto Main_ASM ; Go to start of main code
;******************************************************************************
; All interrupts vector to here, Priorities disabled
ORG 0x0008
bra Tmr_ints ; Go to interrupt routine
;******************************************************************************
;******************************************************************************
; Higher priority for Timer0 overflows, send out stepper
; drive pulse for X axis on PORTD.0
Tmr_ints
btfss INTCON,TMR0IF ; did Timer0 interrupt?
bra LowPri ; no. branch to Timer1 int
bsf PORTD,0 ; yes. High PORTD.0
call Pulse_out ; Send 5uS pulse on PORTB.0
bcf PORTD,0 ; Low PORTD.0 (Timer1 interrupts around here)
bcf INTCON,TMR0IF ; Clear Timer0 interrupt flag
movff X_delay+1,TMR0H ; Load timer0 with X_delay high byte
movff X_delay,TMR0L ; Load timer0 with X_delay low byte
movf X_steps,W ; load WREG for compare after subtraction
decf X_steps,F ; Decrement X_steps low byte
cpfslt X_steps ; if X_steps < WREG then jump over next decrement
decf X_steps+1 ; else, decrement high byte
; Lower priority for Timer1 overflows, send out stepper
; drive pulse for Y axis on PORTD.3
LowPri
btfss PIR1,TMR1IF ; Timer1 int pending?
bra IntExit ; no. exit
bsf PORTD,3 ; High PORTD.3
call Pulse_out ; Delay for 10 microseconds
bcf PORTD,3 ; High PORTD.3
bcf PIR1,TMR1IF ; Clear Timer1 interrupt flag
movff Y_delay+1,TMR1H ; Load Timer1 with Y_delay high byte
movff Y_delay,TMR1L ; Load timer1 with Y_delay low byte
IntExit
retfie FAST ; return & restore WREG, STATUS, BSR
;****************************************************************************** *
; 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
bcf RCON,7 ; disable priority levels on interrupts,IPEN=0
bsf INTCON,7 ; Enable all interrupts
bsf INTCON,6 ; Enable all peripheral interrupts
bcf INTCON,3 ; Disable PORTB interrupts
bcf INTCON2,2 ; Make Timer0 overflow low priority
bcf IPR1,0 ; Make Timer1 overflow low priority
bsf INTCON,5 ; Enable Timer0 overflow int
bsf PIE1,0 ; Enable Timer1 overflow int
; 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 TMR0H ; Zero the clock
clrf TMR0L ; 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 TMR1H ; Zero the clock
clrf TMR1L ; Zero the clock
bsf T1CON,0 ; Timer1 on
; Temp code to simmulate PBP input for the delays
clrf X_delay ; this handles the low byte
clrf X_delay+1 ; this handles the high byte
clrf Y_delay
clrf Y_delay+1
clrf X_steps
clrf X_steps+1
; 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+1,PORTC ; high byte to portc
;btg PORTC,1 ; toggle RC1 (note: comf only works with whole 8-bit registers)
movff X_steps,PORTD ; low byte to portd
;btg PORTD,1 ; toggle RD1
tstfsz X_steps ; Test, skip next if zero
goto Main_loop ; More steps to do, so loop
tstfsz X_steps+1 ; Test, skip next if zero
bra Re_load_lb
goto All_done
Re_load_lb
decf X_steps+1,F ; Decrement hb and then carry to lb
setf X_steps ; Decremented hb, so load ff to lb
goto Main_loop
All_done
bcf INTCON,7 ; Clear GIE, disable ALL interrupts
clrwdt
sleep
goto $-2
end
I think you're much better off putting both interrupts in the same handler, and just checking for which one caused the interrupt VS having a high pri interrupt your low pri, so you can use the auto restore for W, STATUS & BSR.
Bookmarks