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.
-
For 100kHz, you need to use a fast PWM mode, with a TOP specified by OCRxA,Dave X– Dave X2016年02月21日 22:48:16 +00:00Commented Feb 21, 2016 at 22:48
-
1arduino.stackexchange.com/a/19553/6628 has an exellent answer. You do need the smaller /1 prescaler though.Dave X– Dave X2016年02月22日 15:15:28 +00:00Commented Feb 22, 2016 at 15:15
1 Answer 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().
-
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 outputLuis Ramon Ramirez Rodriguez– Luis Ramon Ramirez Rodriguez2016年02月22日 21:38:50 +00:00Commented Feb 22, 2016 at 21:38
-
1Yes, 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– Dave X2016年02月23日 01:30:18 +00:00Commented Feb 23, 2016 at 1:30
-
Tested, it works just fine.Luis Ramon Ramirez Rodriguez– Luis Ramon Ramirez Rodriguez2016年02月23日 16:31:01 +00:00Commented Feb 23, 2016 at 16:31