Related to Arduino Mega 2560

I am using this code to vary the frequency from 73 kHz to 130 kHz. It works fine for Pin 9, but for Pin 10, which is supposed to output the inverted PWM signal, it is showing 32 MHz. I don't know why this issue is occurring.

void setup() {
  pinMode(9, OUTPUT);   // OC2A - Switch A (High Side)
  pinMode(10, OUTPUT);  // OC2B - Switch B (Low Side)
  
  // Disable interrupts during timer setup
  cli();
  
  // Reset Timer2 control registers
  TCCR2A = 0;
  TCCR2B = 0;
  
  // Configure Timer2 for Fast PWM Mode 7 (WGM2[2:0] = 111)
  // COM2A1:0 = 10 (Clear OC2A on Compare Match, set at BOTTOM) - non-inverting
  // COM2B1:0 = 11 (Set OC2B on Compare Match, clear at BOTTOM) - inverting
  TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(COM2B0) | _BV(WGM21) | _BV(WGM20);
  
  // Set Fast PWM Mode 7 (WGM22 bit) and no prescaler (CS2[2:0] = 001)
  TCCR2B = _BV(WGM22) | _BV(CS20);
  
  // Set initial TOP value for ~73kHz frequency
  OCR2A = 218;  // TOP value for ~73kHz
  OCR2B = OCR2A / 2;  // 50% duty cycle for complementary operation
  
  // Re-enable interrupts
  sei();
}

void loop() {
  // Sweep frequency from ~73kHz to ~130kHz by adjusting OCR2A (TOP value)
  for (int ocr = 218; ocr >= 122; ocr--) {
    OCR2A = ocr;  // Adjust TOP value to change frequency
    OCR2B = ocr / 2;  // Maintain 50% duty cycle (ensure OCR2B < OCR2A)
    delay(100);  // Delay for smooth frequency sweep
  }
  
  // Hold at minimum frequency briefly
  delay(100);
  
  // Sweep back from ~130kHz to ~73kHz
  for (int ocr = 122; ocr <= 218; ocr++) {
    OCR2A = ocr;  // Adjust TOP value to change frequency
    OCR2B = ocr / 2;  // Maintain 50% duty cycle (ensure OCR2B < OCR2A)
    delay(100);  // Delay for smooth frequency sweep
  }
  
  // Hold at maximum frequency briefly
  delay(100);
}

It seems to be impossible as for me. The maximum core clock of the Atmega2560 is 20 MHz

I think you are measuring incorrectly.

2 Likes

I am measuring the frequency correctly. When I set the frequency to a constant value, the inverted PWM signal on Pin 10 works correctly. However, when I try to vary the frequency for both pins, Pin 9 works fine, but Pin 10 starts behaving randomly.

in any way you can't get a 32 MHz signal on a 16 MHz core clock.
Are you meant a 32 KHz rather than MHz ?

Hi, @codruser
Welcome to the forum.

How are you measuring frequency?

Tom.... :smiley: :+1: :coffee: :australia:

You selected a "Fast PWM" mode where the timer counts to the OCR2A value.

Since the OCR2A is used as TOP value for the counter, the PWM signal on channel A a is not generated. In this mode, you cannot use pin 10 as a PWM output.

this is totally expected, isn't it?

I am measuring the frequency correctly using an oscilloscope. When I set the frequency to a constant value, the inverted PWM signal on Pin 10 works as expected. However, when I vary the frequency dynamically, Pin 9 behaves correctly, but Pin 10 starts behaving randomly. I am not sure why this is happening.

Ok, so how can i use this as an inverting PWM for PIN 9 and 10.

please try to think logically
Are you understand that if you got 32MHz on a 16MHz core - it means your measurements are complete nonsense?

Do not use the modes, where OCR2A used as TOP

See the Atmega2560 datasheet, chapter 20 "8bit Timer2", the table 20-8

I need a wider frequency range, from 73 kHz to 130 kHz. This cannot be achieved using this timer.

good point
Use 16-bit timers
See the Fast PWM mode 14 of the Timer1

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.