This code below:

void setup() {
  #if defined(__AVR_ATmega168__)
    // 62.5KHz PWM for the ATMega168 -> only on Arduino pins 9 and 10

    // set prescaler to 1
    // (sbi means "set bit register", cbi means "clear bit register")
    cbi(TCCR1B, CS12);
    cbi(TCCR1B, CS11);
    sbi(TCCR1B, CS10);

    // set fast PWM
    cbi(TCCR1B, WGM13);
    sbi(TCCR1B, WGM12);
    // with fast PWM, the frequency is (CLK/256*prescaler) = 16MHz/256 = 62.5KHz
    // with slow PWM, it is half that speed (31KHz)
    // 22KHz for the ATMega8 (this is a low frequency)
    TCCR2 = ((TCCR2 & ~0x07) | 0x01); //<ERROR POINTS HERE!
    TCCR1B = ((TCCR1B & ~0x07) | 0x01);

when verify, generates an error:

In function 'void setup()':
pwm-control-1:185: error: 'TCCR2' was not declared in this scope
TCCR2 = ((TCCR2 & ~0x07) | 0x01);
exit status 1
'TCCR2' was not declared in this scope

So far i know this code generates pwm at pin 9 or 10, and designed for ATmega168 or ATmega8. The code came with a .pde extension and I opened it on 'Arduino: 1.8.3' and saved as an .ino file.

Can any one please tell me how to convert this code to work with 'ATmega328P-PU' and for the latest Arduino IDE. And also if there anything else to consider running with this code

I'm not an expert in pwm and timer/controls in micros... just started to learn..

Note: I've only shown the necessary part of the code

  • Since your problem is with the software delivered with Arduino, this question belongs on Arduino.SE – pipe Aug 27 '17 at 8:07

Looks like this code is pretty old. It's assuming that any Arduino that isn't using an ATmega168 is using an ATmega8. In reality, the ATmega8 hasn't been used on any Arduino boards in the last ten years or so -- it's pretty much obsolete.

The easiest fix will be to remove the non-'168 branch (between #else and #endif), and make the '168 branch default (remove the #if line). This will probably still fail on ATmega32U4 boards, but at least it'll now work on ATmega328 hardware.


The problem is because TCCR2 is not declared, as there is no register with that name. Maybe you wanted to configure the timer 2, i.e. you meant TCCR2A or TCCR2B instead of TCCR2.

EDIT: analyzing your code, you should definitely write TCCR2B.


Check the datasheet to see if there is a tccrb. Maybe for your device, it is tccra, tccrb, or teerc, ....

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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