Hello everyone!
I'd like to generate a PWM signal with a duty cycle of 30%. When the following code was flashed to an UNO board, pin 11 (PB3) remained high and never did the good old oscillation. I'm sure I screw something up, I just can't seem to figure out what.
void setup()
{
Serial.begin(19200);
/* MY SETTINGS:
╔════════╦═══════╦═══════╦═══╦═══╦═══════╦══════╦══════╦══════╗
║ ║ FOC2A ║ FOC2B ║ - ║ - ║ WGM22 ║ CS22 ║ CS21 ║ CS20 ║
╠════════╬═══════╬═══════╬═══╬═══╬═══════╬══════╬══════╬══════╣
║ TCCR2B ║ 0 ║ 0 ║ - ║ - ║ 1 ║ 1 ║ 0 ║ 1 ║
╚════════╩═══════╩═══════╩═══╩═══╩═══════╩══════╩══════╩══════╝
╔════════╦════════╦════════╦════════╦════════╦═══╦═══╦═══════╦═══════╗
║ ║ COM2A1 ║ COM2A0 ║ COM2B1 ║ COM2B0 ║ - ║ - ║ WGM21 ║ WGM20 ║
╠════════╬════════╬════════╬════════╬════════╬═══╬═══╬═══════╬═══════╣
║ TCCR2A ║ 1 ║ 0 ║ 0 ║ 0 ║ - ║ - ║ 1 ║ 1 ║
╚════════╩════════╩════════╩════════╩════════╩═══╩═══╩═══════╩═══════╝
Timer Mode: 7 (WGM2:0 = 7)
Duty cycle: 30%
TOP: 102
*/
pinMode(LED_BUILTIN, OUTPUT);
// set OC2A as OUTPUT
DDRB |= (1 << PB3);; // OC2A pin - pin No.3
// clear settings
TCCR2A = 0;
TCCR2B = 0;
Serial.print("TCCR2A: ");
Serial.println(TCCR2A, BIN);
Serial.print("TCCR2B: ");
Serial.println(TCCR2B, BIN);
// set TOP to 102 -> generate 25KHz
OCR2A = 102;
// 30% duty cycle
OCR2B = 34;
// set Timer mode 7: goes from BOTTOM to TOP
// WARNING: WGM22 is part of TCCR2B
TCCR2A |= (1 << WGM21) | (1 << WGM20);
// clear OC2A on compare match, set OC2A at BOTTOM
// non-inverting FAST PWM mode
TCCR2A |= (1 << COM2A1);
Serial.print("TCCR2A: ");
Serial.println(TCCR2A, BIN); // prints 10000011
// set prescaler to 0 -> running at 16MHz - start timer
TCCR2B = (1 << CS22) | (0 << CS21) | (1 << CS20);
// WGM2:0 define mode 7
TCCR2B |= (1 << WGM22);
Serial.print("TCCR2B: ");
Serial.println(TCCR2B, BIN); //prints 00001101
}
So the question is: what am I missing to generate the PWM signal? Thank you in advance!
For mode = 7, TOP is the value in OCRA. From the Fine Manual: "Setting the OCR2A equal to MAX will result in a constantly high or low output (depending on the polarity of the output set by the COM2A1:0 bits.)" This is what I think you are seeing.
What you put in OCR2B does not come into it- at least, not for output on OC1A. If you set DDRD for output on PD3 (OC2B), and turn on COM2B1 in TCCR2A you might see some action (not sure that the comment about frequency 25kHz is correct though).
If the output must be on OC1A. you could change to mode 3, with OCR2A = 77 you should get duty cycle 30%, but you won't have fine control of the frequency due to limited prescaler values.
This is exactly what happened!
Indeed, when I started using OC2B pin to monitor the output, all was good (after setting it to output).
Thanks for taking the time to look up the relevant stuff in the datasheet! I missed it..