I have designed an assembler program for PIC 12F675, but it gives wrong timing. Datasheet says that internal oscillator is 4 MHz, and its instruction cycle is 4 clocks. Thus single instruction executes 1 us. Thus for timer 0, looping from 0
to FF
with prescaler 1:256 I expect to get 131 ms per period (2 times with output value inverted), and for timer 1 and loaded counter value of B8FB
I expect time of 18.18 ms.
I get:
TMR0 -> 108 ms (instead of 131 ms)
TMR1 -> 30 ms (instead of 18 ms).
What do I do wrong?
Code is below. It does simple things: for TMR0 it just checks for overflow bit and toggles LED state, for TMR1 it checks for overflow, and if it did, it toggles LED and resets counter back to B8FB
.
CONF1 equ _INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF
CONF2 equ _MCLRE_OFF & _BODEN_OFF & _CP_OFF & _CPD_OFF
__CONFIG CONF1 & CONF2
START
; in bank 0
bcf STATUS,RP0 ; bank 0
movlw 02h
movwf GPIO ; init GPIO
movlw 07h ; comparator off: set GP<2:0> to
movwf CMCON ; digital IO
clrwdt ; clear watchdog
clrf TMR0 ; clear timer 0 value (mut be performed before
; writing option register
; in bank 1
bsf STATUS,RP0 ; bank 1
clrf PIE1 ; disable peripheral interrupts
movlw 07h ; pull-ups enabled,
; GP2/INT pin interrupt on falling edge,
; TMR0 is clocked by internal oscillator,
; prescaler for TMR0 is 1:256
movwf OPTION_REG
clrf ANSEL ; all pins are digital I/O
movlw 02ch ; (1=input, 0=output)
movwf TRISIO ; and set GP0/GP1/GP4 as outputs,
; GP2/GP3/GP5 as input
; movlw 034h ; (1=enabled, 0=disabled)
movwf WPU ; set weak pull-ups on all input pins
; initialize TMR1FLG value
bcf STATUS,RP0 ; change back to bank 0
movlw 01h
movwf TMR1FLG ; starting as NTSC mode until first interrupt
; finished configuring, now enabling interrupts
; movlw 090h ; interrupts enabled from INT pin,
; ; TMR0 interrupts are disabled
; movwf INTCON ; set interrupts reg
; test code
; start the timer, 18181 = 04705h, and -04705h=0b8fbh (timer counts up)
clrf T1CON ; stop timer to prevent contention
movlw 0b8h
movwf TMR1H
movlw 0fbh
movwf TMR1L ; set up TMR1 counter to 0b8fbh
bcf PIR1,TMR1IF ; clear timer 1 interrupt flag
incf T1CON,F ; start timer with 4MHz/4 (T1CON is 01h now)
; clearing interrupt
bcf INTCON,INTF
test_loop
btfss INTCON,T0IF ; Timer 0 overflew?
goto no_tmr0 ; no, continue to main loop
bcf INTCON,T0IF ; reset timer 0 flag
movf W_TEMP,W
xorlw 02h
movwf W_TEMP
movwf GPIO ; alternate green LED
no_tmr0
btfss PIR1,TMR1IF
goto test_loop
; TMR1 overflew
clrf T1CON ; stop timer to prevent contention
movlw 0b8h
movwf TMR1H
movlw 0fbh
movwf TMR1L ; set up TMR1 counter to 0b8fbh
bcf PIR1,TMR1IF ; clear timer 1 interrupt flag
incf T1CON,F ; start timer with 4MHz/4 (T1CON is 01h now)
; clearing interrupt
bcf INTCON,INTF
movf W_TEMP,W
xorlw 010h
movwf W_TEMP
movwf GPIO ; alternate red LED
goto test_loop