I wanted to generate a high-resolution PWM (15-bit) output on the Port#9 of an UNO Arduino board. I used the following code, but it gives me a couple of warnings an no pulse train on the port:
Here is the code:
// Arduino UNO PWM Frequency and Resolution Adjustment (Port 9)
const int pwmPin = 9;
void setup() {
pinMode(pwmPin, OUTPUT);
// Configure Timer1 for PWM on pins 9 and 10.
// We'll focus on pin 9.
// 1. Disable interrupts during configuration.
cli();
// 2. Set Timer1 Control Registers (TCCR1A and TCCR1B).
// WGM13, WGM12, WGM11, WGM10 bits control the Waveform Generation Mode.
// We'll use mode 14 (Fast PWM, ICR1 top).
// COM1A1, COM1A0 bits control the Output Compare mode for pin 9 (OC1A).
// COM1B1, COM1B0 bits control the Output Compare mode for pin 10 (OC1B).
// CS12, CS11, CS10 bits control the Clock Select bits for the prescaler.
// Set WGM13 and WGM12 to 1, WGM11 and WGM10 to 1 for mode 14 (Fast PWM, ICR1 top).
// Set COM1A1 to 1, COM1A0 to 0 for non-inverting PWM on pin 9.
// Set COM1B1 and COM1B0 to 0 for normal port operation on pin 10.
TCCR1A = _BV(COM1A1) | _BV(WGM11) | _BV(WGM10);
// Set WGM13 to 1, WGM12 to 1 for mode 14 (Fast PWM, ICR1 top).
// Set CS10 to 1 for no prescaling.
TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10);
// 3. Set the Top value for Timer1 (ICR1).
// Frequency = Clock / (Prescaler * (1 + ICR1))
// 1000 Hz = 16,000,000 Hz / (1 * (1 + ICR1))
// ICR1 = (16,000,000 / 1000) - 1
// ICR1 = 15999
ICR1 = 15999; // Set the top value for 1000 Hz.
// 4. Set the Output Compare Register A (OCR1A) for the duty cycle.
// 16-bit resolution means values from 0 to 65535. However, since we set ICR1 to 15999,
// the max value should be 15999.
// Example for 50% duty cycle:
OCR1A = 7999; // 50% duty cycle (15999 / 2)
// 5. Re-enable interrupts.
sei();
}
void loop() {
// You can change the duty cycle here if needed.
// Example for 25% duty cycle:
//OCR1A = 3999;
// delay(1000); // Change duty cycle once per second for testing.
}

