As told in this post:


The arduino can achive up to 62.5khz with 8 bits resolution

adding this line in the setup:

TCCR0B = TCCR0B & 0b11111000 | 0x01

sets the divisor of the timer to 1

int output = 5;
void setup() {
  // put your setup code here, to run once:
  TCCR0B = TCCR0B & 0b11111000 | 0x01;


void loop() {


But I need a frequency of 100khz or as close as possible, the 8 bits resolution is not necessary of my porpouse, it will work just fine with 6 or 7 bits.

  • For 100kHz, you need to use a fast PWM mode, with a TOP specified by OCRxA, – Dave X Feb 21 '16 at 22:48
  • 1
    arduino.stackexchange.com/a/19553/6628 has an exellent answer. You do need the smaller /1 prescaler though. – Dave X Feb 22 '16 at 15:15

Here's code for timer 1 on a atmega32u tested in a Teensy 2.0:

void setup() {
  // put your setup code here, to run once:

   // Timer 1 Fast PWM mode *toggling* OC1A at 50kHz with *two* OCR1A counts
   // And 7.32 bits 0-159 PWM on OC1B at 100kHz
   // Output on OC1B  
   // Set at TOP, Clear at OCR1B
   // WGM =15 0b1111 

   DDRB |= bit(DDB5) | bit(DDB6);  // atmega32u OC1A and OC1B outputs
  // DDRB |= bit(DDB1) | bit(DDB2);  // atmega168/UNO OC1A and OC1B (Tested by OP/Luis)

   TCCR1A =  bit(WGM11) | bit(WGM10) | bit(COM1A0) | bit(COM1B1)  ; // Toggle OC1A, Clear on OC1B    
   TCCR1B =  bit(WGM13) | bit(WGM12) | bit(CS10);  // Set /1 prescaler
   OCR1A  = 159 ;//79;    // Set TOP count to 16000000/(2*PreScaler*Ftoggle)
                          // or 16000000/(PreScaler *Ftimer)
   OCR1B  = 10;           // 10/160 duty cycle
   TCNT1 = 0 ;

void loop() {
  // put your main code here, to run repeatedly:
  OCR1B = 160/4 -1 ; // 25% duty cycle. 

The trick here is using OCRxA to set the TOP value/resolution/frequency of the timer, and then using OCRxB as the PWM-controlled output. The popular examples aim for a specific frequency with toggling, but often don't go into showing the PWM with the non-TOP OCRxx registers.

If you check the registers for your chip, this should also adapt to the other timers. Here, I used timer1 to avoid confusing delay() and millis().

  • This will correspond to the pin 10 of the arduino uno rigth? arduino.cc/en/Hacking/PinMapping168. I have no try the code and get no output – Luis Ramon Ramirez Rodriguez Feb 22 '16 at 21:38
  • 1
    Yes, per that diagram digital Pin 10 is OC1B, but since on the atmega168, it is PB2, so the DataDirectionRegister needs to enable bit 2. I added it in a comment in the above code, but I'm not able to test it. – Dave X Feb 23 '16 at 1:30
  • Tested, it works just fine. – Luis Ramon Ramirez Rodriguez Feb 23 '16 at 16:31

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.