Timer 2 prescaler bits... can't set to 32 :(

Hi all,

I set Timer2 to:

TCCR2B = 0<<CS22 | (0<<CS21) | (1<<CS20);

which gives me a prescaler of 16us per interrupt, but that interrupt is too short to do anything more than increment a few counters… I would like to set the prescaler to 32… but adjusting these bits scales down too much :frowning:

Can any help me set the prescaler to 32?

thanks x

EDIT:

I currently use: TCCR2B = 0<<CS22 | (1<<CS21) | (0<<CS20);

which scales to 128… this gives me plenty of time to check some logic in my ISR… but is a little to corse for the timing requirements of my project

The answer can be found in the table on page 162 of the '328 data sheet, which you can get from http://www.atmel.com/dyn/resources/prod_documents/doc8161.pdf

Happy hacking,

-br http://bitlash.net http://entropymouse.com

 TCCR2B = [glow]0<<CS22[/glow] | ([glow]0<<CS21[/glow]) | (1<<CS20)

The highlined dont do anything,to set a bit you do:
TCCR2B |= (1<<CS20);
To clear you do:
TCCR2B &= ~((1<<CS22)|(1<<CS21));

Thanks for the link, If I've read it properly... my original settings were un prescaled... so 16us is the timer rate, and the next setting is a devisor by 8, which is giving me my 128us. So that is the fastest I can get on this timer, above 16us

That will have to do, it's not perfect, but it is just about fast enough!

Many thanks.

Thanks Senso, good tip, I will adjust my code to the correct way. By luck the top bits must already be clear :)

Hm... that's a nice clean and easy to understand way to set the bits.

Why then do some examples like this one: http://www.arduino.cc/playground/Code/PCMAudio

Go to all the trouble to use this undocumented macro to do the same thing then?

TCCR2B = (TCCR2B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);

Your code I can simply read. That code I have no idea what it does unless I know what _BV does, and that is hidden somewhere in the Arduino's libs.

Wait a minute... I just noticed the Arduino has built in macros for setting and clearing bits:

bitClear(TCCR2B, CS22); bitSet(TCCR2B, CS21); bitSet(TCCR2B, CS20);

It doesn't geat simpler and easier to understand than that. Why do it the other way? Even knowing what bitwise nots and ands and ors do, it took a while for me to decipher what the other code was doing. The above however would be clear at a glance.

And since the macros are basically the same bitwise operations, it should compile to pretty optimized code. Not that the code to set up a timer likely needs to be super optimized.

I know using interrupts isn't exactly something geared towards beginners, but it would make learning to use them easier.

Thanks for the link, If I've read it properly... my original settings were un prescaled... so 16us is the timer rate, and the next setting is a devisor by 8, which is giving me my 128us. So that is the fastest I can get on this timer, above 16us

That will have to do, it's not perfect, but it is just about fast enough!

Many thanks.

It sounds like you're saying you think you can run the timer at 16us or at 128us. I'm no expert on interrupts, and I'm not sure where you get those numbers, but if you divide 1 second by 16mhz, you get 0.0000000625. I'm not sure whether that's 6.25us or 625us, but I don't see a 16 in there.

Anyway, I'm getting off track. You seem to think you can run the interrupt at /1 or /8 or /32... and that is the speed at which your interrupt is called.

But that's not the case. That is the rate at which your timer updates. And while you can call the interrupt every time the timer updates, you can also call it every 2nd or 3rd or whatever time it updates.

So you could set the timer to a prescalar of /8 OR you could set it to /1 and then set it to trigger when it compares itself to a certain register and the values are equal, and then set that register to 8. The interrupt would then be triggered just as often as it would have been if you set the presclar to /8 and made it trigger every time.

This means that if /8 is too slow, but /1 is too fast, you could set that register I mentioned to 6, and then effectively get clk/6.

At least that is my understanding of how it all works. I am in the middle of writing some interrupt code myself.

It sounds like you're saying you think you can run the timer at 16us or at 128us. I'm no expert on interrupts, and I'm not sure where you get those numbers, but if you divide 1 second by 16mhz, you get 0.0000000625. I'm not sure whether that's 6.25us or 625us, but I don't see a 16 in there.

Anyway, I'm getting off track. You seem to think you can run the interrupt at /1 or /8 or /32... and that is the speed at which your interrupt is called.

But that's not the case. That is the rate at which your timer updates. And while you can call the interrupt every time the timer updates, you can also call it every 2nd or 3rd or whatever time it updates.

So you could set the timer to a prescalar of /8 OR you could set it to /1 and then set it to trigger when it compares itself to a certain register and the values are equal, and then set that register to 8. The interrupt would then be triggered just as often as it would have been if you set the presclar to /8 and made it trigger every time.

This means that if /8 is too slow, but /1 is too fast, you could set that register I mentioned to 6, and then effectively get clk/6.

At least that is my understanding of how it all works. I am in the middle of writing some interrupt code myself.

Hey there, I set it up so that Timer2 calls my ISR every time it overflows, the lowest rate I can get it to do that is 16us. The next prescaler value causes it to overflow every 128us... which is what I've had to use, which is just about usable for my project.