Exact match. Not showing close matches.
'[PIC] How to calculate time (seconds) using freque'
|I'm having a rough time calculating times and I could need a hint.
What I'm having is a 12F683-chip using INTOSC 31kHz. Now, I want to
use the Timer0-module to start when the comparator interrupt occured.
This is no problem for me.
After the Timer0 has started, I want the application to do something
after X seconds (X is supposed to be around 8, but it can be 10 if
it's easier to explain). Timer0 uses Fosc/4, which means its frequency
is 8192Hz, or 0.12ms (1/8192). It's an 8bit-timer and overflows every
256 tick, which means every 30.72ms. For the sake of the simplication,
say 30ms. 8 seconds divided with 30ms gives 333 overflows.
Am I correct this far?
A register could keep the track of the amount of overflows, and when
it reaches 333, the application should react. Now, since the registers
are 8 bit only, I cannot use a single register to keep track on the
amount of overflows. Therefore, I have to use the prescaler which I -
still - haven't got a perfect grip of how it's working.
I'm _guessing_ that - provided prescaler is 1:2 - the frequency will
be divided in half. So, prescale 1:2 gives 4096Hz, or a tick per
0.2ms, which overflows Timer0 every 51.2ms (say 50ms). 8 seconds
divided with 50ms gives 160 overflows, which fits in a register.
On the other way around, if 1:2 prescaling means the frequency will
double, 16384Hz, a tick occurs per each 0.06ms, 8 seconds per 15.36ms
(15ms), requiring 520 overflows, which is even worse.
If anyone could shed some lights for me whether my path of thoughts
are correct or if they are completely erratic, I would be grateful.
- Rikard - http://bos.hack.org/cv/
> A register could keep the track of the amount of overflows, and when
> it reaches 333, the application should react. Now, since the registers
> are 8 bit only, I cannot use a single register to keep track on the
> amount of overflows.
Correct. Just use two registers.
Rikard Bosnjakovic wrote:
I think you are making this more complicated than you need to. Yes, the
8-bit registers hold only
0 to 255. But the PIC has some wonderful instructions like INCFSZ,f ,
which allow you to EASILY
count by 256.
Assume that TIM_LS is the fast register, and TIM_MS counts by 256. All
you need to do is:
INCFSZ TIM1,F ;increment, but skip next instruction if
increments thru 00
GOTO NOT256 ;nope no overflow, so get out...
INCF TIM2,F ;TIM1 overflowed, so increment TIM2
.... more stuff here?
NOT256 ...and more stuff here?
The easiest way to verify timers is to make an LED wink on and off. If
you think the LED should be
ON then OFF at a ONE SEC rate, check it against your watch or
oscilloscope and see.
|On 7/12/07, Peter Feucht <palmed-medizintechnik.de> wrote: p.feucht
> You didn't say anything about accuracy, but if you are using a prescaler of
> 1:128 (hope ist possible with the F683, don't have a datasheet on hand) the
> timer's clock input is 32768(Masterclock)/4(Fosc/4)/128(Prescaler)= 64ms,
Thanks for the explanation. I used the tip of yours and set the
prescaler to 1:128 (it's possible to do it up to 1:256 in the F683).
However, the Timer0 interrupts every 2 seconds or so despite it should
be around 10 seconds. For 10 seconds, it's 156 ticks, so I load TMR0
with 100 (256-156):
The datasheet tells me that any write to TMR0 resets the prescaler. I
think this means I have to re-write the prescaler bits into OPTION_REG
once more, so I'm having this code immediately after the TMR0-write
movfw OPTION_REG ; when TMR0 is
altered, the prescaler is reset
iorlw b'00000110' ; so we have to write it back
But I still get the interrupts after just 2 seconds, which is not even
close to 10 seconds.
Am I missing something?
- Rikard - http://bos.hack.org/cv/
An approach I use in systems with lots of time-based things:
Timer interrupt: ( set up to happen every 1mS)
Pick up Device1_Timer
If it's not zero, then decrement it.
Pick up device2_timer
if it's not zero, then decrement it.
(and so on)
Pick up HMS_Timer ; Hundred Millisec
If it's not zero, then decrement it and reti
If it is zero, reload, and continue, serving 100mS timers
Pick up Seconds_Timer
if it's not zero, then decrement it
;Other 100mS per tick timers go here.
Ok, Device 1 wants to wait 50mS.
It loads 50 into it's timer byte, and then waits till that byte becomes zero.
Device 2 wants to wait 100mS, same thing.
Some other device wants to wait 5 seconds, it loads 50 into
Seconds_Timer, and waits till that goes to zero.
None of these tasks has to sit and spin in a loop, they simply return
to main, and don't execute till it's their time.
> The datasheet tells me that any write to TMR0 resets the
> prescaler. I think this means I have to re-write the prescaler
> bits into OPTION_REG
No, it means that the value IN the pre-scaler is reset, ie 00. The
actual division BY the pre-scaler, like the song, remains the same,
so you don't need to touch Option
wrt your other thought, a pre-scaler or post-scaler always divides
Getting back to your original problem, you want an 8-second
delay with an effective clock of 8192Hz (32k Fosc / 4)
8192Hz = 122.0703125us per tick
8 seconds = 8,000,000us / 122.0703125us = 65536 ticks
= 0x10000 or 0xFFFF + 1 => a 16-bit rollover
So, an 8-bit TMR0 with p/s = 1:256 will rollover once in 8s
The p/s will rollover in (256 * 122.0703125us) = 31250us
TMR0 will rollover in (256 * 31250us) = 8,000,000us
If Fosc is really 31kHz then the rollover time will be longer,
because of the lower frequency, by 32768/31000 => 8.456s
|Rikard Bosnjakovic wrote:
> banksel OPTION_REG
> movfw OPTION_REG ; when TMR0 is
> altered, the prescaler is reset
> iorlw b'00000110' ; so we have to write it back
> movwf OPTION_REG
The prescaler is cleared, not the prescaler setting. This code is
unnecessary. When you write to TMR0, the internal prescaler countdown is
reset, but the division ratio doesn't change.
Also, I hope you're setting OPTION_REG fully when you configure TMR0.
Doing read-modify-write operations on setting registers is rarely a good
idea. Sometimes bits have weird read behavior, other times you're
missing out on settings. For example, you need to make sure PSA is clear
to assign the prescaler to TMR0. PSA is set by default. You also need to
clear T0CS to tell TMR0 to run on Fosc, not an external pulse input.
T0CS is also set by default.
Assuming you aren't touching OPTION_REG before, what you're doing is
actually having no effect. OPTION_REG is 11111111 on startup, and ORing
that with any constant isn't going to change anything. You're winding up
with the prescaler assigned to the WDT at 1:128. The WDT times out every
18ms nominal, which is 2.3 seconds with the prescaler assigned. You're
probably having the WDT interrupt / reset your chip, not TMR0.
> banksel GPIO
Also, sleep stops the main oscillator. This means TMR0 won't tick, and
you won't get any interrupts.
Hector Martin (marcansoft.com) hector
Public Key: http://www.marcansoft.com/marcan.asc
More... (looser matching)
- Last day of these posts
- In 2007
, 2008 only
- New search...