Set PWM Pin 11 to 20Khz?

Hello, I'm using the PWM Pins 5,9,10,11 with my 32u4 Arduino Board for 4 small motors.

The follwing code is working fine, but for the PWM PIN 11 I have to use "OCR1C" (OCR1C = speed;).

For the others I can simple use analogWrite(9, speed);

So... how I have to change the code to use analogWrite for PWM Pin 11?

  // * PWM Pins 9 & 10, Timer 1 is using: Channel A OCR1A at Pin 9 and Channel B OCR1B  at Pin 10 *
    TCCR1A = 0b10100000;
    TCCR1B = 0b00010001;   // (              ,No prescaling: TCCR1B |= _BV(CS10) )
    
    // * PWM Pin 5, Timer 3 is using: Channel A OCR3A at Pin 5 *
    TCCR3A = 0b10100000;
    TCCR3B = 0b00010001;
    
    // * PWM Pins 3 & 11, Timer 0 (driven by  Timer 1) is using: Channel C OCR1C at Pin 11 *
    TCCR0A &= ~(_BV(COM0A1) | _BV(COM0A0));  
    TCCR1A |= _BV(COM1C1) | _BV(COM1C0);  

    
    
    // * PWM Pins 6 & 13, Timer 4 (driven by  Timer 1) is using: Channel D OCR4D at Pin 6 and Channel A OCR4A  at Pin 13 *
    TCCR4A = 0b10100000;
    TCCR4B = 0b00010001;

    
    // * Set 20 Khz *
    ICR1 = (F_CPU/(20000.0f*2));
    ICR3 = (F_CPU/(20000.0f*2));

// * PWM Pins 3 & 11, Timer 0 (driven by Timer 1) is using: Channel C OCR1C at Pin 11 * TCCR0A &= ~(_BV(COM0A1) | _BV(COM0A0)); TCCR1A |= _BV(COM1C1) | _BV(COM1C0);

That interesting, I did not realize you could drive one timer with another (unless it was an external loop). I will have to have a closer look (i.e. read the AVR datasheet).

Regards Alan0

Hi DreiMalNull,

Well that was interesting - I almost gave up. I have don't have a Mega so I have not read this datasheet before. It all looks correct but note that the Output Compare Modulator (refer to Section 19) outputs on PB7.

Regards Alan0

PB7 is Pin 11 ... so it's correct.

i've realized that "analogWrite" has is still using Timer 0 if I want to call PWM Pin 11 ... so there is no other solution to use OCR1C = speed.

Anyway... it's ok... but the code is looking ugly with it :)

Hi DreiMalNull,

If you want more control, you could use a timer ISR and control the pins “manually”.

Here is an example for a 20kHz PWM on pins 5 and 6 for an UNO:

// Timer2 compare A interrupt service routine
ISR(TIMER2_COMPA_vect)
{
  // Turn on PWM pins 5 and 6
  //      76543210 Arduino digital pin number
  PORTD|=B01100000;
}

ISR(TIMER2_COMPB_vect)      // Timer2 compare B interrupt service routine
{
  // Turn off PWN pins 5 and 6
  //      76543210 Arduino digital pin number
  PORTD&=B10011111;
}

...

  // Initialize timer2
  noInterrupts();           // Disable all interrupts
  TCCR2A = B00000010;       // Disconnect Arduino D3 and D11 pins and set CTC mode (see AVR datasheet S11.11.1)
  TCCR2B = B00000010;       // Set clock prescaler to 8, now clock is 2MHz (see AVR datasheet S11.11.2)
  TCNT2  = B00000000;       // Reset timer (why not?) (see AVR datasheet S18.11.3)
  OCR2A  = 99;              // Set compare match register A for 20kHz PWM frequency (see AVR datasheet S18.11.4)
  OCR2B  = 7;               // OCR2B (see AVR datasheet S18.11.5) to duty, 1% per step, minimum pulse width is 4 us.
  TIMSK2 = B00000110;       // Enable timer compare interrupt on OCR2A and 0CR2B (see AVR datasheet S18.11.6)
  interrupts();             // Enable all interrupts

Regards Alan0

Thanks.