PDA

View Full Version : Interrupt based timer outputting wrong frequency



Dick Ivers
- 26th September 2011, 17:52
This object of the test program below is to toggle a LED at a 5 hz frequency. When the actual 12F1822 test circuit is run, the LED toggles at a 50 hz rate, confirmed by oscilloscope.

What seems to be happening is that the increment-to-count 10 part of the handler is not executing. The toggle frequency is determined only by the pre-scale and post- scale settings. Any ideas?



***************************************
*Program to test timer 2 interrupt
*Target processor is PIC 12f1822
*88 program words, revised 09/26/2011
***************************************
'set 12f1822 configurat1on
#CONFIG
__config _CONFIG1, _FOSC_INTOSC & _MCLRE_OFF & _CLKOUTEN_OFF
__config _CONFIG2, _PLLEN_OFF & _LVP_OFF
#ENDCONFIG

'set registers
OSCCON = 01101000 '4 mhz osc
OSCTUNE = 0 'factory calibration
ANSELA = 0 'all digital
OPTION_REG.7 = 0 'global pullups enabled
WPUA = 000100 'porta pin2 weak pullup enabled
CM1CON0.7 = 0 'comparator disabled
TRISA = 001111 'porta.5 and porta.4 are outputs, all others input

INTCON = 11000000 'global and peripheral interrupts enabled
PIE1 = 00000010 'enable tmr2 interrupt
T2CON = 00011110 'turn on tmr 2 (bit 2),1:16 prescale,1:4 postscale
PIR1.1 = 0 'clear tmr2 interrupt flag
PR2 = 156 'preset for 100 hz interrupt

define INTHAND clock

goto overint

asm
clock
INCF _ticks,f ;ticks=ticks + 1
MOVF _ticks,w ;read ticks into w
SUBLW d'10' ;subtract w from decimal 10
BTFSS STATUS,2 ;zero?
RETFIE ;return for next interrupt if not zero
CLRF _ticks ;clear ticks count

MOVLW b'00010000 ;load binary literal into w
XORWF PORTA,f ;toggle porta pin4
BSF _tenths ;set tenths-changed flag
BCF PIR1,1 ;reset tmr2 interrupt flag
RETFIE ;return to main
endasm

overint:

'declare variables
ticks var byte bank0
tenths var bit bank0

'initialize register functions
porta.4 = 1 'initialize led off
tenths = 0 'clear tenths-changed bit

main:
tenths = 0 'clear tenths-changed bit
pause 1000 'wait 1 second
goto main 'loop back to main

Darrel Taylor
- 26th September 2011, 18:55
In the first part of the ISR, it doesn't clear the interrupt flag if the value isn't 10.
So it exits and re-enters the ISR 10 times really fast.

Once it gets to 10, it toggles the pin and finally clears the flag, which all happens from a single interrupt.

Dick Ivers
- 26th September 2011, 21:19
Darrel,
Thanks, it's working now ... getting 5 hz toggle. Added this line at the beginning of the ISR routine:

BCF PIR1,1 ;clear tmr2 interrupt flag