Timer/Counter0 overflow and timebase relation

Go To Last Post
12 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello everyone, maybe the question is a bit trivial but is there any formula to calculate the time from timer overflows?

In simple case when we run AVR at 8MHz and we have the Timer/Counter0 setup for normal operation with /8 prescaler how can I calculate the time from overflows let's say seconds´?

 

8000000/256 = 31250? overflows, but it is still not time

 

This topic has a solution.

program is working......

Last Edited: Mon. Oct 29, 2018 - 12:02 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Time is 1 / freq

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Dave_Zeb. wrote:

.... operation with /8 prescaler .... 8000000/256 = 31250? overflows, but it is still not time

 

But that isn't using the prescaler.

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

8000000(clock freq) / 8(prescale) / 256(counter max count) = time period to overflow

time = 1/period  = 0.000256 seconds

 

Jim

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274

 

 

 

Last Edited: Fri. Oct 26, 2018 - 12:58 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

then for if I understood this right it should be like this:  F_CPU =8Mhz, the Timer0 without prescaling will have a 0.125 µs per tick, and for the hole time per overflow will be 256 x 0.125µs= 32 µs. So  each timer0 overflow equals to 32µs.

program is working......

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You got it! smiley

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274

 

 

 

Last Edited: Fri. Oct 26, 2018 - 01:15 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you want your clock to have a resolution of one second then you should

choose a larger prescale value to minimize the number of overflows .  The

max is 1024.  With an 8 MHz clock you will see 8000000 / (1024 * 256)

timer overflows per second.  This is not a round number, it's about 30.5,

so you will have to use a smaller prescale value and count more overflows.

 

The next smaller prescale setting is /256 which requires counting 122.07

overflows per second.  Rounding to 122 speeds up your clock a bit (the

error is about 600 ppm).

 

Once you have a one-second 'tick' you call a clock update function every

second which is fairly straightforward:

 

uint8_t seconds;  // need a way to initialize
uint8_t minutes;  // these to the current time
uint8_t hours;

void clock_update () {
    ++seconds;

    if (seconds == 60) {
        seconds = 0;
        ++minutes;

        if (minutes == 60) {
            minutes = 0;
            ++hours;

            if (hours == 24) {
                hours = 0;
            }
        }
    }
}

 

Adding dates is a bit more complicated due to the varying number of

days per month and leap years, etc.

 

Alternately you can add a DS1307 real-time clock to your project and

it does all this for you -- just need to talk to it via I2C / TWI.   Though

beware of the Y2K1 bug (it uses a 2-digit year!).

 

--Mike

 

EDIT: removed confused mention of OCRA

 

Last Edited: Sat. Oct 27, 2018 - 08:38 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks a lot for nice explanation Mike. Actually it is so amazing that you can use just a bare AVR and build a real-time clock with it. Even if you consider some small uncertainties due to various factor, I think it is pretty amazing.

I am using the Timer0 for a time base. So I guess the 122.07 is better option. I'll go for that one. Not really want to add another IC to setup.

 

program is working......

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avr-mike wrote:

...(the error is about 600 ppm)...

 

Which doesn't sound much but it is 5 hours per year. Or 25 minutes a month which might be an issue for an alarm clock.

#1 This forum helps those that help themselves

#2 All grounds are not created equal

#3 How have you proved that your chip is running at xxMHz?

#4 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand." - Heater's ex-boss

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Or one uses the ‘fractional n’ technique where you change the OCRA value each compare so the error averages out. Eg if you needed a divisor of 10.5 then first compare wounld be 10, next 11, next 10 and so on so the average is 10.5. Extend this concept to get the average divisor you want.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In the case above (8 MHz clock), there's no reason to have to live with other than an exact result.  31250 is 250 * 125, so set the timer to count to 250 (OCR = 249), and count 125 timer overflows in software to get exactly 1 second (+/- the AVR clock accuracy, of course).  This is based on a prescaler of 256, BTW.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Here is an example of the 'fractional n' calculation.  Let's say you want to divide a clock by 10.7.  This means you will sometimes set OCRA to 10, and sometimes set it to 11, to get an average of 10.7.  First you strip off the integer and just focus on the decimal part, which is 0.7 in this case.  Then you represent the decimal part as N/D.  Here it is 7/10.  Reduce as necessary (so one half becomes 0.5 becomes 5/10 becomes 1/2).

 

Since D = 10, the complete cycle will take 10 passes and count 107 clocks total (10 * 10.7).  Here is the sequence:

 

First set a signed accumulator to 0.

ACC = 0

 

Next, perform the calculation, each time through:

ACC = ACC - N

 

If ACC < 0, add D and increase the timer count by 1 for that pass.

 

For the 10.7 example, here are the numbers:

 

ACC = 0

 

Now look at each pass in turn

 

1) ACC = 0 - 7 = -7.  Add 10.  ACC = 3.  Increase OCRA from 10 to 11  Total cycles counted = 11

2) ACC = 3 - 7 = -4.  Add 10.  ACC = 6.  Increase OCRA from 10 to 11  Total cycles counted = 22

3) ACC = 6 - 7 = -1.  Add 10.  ACC = 9.  Increase OCRA from 10 to 11  Total cycles counted = 33

4) ACC = 9 - 7 = 2.  OCRA = 10                                                          Total cycles counted = 43

5) ACC = 2 - 7 = -5.  Add 10.  ACC = 5.  Increase OCRA from 10 to 11  Total cycles counted = 54

6) ACC = 5 - 7 = -2.  Add 10.  ACC = 8.  Increase OCRA from 10 to 11  Total cycles counted = 65

7) ACC = 8 - 7 = 1.  OCRA = 10                                                          Total cycles counted = 75

8) ACC = 1 - 7 = -6.  Add 10.  ACC = 4.  Increase OCRA from 10 to 11  Total cycles counted = 86

9) ACC = 4 - 7 = -3.  Add 10.  ACC = 7.  Increase OCRA from 10 to 11  Total cycles counted = 97

10) ACC = 7 - 7 = 0.  OCRA = 10                                                        Total cycles counted = 107

11) Back to 1

 

At this point, we have counted 107 clocks in 10 passes, or an average of 10.7 clocks per pass, just as required.

 

The technique also works for non-based-10 calculations, e.g. 129/14.  This boils down to 9-3/14.  So the base OCRA value = 9, N = 3, and D = 14.  Adding (14-3)*9 + 3*10 gives 129 clocks total over 14 passes.

 

 

 

 

Last Edited: Sat. Oct 27, 2018 - 01:32 AM