8

I'm currently playing with Arduino's hardware timers, and a question came to my mind. Let me explain it a bit.

Let's suppose I want a certain function to execute every 1024 clock ticks. AFAIK, I could achieve this in several ways, playing with the prescaler value for Timer2, and its CTC:

  1. Setting the prescaler to 1 and the CTC to 1024
  2. Setting the prescaler to 8 and the CTC to 128
  3. ...
  4. Setting the prescaler to 1024 and the CTC to 1.

All these ways would achieve what I want, but, which one is more efficient? Or it doesn't matter at all?

Thanks in advance for sharing your knowledge :P

2
  • 1
    Larger prescaler values will result in a very slight decrease in power consumption as whatever circuitry is connected to the output of the prescaler will switch at a lower frequency, and power consumption is proportional to c v^2 f. Sep 3, 2014 at 7:29
  • CTC is not a number, it's a mode of operation of the counter (mode 2). You set the period of the timer by setting OCR2A, the actual period being (OCR2A+1)×prescaler CPU cycles. Thus, if you set the prescaler to 8, you have to set OCR2A=127. Jan 14, 2016 at 11:03

2 Answers 2

2

If 'clock tick' count (here 1024), timer width and MCU clock used are constant (a fixed value), I would not go for last option i.e. prescalar 1024 and CTC of 1. Here are my reasons (specially for Arduino )

1) When CTC is close to zero ( like 1-> 10), sometimes timer behaves as if count is zero and outputs a square wave (with 50% duty ratio) with half the demanded frequency. So make CTC reasonably big. But again selecting a high clock frequency (pre scalar 1) may also show reduced accuracy. A intermediate option I think is better.

2) When count CTC changes dynamically in a process, timer pre scalar should be selected such that CTC count will always be less than or equal to timer width over whole process.

i.e. the maximum 'timer tick count' should be comfortably accommodated by the timer with it's given width. Even here same dilemma again occurs, then selection based on point 1 is better.

If this is not enough, then only way I think is to implement each case physically and check which combination gives you the best results. Practical results I think are more reliable ( may be you will get a board specific efficient combination!)

3
  • 1
    I don't see any reasonable root cause to validate your remark about low CTC values that may reduce accuracy. In particular, the "sometimes timer behaves..." is obviously wrong: why would timers in the AVR architecture would have not repeatable behavior in this case?
    – jfpoilpret
    Sep 3, 2014 at 19:09
  • I said low pre scalars (not CTC values) may reduce accuracy. Low CTC values may give unwanted outputs from timers.
    – Janakiram
    Sep 4, 2014 at 3:34
  • 'Sometimes' here means for 'some boards' of Arduino. I used this word because question not was asked for specific board. I have many times worked with 'Arduino Due' timers, with timer frequency 10.5 MHz and whenever I gave CTC count less than 15 ( or near by ) timers gave me a square wave, so obvious reason is that count is taken as zero. This is not mathematical but a practical observation. As said I have only worked with 'Due' for my purpose which is an ARM ( not AVR with lesser clock frequencies used in Arduino ) and so using 'sometimes' is valid I think.
    – Janakiram
    Sep 4, 2014 at 3:39
3

There is a trade-off between resolution and achievable frequencies. You mention Timer 2, but on the Atmega328P Timer 2 is an 8-bit timer, thus you would not be able to set the CTC to 1024.

Let's assume we are talking about an 16-bit timer, like Timer 1 on the Atmega328P. With a prescaler of one, you can time (assuming a 16 MHz clock) from 1 to 65536 "ticks", that is 62.5 ns up to 4096 µs.

This would be the most precise measurement because you are using one (processor) clock tick per timer tick (a prescaler of one).

However if you plan to time for more than 4.096 ms then you need to bump up the prescaler. The next prescaler up on Timer 1 is 8, so now you can time for an interval 8 times as long (32768 µs) however your accuracy (precision) has now decreased by a factor of 8. The granularity of the timer has increased from 62.5 ns to 62.5 * 8 ns, which is 500 ns.

If you need to time longer than 32.768 ms then the prescaler has to be larger again, the next one being 64. So now you can time up to 262144 µs, but with a granularity of 62.5 * 64, which is 4000 ns (4 µs).

My suggestion would be to use the lowest prescaler that you can, but still get the interval you want. So obviously you can't use a prescaler of one to time 10 ms.


I have a discussion about timers on http://www.gammon.com.au/timers.

On that page is a chart which helps visualize the effects of different prescalers:

Timers and prescalers

The top part (count of one) effectively gives you the granularity of each prescaler. For example, a prescaler of 256 has a granularity of 16,000 ns (16 µs). Certain frequencies (powers of 2) will lend themselves to combinations (eg. prescaler of 1 with a count of 256, or prescaler of 256 with a count of 1).

However for frequencies that don't have that property, the smaller prescaler will (if it can be used) give a finer granularity.

3
  • Using a higher prescaler does not loose any precision at all. You do get bigger granularity, but if you target a cycle count that is a power of two (like in the question), granularity is not an issue. Jan 14, 2016 at 10:50
  • But if not, then the lower prescaler lets you get closer to the target. Say you want to time 30 clock cycles. A prescaler of 1 lets you enter the number 30 directly. A prescaler of 8 means you have to use 30 / 8 (3.75) which you cannot directly enter into the register, thus losing precision.
    – Nick Gammon
    Jan 14, 2016 at 20:55
  • The question was worded with 1024 counts, so my remarks don't apply to that, but I was trying to give a more general answer, in case the fact that 1024 is a rather special case wasn't obvious.
    – Nick Gammon
    Jan 14, 2016 at 20:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.