1

As told in this post:

http://forum.arduino.cc/index.php/topic,16612.0.html#

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() {
 analogWrite(output,127);
}

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.

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

1 Answer 1

1

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().

answered Feb 22, 2016 at 15:59
3
  • 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 Commented Feb 22, 2016 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. Commented Feb 23, 2016 at 1:30
  • Tested, it works just fine. Commented Feb 23, 2016 at 16:31

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.