Let's Make Robots!

PWM and registers

Hello,

some time ago i had opened a forum post about PWM on arduino. RobotFreak gave me a piece of code that made my remote work:

#define pwmPin 11

void setup()  {
 
  // toggle on compare, clk/1
  TCCR2A = _BV(WGM21) | _BV(COM2A0);
  TCCR2B = _BV(CS20);
  // 36kHz carrier/timer
  OCR2A = (F_CPU/(IR_CLOCK_RATE*2L)-1);
  pinMode(pwmPin, OUTPUT);
  
}

This works great. But my project actually needs pin 11 for other stuff (it's the MOSI pin). So i tried changing it but it doesn't work. I have to say i don't have great clue on how these things work (registers) so i for sure have made an error. This is how i changed it:

void setup()  {
   
  // toggle on compare, clk/1
  TCCR2A = _BV(WGM21) | _BV(COM2B0);
  TCCR2B = _BV(CS20);
  // 36kHz carrier/timer
  OCR2B = (F_CPU/(IR_CLOCK_RATE*2L)-1);
  pinMode(pwmPin, OUTPUT);
  
}

basically just replaced B with A, and according to this article (http://www.arcfn.com/2009/07/secrets-of-arduino-pwm.html) the OCR2B register controls PWM on PD3, so i also define pwmPin as 3 (arduino output that matches PD3). For some reason it doesn't work, what am i missing?

Thank you.

 

 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

It works!....but only on my arduino duemilanove board, and it doesn't on my breadboarded arduino. I guess the breadboarded one has a problem, even the SPI problem i had got solved by switching to an arduino board.

Thanks for the help!

Did you connect AVcc of your ATMega on breadboard? I'm not sure what kind of behavior not connecting AVcc will cause, but when I was reading ATMega datasheet this caught my eye: "AVcc is the supply voltage pin for the A/D Converter, PC3:0, and ADC7:6. It should be externally connected to VCC, even if the ADC is not used. If the ADC is used, it should be connected to VCC through a low-pass filter. Note that PC6...4 use digital supply voltage, VCC."

So AVcc seems to power pins PC3:0 (and ADC7:6 on TQFP and 32 MLF versions). I'm just thinking that maybe it does something else too. It seems that there has been something weird with Vcc and AVcc connection at least on ATMega 8 in the past and maybe in current versions too. But this is just a guess. I don't know for sure if that could be a problem. If AVcc just powers PC3:0 it shouldn't affect neither PWM nor SPI I guess. Here's couple of links with discussion related to Vcc and AVcc weirdness:
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=printview&t=20967&start=0
http://news.emcelettronica.com/avr-forum-atmega8-still-have-known-avcc-bug

 

Nope. AVcc was connected to V+ normally. Not to say that basic sketches like "Blink" work fine. That is really driving me mad. I've tried 5 different atmega328s, they all work on board and not on the breadboard. Unfortunately i'm not at home, will have to wait until friday then i'll be able to put my hands on it again. I am thinking it has to do with the resonator, not sure why though.

I've had issues with running my arduino via a breadboard as well. I think it's related to the connections of the crystal/resonator not being as solid a contact as it should be. Just a thought.

I eventually got it to work, but i have no idea why it works! 

Basically when i took away the 10K resistor that connected V+ to reset the atmega started working fine. When i plug the 10K in it stops working! I don't know what this happens. I was thinking of some internal pull up that makes the atmega work fine even without the 10K pullup, but then i can't understand why it stops working when i add an external 10K, not to mention the duemilanove works fine with the external pull up....

Hmm...

 

EDIT: forget it, i'm an idiot :D

You guys are right! I thought there was no difference between COM2A0 and COM2B0, i better check the datasheets next time. Tomorrow i'll try switching to timer1 (timer0 controls millis() and delay(), i better not mess with him).

I agree with nuumio in as much as I can understand the code and from reading the datasheet. In no way am I an expert or fully understand what the code is doing. However it does appear that the code s specific to timer2 and affects both registers A and B. With what you changed, you've affected how this timer is functioning, possibly making it not work at all.

It does sound correct that you would want to use timer0 as opposed to timer1 as timer  0 and 2 are both 8 bit timer/counters where 1 is a 16bit timer/counter. Wish I could be more help, but I'm still learning this stuff as well.  :)

If I read your code and the datasheet correctly you are setting Timer2 to CTC mode and compare match output A to toggle on compare match. Checking the datasheet (http://www.atmel.com/dyn/resources/prod_documents/doc8271.pdf, not sure if this is right one) tells that compare match output B doesn't support toggle on compare match in PWM modes (it's says "reserved", on pages 160-161). I have only looked at AVR PWM generation very briefly with ATTiny so I might have gotten it all wrong.

Can you use timer0 or timer1 for PWM (pins PD6 [OC0A] and PB1[OC1A])? Or maybe you can do software pwm so that you write interrupt handler for timer2's compare match B and toggle the pin state yourself there. Or maybe someone more familiar with AVR/Arduino PWM can give better solution :-)