PDA

View Full Version : timing equation



glkosec
- 20th November 2008, 15:24
I have found this little bit of code from the forum and am trying to do something similar to this with the TMR0 module on a 12F675. I was just wondering how tey came up with the 16.384ms for the time between interrupts.

I would like to know the equation so i can make it work for my timer application. Any help would be much appreciated.


' Set TMR0 to interrupt every 16.384 milliseconds
OPTION_REG = $55 ' Set TMR0 configuration and enable PORTB pullups
INTCON = $a0 ' Enable TMR0 interrupts
On Interrupt Goto tickint

mister_e
- 20th November 2008, 18:23
When you use Timer, you have to take in account at least the OSC and the Timer Prescaler. The datasheet should explain it a little bit.

This link should also help
http://www.sxlist.com/techref/microchip/timer.htm

My PICMultiCalc should help you a little bit too.
http://www.picbasic.co.uk/forum/attachment.php?attachmentid=2957&d=1225550328

glkosec
- 21st November 2008, 14:29
i have written this test program to become more familiar with the timer0 module. The only problem is that according to my calulations from the calculator that was posted on this thread the timer should throw and interrupt every 1 ms and then every 1000 roll overs it should increment the seconds variable +1 so my counter counts in seconds. with the code below this should keep the led on for 5 seconds. but im only getting the led to stay on for 320ms. Why is the timing so far off from what i calculated?


'Definitions'
DEFINE OSC 3
DEFINE ADC_BITS 10 ' set number of bits in result
DEFINE ADC_CLOCK 3 ' set clock source
DEFINE ADC_SAMPLEUS 50 ' set sampling time for microseconds
'Definitions'

'Register Initializations'
ADCON0 = %10001011 ' set as right justified and turn on AD
ANSEL = %01001100 ' A to D on AN2 and AN3
CMCON = %00000111 ' set all pins to digital
TRISIO = %00011111 ' define Inputs and Outputs
GPIO = %00000000 ' set all pin states to off
WPU = %00000000 ' shut off weak pull ups
OPTION_REG = %01010001 ' set the tmr 0 to prescale of 1:4 for 1ms roll over
INTCON = %10100000 ' ENABLE THE TMR0 INTERRUPTS
'Register Initializations'


'Variables'
LED VAR GPIO.5
i var word
ROLLCOUNT VAR WORD
ROLLOVER_COUNTER VAR WORD
SECONDS VAR WORD
'Variables'

ON INTERRUPT GOTO ROLL_OVER
INITIALIZE:
for i = 0 to 50
pause 10
next i

LED = 1
ROLLOVER_COUNTER = 0
SECONDS = 0

MAIN:
IF SECONDS = 5 THEN LED_OFF

GOTO MAIN

LED_OFF:
LED = 0
ROLLOVER_COUNTER = 0
SECONDS = 0
GOTO INITIALIZE

DISABLE
ROLL_OVER:
ROLLOVER_COUNTER = ROLLOVER_COUNTER + 1 ' INCREMENT ROLL COUNT 1 EVERY 1 ms
IF ROLLOVER_COUNTER >= 1000 THEN 'created to count seconds instead of ms
SECONDS = SECONDS + 1
ROLLOVER_COUNTER = 0
ENDIF
INTCON.2 = 1
RESUME
ENABLE

Bruce
- 21st November 2008, 15:44
It would help to get rid of the pause 10. With your timer0 interrupt happening every 1mS
you can miss up to 10 interrupt counts. Using BASIC interrupts your pause command will
have to complete before it jumps to your interrupt handler.

What speed crystal are you using?

Edit: If you're using GPIO.5 as the LED output, then I suspect you're uisng the internal osc.
DEFINE OSC 3 is going to throw timing off since the internal osc freq is 4MHz.

DEFINE OSC 4
DEFINE OSCCAL_1K 1

Would help get your timing a lot closer.

Acetronics2
- 21st November 2008, 16:19
Hi,



INTCON

bit 2 T0IF: TMR0 Overflow Interrupt Flag bit(2)
1 = TMR0 register has overflowed (must be cleared in software)
0 = TMR0 register did not overflow



Everything works as written ... program loops in interrupt ( I make it short ... lol ) after a first "regular" TMR0 interrupt !!!

may be should CLEAR the TMR0 Flag ... instead of setting it ... ???

Just an idea
Alain

Bruce
- 21st November 2008, 16:22
Yep that would help too....;o}

Bruce
- 21st November 2008, 16:46
Untested, but try something like this;


DEFINE OSC 4
DEFINE OSCCAL_1K 1 ' load factory osccal value

'Register Initializations'
ANSEL = 0 ' all digital
CMCON = %00000111 ' set all pins to digital
TRISIO = %00011111 ' define Inputs and Outputs
GPIO = %00000000 ' set all pin states to off
WPU = %00000000 ' shut off weak pull ups
OPTION_REG = %01010001 ' set the tmr 0 to prescale of 1:4 for 1ms roll over
INTCON = %10100000 ' ENABLE THE TMR0 INTERRUPTS

'Variables'
LED VAR GPIO.5
ROLLOVER_COUNTER VAR WORD
SECONDS VAR BYTE

LED = 0 ' LED off on boot

ON INTERRUPT GOTO ROLL_OVER

MAIN:
IF SECONDS = 5 THEN
ROLLOVER_COUNTER = 0
SECONDS = 0
TOGGLE LED
ENDIF
GOTO MAIN

DISABLE
ROLL_OVER:
ROLLOVER_COUNTER = ROLLOVER_COUNTER + 1 ' INCREMENT ROLL COUNT 1 EVERY 1 ms
IF ROLLOVER_COUNTER >= 1000 THEN 'created to count seconds instead of ms
SECONDS = SECONDS + 1
ROLLOVER_COUNTER = 0
ENDIF
INTCON.2 = 0
RESUME
ENABLE

END