I want to setup a custom frequency(12Hz) and duty cycle (20%) with a 16MHz Arduino Uno (ATMEGA328P).
AVR Calculator yields:
ICR1 = 20833
OCR1A = 4167
I have read a tonne of forums and tuts but for some reason I cannot get this to work.
Below is my code:
void setup()
{
// PB1 is now an output (Pin9 Arduino UNO)
DDRB |= (1 << DDB1);
// PB2 is now an output (Pin10 Arduino UNO)
DDRB |= (1 << DDB2);
// Set PWM frequency/top value
ICR1 = 20833;
// Set PWM duty cycle
OCR1A = 4167;
// Set inverting mode (start low, go high)
TCCR1A |= (1 << COM1A1);
TCCR1A |= (1 << COM1B1);
TCCR1A |= (1 << COM1A0);
TCCR1A |= (1 << COM1B0);
// Set fast PWM Mode
TCCR1A |= (1 << WGM11);
TCCR1B |= (1 << WGM12);
TCCR1B |= (1 << WGM13);
// Set prescaler to 64 and starts PWM
TCCR1B |= (1 << CS10);
TCCR1B |= (1 << CS11);
}
void loop() {
// Refresh PWM frequency
OCR1A = 4167;
}
If someone can help, that would be great!
Thanks,
Dylan
Okay, so I seemed to find the issue. I was not setting up the registers correctly for fast PWM in mode 14 (ATMEGA328P has 15 timer1 modes). After a lot of experimentation and further reading, below is the correct setup for variable frequency and duty cycle. ICR1 denotes the TOP value (controls frequency) and OCR1A gives the switching value (duty cycle).
// ADJUSTABLE VARIABLES
// Strobe frequency
uint16_t timer1Prescaler = 64;
uint8_t strobeFreq = 20,
strobeDutyCycle = 20;
void setup
{
// Set PB1 to be an output (Pin9 Arduino UNO)
DDRB |= (1 << PB1);
// Clear Timer/Counter Control Registers
TCCR1A = 0;
TCCR1B = 0;
// Set non-inverting mode
TCCR1A |= (1 << COM1A1);
// Set fast PWM Mode 14
TCCR1A |= (1 << WGM11);
TCCR1B |= (1 << WGM12);
TCCR1B |= (1 << WGM13);
// Set prescaler to 64 and starts PWM
TCCR1B |= (1 << CS10);
TCCR1B |= (1 << CS11);
// Set PWM frequency/top value
ICR1 = (F_CPU / (timer1Prescaler*strobeFreq)) - 1;
OCR1A = ICR1 / (100 / strobeDutyCycle);
}
void loop()
{
// main loop code
}
NOTE: Clearing the Timer/Counter Control Registers is important when using the Arduino IDE as it does do a little setup behind the scenes before executing the setup() function.