Il moduo timer0 viene incrementato ad ogni ciclo istruzione, se è usato senza prescaler.
Il timere viene selezionato azzerando il bit TMR0CS del registro OPTION_REG.
Nota: Quando viene scritto il registro TMR0 l'incremento viene inibito per due cicli istruzioni succesivi.
SOFTWARE PROGRAMMABLE PRESCALER
E' possibile impostare via software un prescaler per il Timer0. Il prescale è abilitato azzerando il bit PSA del registro OPTION_REG. Le 8 opzioni del prescaler sono da 1:2 fino a 1:256. I valori del prescaler sono selezionabili tramite i bit PS<2:0> di OPTION_REG. Ogni istruzione che scrive il registro TMR0 azzera il prescaler.
TIMER0 INTERRUPT
Il timer0 genera un'interrupt quando il registro TMR0 ha un'overflows dal valore FFh a 00h. Il bit interrupt flag TMR0IF del registro INTCON viene settato ogni volta che il registro TMR0 ha un'overflows, indipendentemente che l'interrupt Timer0 sia abilitato. Il bit TMR0IF può essere azzerato solo via software. L'interrupt Timer0 è abilitato settando il bit TMR0IE di INTCON.
SCRITTURA DEL FIRMWARE
Vediamo come va configurato il modulo timer0 per fare un firmware che faccia lampeggiare un led ad ogni secondo esatto.
Il calcolo del tempo impiegato a far scattare l'interrupt è il seguente:
(0x100-TMR0_RESET_VAL)*durata_ciclo_istruzioni*PRESCALER_VALUE+2*durata_ciclo_istruzioni
;*****************************************************************************************
; CONSTANT DEFINITIONS
;*****************************************************************************************
; /----------- WPUEN: PWeak Pull-up Enable bit = X
; |/---------- INTEDG: Interrupt Edge Select bit = X
; ||/--------- T0CS: TMR0 Clock Source Select bit = 0 = Internal
; ||| instruction cycle clock (FOSC/4)
; |||/-------- T0SE: TMR0 Source Edge Select bit = X
; ||||/------- PSA: Prescaler Assignment bit = 0 = Prescaler is
; ||||| assigned to the Timer0 module
; |||||///---- PS2:PS0: Prescaler Rate Select bits =
; |||||||| 010 = TMR0 Rate 1 : 8
; ||||||||
OPTION_REG_CFG EQU B'11010010'
T0_RESET_VAL EQU 0x83 ; interrupt ogni 1ms per clock a 4MHz e prescaler = 8
; ([0x100-0x83]*1us*8=1ms) (Formula imprecisa!!!!)
T0_POSTSCALER_L_VAL EQU 0xE8 ; postscaler = 1000
T0_POSTSCALER_H_VAL EQU 0x03
;*****************************************************************************************
; VARIABLE DEFINITIONS
;*****************************************************************************************
T0_timeout EQU 0x2A
T0_postscaler_l EQU 0x2B
T0_postscaler_h EQU 0x2C
T0_reset EQU 0x2D
orologio_sec EQU 0x2E
orologio_min EQU 0x2F
orologio_ore EQU 0x30
;**********************************************************************
; VERSIONE: 1.0.3
; ULTIMA MODIFICA: 14.02.12
; INPUT: NONE
; OUTPUT: NONE
; Inizializzazione delle variabili T0_reset,
; T0_postscaler_h e T0_postscaler_l
;**********************************************************************
T0_init
;T0_Reset = T0_RESET_VAL;
;T0_PostScaler = 1000;
return
;**********************************************************************
; VERSIONE: 1.0.3
; ULTIMA MODIFICA: 14.02.12
; INPUT: NONE
; OUTPUT: NONE
; inizializzazione del registro OPTION_REG, azzeramento della flag
; T0_timeout, ripristino del valore di TMR0 e abilitazione
; dell'interrupt del timer0
;**********************************************************************
T0_setup
;OPTION_REG = OPTION_REG_CFG //Prescaler Rate 1:8
;T0_timeout = false;
;TMR0 = T0_reset;
;enable_interrupts(INT_TIMER0);
;INTCON.TMR0IF = 0;
return
; VERSIONE: 1.0.3
; ULTIMA MODIFICA: 14.02.12
; INPUT: NONE
; OUTPUT: NONE
; inizializzazione del registro OPTION_REG, azzeramento della flag
; T0_timeout, ripristino del valore di TMR0 e abilitazione
; dell'interrupt del timer0
;**********************************************************************
T0_setup
;OPTION_REG = OPTION_REG_CFG //Prescaler Rate 1:8
;T0_timeout = false;
;TMR0 = T0_reset;
;enable_interrupts(INT_TIMER0);
;INTCON.TMR0IF = 0;
return
;**********************************************************************
; VERSIONE: 1.0.3
; ULTIMA MODIFICA: 14.02.12
; INPUT: NONE
; OUTPUT: NONE
;**********************************************************************
T0_disable
;disable_interrupts(INT_TIMER0);
return
;**********************************************************************
; VERSIONE: 1.0.3
; ULTIMA MODIFICA: 14.02.12
; INPUT: NONE
; OUTPUT: NONE
;**********************************************************************
T0_isr
;TMR0 = T0_reset;
;--T0_postscaler;
;if(!T0_postscaler) {T0_timeout=true;}
; The interrupt flag bits must be cleared before exiting
; the ISR to avoid repeated interrupts.
return
;**********************************************************************
; VERSIONE: 1.0.3
; ULTIMA MODIFICA: 14.02.12
; INPUT: NONE
; OUTPUT: NONE
; inizializzazioni variabili routine orologio, T0_init
; abilitazione interrupt
;**********************************************************************
orologio_init
;orologio_sec=0;
;orologio_min=0;
;orologio_ore=0;
;T0_init();
return
;**********************************************************************
; VERSIONE: 1.0.3
; ULTIMA MODIFICA: 14.02.12
; INPUT: NONE
; OUTPUT: NONE
; visualizzazione dei secondi sui led
;**********************************************************************
orologio
;if(!T0_timeout) return
;T0_timeout=false;
;T0_PostScaler=1000;
;orologio_sec++;
;if(orologio_sec==60) orologio_sec=0; orologio_min++
;if(orologio_sec>60) orologio_sec=0;
;output su led
;*****************************************************************************************
; VERSIONE: 1.0.0
; ULTIMA MODIFICA: 09.12.09
; INPUT: NONE
; OUTPUT: NONE
;*****************************************************************************************
isr
; GIE bit is cleared
; Critical registers are automatically saved to the
; shadow registers (W register, STATUS register (except for TO and PD),
; BSR register, FSR registers, PCLATH)
; Determine the source of the interrupt by polling the interrupt flag bits. ; if(TMR0IF==1) T0_isr
banksel INTCON
btfsc INTCON, TMR0IF
call T0_isr
; if(TMR1IF==1) T1_isr
banksel INTCON
btfsc INTCON, TMR1IF
call T1_isr
; Critical registers are automatically restored
; GIE bit is setted
retfie
; VERSIONE: 1.0.3
; ULTIMA MODIFICA: 14.02.12
; INPUT: NONE
; OUTPUT: NONE
;**********************************************************************
T0_isr
;TMR0 = T0_reset;
;--T0_postscaler;
;if(!T0_postscaler) {T0_timeout=true;}
; The interrupt flag bits must be cleared before exiting
; the ISR to avoid repeated interrupts.
return
;**********************************************************************
; VERSIONE: 1.0.3
; ULTIMA MODIFICA: 14.02.12
; INPUT: NONE
; OUTPUT: NONE
; inizializzazioni variabili routine orologio, T0_init
; abilitazione interrupt
;**********************************************************************
orologio_init
;orologio_sec=0;
;orologio_min=0;
;orologio_ore=0;
;T0_init();
return
;**********************************************************************
; VERSIONE: 1.0.3
; ULTIMA MODIFICA: 14.02.12
; INPUT: NONE
; OUTPUT: NONE
; visualizzazione dei secondi sui led
;**********************************************************************
orologio
;if(!T0_timeout) return
;T0_timeout=false;
;T0_PostScaler=1000;
;orologio_sec++;
;if(orologio_sec==60) orologio_sec=0; orologio_min++
;if(orologio_sec>60) orologio_sec=0;
;output su led
;*****************************************************************************************
; VERSIONE: 1.0.0
; ULTIMA MODIFICA: 09.12.09
; INPUT: NONE
; OUTPUT: NONE
;*****************************************************************************************
isr
; GIE bit is cleared
; Critical registers are automatically saved to the
; shadow registers (W register, STATUS register (except for TO and PD),
; BSR register, FSR registers, PCLATH)
; Determine the source of the interrupt by polling the interrupt flag bits. ; if(TMR0IF==1) T0_isr
banksel INTCON
btfsc INTCON, TMR0IF
call T0_isr
; if(TMR1IF==1) T1_isr
banksel INTCON
btfsc INTCON, TMR1IF
call T1_isr
; Critical registers are automatically restored
; GIE bit is setted
retfie
Nessun commento:
Posta un commento