; Nicole Arruda and Raj Nahamari ; April 2, 2014 ; Microprocessors ; Grad presentation: timers and interrupts ; filename: using_timer_interrupts.asm ; This program demonstrates two of the PIC 16F628's timers and ; the use of timer interrupts to trigger events. Each timer ; controls the pulse modulation on one wheel of the Boebot. ; TMR0 controls the right wheel and alternates between a 20ms ; delay and a 1ms delay. TMR2 controls the left wheel and ; alternates between a 20ms delay and a 2ms delay. ; Since the wheels are controlled through an interrupt subroutine, ; the program body is free for other functionality. LIST p=16F628 ;tell assembler what chip we are using include "P16F628.inc" ;include the defaults for the chip __config 0x3D18 ;sets the configuration settings cblock 0x20 ;start of general purpose registers ; counter to toggle between 20ms and 1ms controlR ; counter to toggle between 20ms and 2ms controlL endc ; as usual, an interrupt sets the PC to 0x04 org 0x00 goto main org 0x04 goto isr main ; turn comparators off (make it like a 16F84) movlw 0x07 movwf CMCON banksel OPTION_REG ; in OPTION_REG: ; bit 5 - enable TMR0 ; bit 3 - assign prescaler to TMR0 ; bits 2:0 - set prescaler to 1:128 movlw b'10000110' movwf OPTION_REG banksel T2CON ; in T2CON: ; bits 6:3 - set postscaler to 1:8 ; bit 2 - turn TMR2 on ; bits 1:0 - set prescaler to 1:16 movlw b'01110111' movwf T2CON ; enable TMR2 interrupt banksel PIE1 bsf PIE1,TMR2IE ; bit 7 - enable global interrupt (GIE) ; bit 6 - enable peripheral interrupt ; bit 5 - enable TMR0 interrupt movlw b'11100000' movwf INTCON bsf STATUS,RP0 ;bank 1 movlw b'00000000' movwf TRISB ; portb is output movlw b'11111000' movwf TRISA ;porta is input bcf STATUS,RP0 ;return to bank 0 ; PROGRAM BODY ; Movement of the wheels is controlled entirely through ; interrupts, leaving our program body free to deal with ; the speaker implementation. ; ; RA1 has right wheel | RA2 has left wheel | RB3 has speaker clrf controlR clrf controlL ; set RA1 low and start TMR0 at 100 ; (256 - 100) * 128 ~ 20,000µs, or 20ms bcf PORTA,1 movlw d'100' movwf TMR0 ; TMR2 resets when it matches value in PR2 ; set PR2 to 156 ; 156 * 128 ~ 20,000µs, or 20ms banksel PR2 movlw d'156' movwf PR2 bcf STATUS,RP0 ; return to bank 0 ; set RA2 low bcf PORTA,2 loop ; This is the main loop of the program. Anything ; can go in here without disrupting or being ; disrupted by the motion of the wheels. goto loop ; isr ; SUBROUTINE ; Checks INTCON,2 (TMR0 flag) and PIR1,1 (TMR2 flag) ; to determine which threw the interrupt and calls ; appropriate subroutine. isr ; check TMR0 interrupt flag btfsc INTCON,2 call Right_wheel ; check TMR2 interrupt flag btfsc PIR1,1 call Left_wheel retfie ; Right_wheel ; SUBROUTINE ; Toggles RA1 between low for 20ms and high for 1ms. ; Bit 0 of controlR is used as a flag. Right_wheel bcf INTCON,2 btfss controlR,0 bsf PORTA,1 btfsc controlR,0 bcf PORTA,1 ; modify value in TMR0 btfss controlR,0 movlw d'248' btfsc controlR,0 movlw d'100' movwf TMR0 ; increment controlR (toggle "flag") incf controlR return ; Left_wheel ; SUBROUTINE ; Toggles RA2 between low for 20ms and high for 2ms. ; Bit 0 of controlL is used as a flag. Left_wheel bcf PIR1,1 btfss controlL,0 bsf PORTA,2 btfsc controlL,0 bcf PORTA,2 ; modify value in PR2 btfss controlL,0 movlw d'16' btfsc controlL,0 movlw d'156' banksel PR2 movwf PR2 bcf STATUS,RP0 ; increment controlL (toggle "flag") incf controlL return end