Arduino Nano Every ATMEGA4809 PWM Code

Arduino Nano Every ATMEGA4809 PWM Code

Sample code to adjust the PWM frequency for analogWrite without affecting millis().

D5, D9 and D10 cannot be changed from 970Hz at 16MHz and 1221Hz at 20MHz without affecting millis().

D3 and D6 are by default, the same as D5, D9 and D10 but can be modified in the following way.

Include the following defines/function in your sketch:

#define PWM_NORMAL 0 // 16MHz CPU = 970Hz PWM, 20MHz CPU = 1221Hz PWM
#define PWM_MEDIUM 1 // 16MHz CPU = 31250Hz PWM, 20MHz CPU = 39063Hz PWM
#define PWM_FAST 2   // 16MHz CPU = 62500Hz PWM, 20MHz CPU = 78125Hz PWM

void set_PWM(int option) {
  cli();  // Disable Interrupts
  switch (option) {
    case PWM_MEDIUM:
      TCB0_CTRLA = (TCB_CLKSEL_CLKDIV2_gc) | (TCB_ENABLE_bm);
      TCB1_CTRLA = (TCB_CLKSEL_CLKDIV2_gc) | (TCB_ENABLE_bm);
      TCB2_CTRLA = (TCB_CLKSEL_CLKDIV2_gc) | (TCB_ENABLE_bm);
      break;
    case PWM_FAST:
      TCB0_CTRLA = (TCB_CLKSEL_CLKDIV1_gc) | (TCB_ENABLE_bm);
      TCB1_CTRLA = (TCB_CLKSEL_CLKDIV1_gc) | (TCB_ENABLE_bm);
      TCB2_CTRLA = (TCB_CLKSEL_CLKDIV1_gc) | (TCB_ENABLE_bm);
      break;
    case PWM_NORMAL:
    default:
      TCB0_CTRLA = (TCB_CLKSEL_CLKTCA_gc) | (TCB_ENABLE_bm);
      TCB1_CTRLA = (TCB_CLKSEL_CLKTCA_gc) | (TCB_ENABLE_bm);
      TCB2_CTRLA = (TCB_CLKSEL_CLKTCA_gc) | (TCB_ENABLE_bm);
  }
  sei();  // Enable Interrupts
}

You can then call it either in setup or your main loop:

set_PWM(PWM_NORMAL);
// set_PWM(PWM_MEDIUM);
// set_PWM(PWM_FAST);

Leave a Reply