I'm using Arduino Uno Rev 3.
I'm trying to use Timer2 to produce a PWM signal on digital pin 11.
I've been going through the TC2 chapter in the datasheet again and again and read two threads about Timer2 here in the forum and still I can't get it right. I'm using an LED to just see when I get it right.
I understand that I neet to set TCCR2A, TCCR2B and OCR2A set properly to get this done. Of course the prescaler needs to be set to produce the frequency I need.
I think I need to set them to PWM Phase Correct mode. However, when I set the WGM bits to the mode I think I need, set the COM2A* and put a value in OCR2A - I can't get it to work.
I think that somehow I'm misreading the datasheet and therefore getting incorrect results.
Here are the lines of code I'm playing with.
I just extracted these lines with their current state (sorry, frustration got me trying various modes just to see what happens...), which just my LED to be constantly on to the naked eye.
Which mode do I need to set in the WGMx bits and COM2Ax bits to produce a PWM signal?
Once this is done, how do I control the duty cycle?
A great place to get code for setting up the registers to do PWM is the Arduino source code - specifically the files wiring.c (which contains the init() function that intializes lots of things) and wiring_analog.c (which has the code for analogWrite() )
You have set WGM22 to 0...so "Normal Ports, OC2A disconnected".
Did you mean this?
I have a feeling you meant to do WGM22 = 1 where you toggle on a compare match.
Many thanks for your help!!
The article pointed to by J-M-L is really a great one and very helpful.
The pointer from Robin2 to the central lib file also helped get a better understand of what's going on behind the scenes.
And thanks Johnny for the feedback.
I found out what I was doing wrong...it all goes back to not having an oscilloscope at hand.
In previous sketches where I had inputs coming from various sources, e.g. a PIR sensor, I figured - why not read the input continuously in the main loop and ASCII it out to the serial monitor. This proved to be a great tool for such cases, which BTW I recommend.
However, when starting to play with Timer2 and PWM, not having a scope I tried to use the same method for the PWM signal. Yes, I know it's an output signal. Still, I thought, it might be possible to read back the state of the IO and see it has the PWM I wanted to have. So I put what I thought to be an innocent digitalRead, to obtain the state of the IO when acting as PWM output.
After getting your inputs and following the article it seemed very strange that things still didn't work so I searched again and the only thing left after Timer2 init was that digitalRead. So I commented it out and this is when things started to work.
Today I traced digitalRead to wiring_digital (thanks again Robin) and I found that if one attempts to read an IO that has a Timer output attached to it, the timer is first turned off...which was the thing giving me the trouble.
So now I have the PWM working fine and I only need yet to sort out some frequency and PWM% calculations to reach the exact result.
Many thanks again for all your help.
Ilan