; Lesson13a.asm - demonstration of using TMR0 register ; ; Blink LEDs at three different rates ; ; WB8RCR - 3-Mar-04 ; ;===================================================================== processor pic16f84a include "p16f84a.inc" __config _XT_OSC & _WDT_OFF & _PWRTE_ON list b=4,n=70 ;===================================================================== ; Manifest Constants ;===================================================================== LED1M equ B'0001000' ; Mask for LED1 LED2M equ B'0000100' ; Mask for LED2 LED3M equ B'0000010' ; Mask for LED3 HZ1TIME equ D'244' ; Clock ticks for 1/sec HZ2TIME equ D'122' ; Clock ticks for 2/sec HZ3TIME equ D'81' ; Clock ticks for 3/sec ;===================================================================== ; File register use ;===================================================================== cblock H'20' Hz1Cnt ; Once per second counter Hz2Cnt ; Twice per second counter Hz3Cnt ; Thrice per second counter Outputs ; Output storage endc goto start ;===================================================================== ; Subroutines ;===================================================================== SendOut movf Outputs,W ; Pick up the output word movwf PORTB ; And send it to the world return ;===================================================================== ; Time domains ;===================================================================== ;--------------------------------------------------------------------- ; Three times per second code ;--------------------------------------------------------------------- Hz3 movlw LED3M ; Toggle LED3 bit by xorwf Outputs,F ; XORing with current state call SendOut ; Set outputs return ;--------------------------------------------------------------------- ; Two times per second code ;--------------------------------------------------------------------- Hz2 movlw LED2M ; Toggle LED2 bit by xorwf Outputs,F ; XORing with current state call SendOut ; Set outputs return ;--------------------------------------------------------------------- ; Once per second code ;--------------------------------------------------------------------- Hz1 movlw LED1M ; Toggle LED1 bit by xorwf Outputs,F ; XORing with current state call SendOut ; Set outputs return ;===================================================================== ; Mailine begins here -- Initialization ;===================================================================== start ;--------------------------------------------------------------------- ; Set up timer ;--------------------------------------------------------------------- errorlevel -302 banksel INTCON bcf INTCON,T0IE ; Mask timer interrupt ; Normally, we would have simply loaded a constant, but ; the code below makes it explicit what we are doing banksel OPTION_REG bcf OPTION_REG,T0CS ; Enable timer bcf OPTION_REG,PSA ; Prescaler to timer bcf OPTION_REG,PS2 ; \ bsf OPTION_REG,PS1 ; >- 1:16 prescale bsf OPTION_REG,PS0 ; / ;--------------------------------------------------------------------- ; Set up I/O ;--------------------------------------------------------------------- banksel TRISB ; clrw ; Make all PORTB bits output movwf TRISB ; banksel PORTA ; Back to bank 0 errorlevel +302 ;--------------------------------------------------------------------- ; Initialize memory ;--------------------------------------------------------------------- movlw B'00001110' ; Initially set all LEDs movwf Outputs ; to off movlw HZ1TIME ; Initialize the counters movwf Hz1Cnt ; for the three time domains movlw HZ2TIME movwf Hz2Cnt movlw HZ3TIME movwf Hz3Cnt ;===================================================================== ; Main program loop here ;===================================================================== main btfss INTCON,T0IF ; Did timer overflow? goto main ; No, hang around some more bcf INTCON,T0IF ; reset overflow flag ;--------------------------------------------------------------------- ; Check for three times per second ;--------------------------------------------------------------------- decfsz Hz3Cnt,F ; Count down until Hz3 goto $+4 ; Not time yet movlw HZ3TIME ; Reset the counter so movwf Hz3Cnt ; it's available next time call Hz3 ; Go do thrice per second code ;--------------------------------------------------------------------- ; Check for two times per second ;--------------------------------------------------------------------- decfsz Hz2Cnt,F ; Count down until Hz2 goto $+4 ; Not time yet movlw HZ2TIME ; Reset the counter so movwf Hz2Cnt ; it's available next time call Hz2 ; Go do twice per second code ;--------------------------------------------------------------------- ; Check for once per second ;--------------------------------------------------------------------- decfsz Hz1Cnt,F ; Count down until Hz1 goto $+4 ; Not time yet movlw HZ1TIME ; Reset the counter so movwf Hz1Cnt ; it's available next time call Hz1 ; Go do once per second code goto main end