0% found this document useful (0 votes)
31 views

PWM Using Atmega328

The document provides instructions for setting up 16-bit pulse-width modulation (PWM) directly on an Arduino Uno or ATmega328 microcontroller without using any libraries. It configures timer 1 for fast PWM mode on pins 9 and 10, sets the top counter value to 65535 for 16-bit resolution, and demonstrates how to vary the duty cycle using the output compare registers OCR1A and OCR1B in a loop.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
31 views

PWM Using Atmega328

The document provides instructions for setting up 16-bit pulse-width modulation (PWM) directly on an Arduino Uno or ATmega328 microcontroller without using any libraries. It configures timer 1 for fast PWM mode on pins 9 and 10, sets the top counter value to 65535 for 16-bit resolution, and demonstrates how to vary the duty cycle using the output compare registers OCR1A and OCR1B in a loop.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 1

HOW TO SET UP 16-BIT PWM WITH AN ARDUINO

UNO / ATMEGA328
No fuss working example:
void setup() {
// Set PB1/2 as outputs.
DDRB |= (1 << DDB1) | (1 << DDB2);

TCCR1A =
(1 << COM1A1) | (1 << COM1B1) |
// Fast PWM mode.
(1 << WGM11);
TCCR1B =
// Fast PWM mode.
(1 << WGM12) | (1 << WGM13) |
// No clock prescaling (fastest possible
// freq).
(1 << CS10);
OCR1A = 0;
// Set the counter value that corresponds to
// full duty cycle. For 15-bit PWM use
// 0x7fff, etc. A lower value for ICR1 will
// allow a faster PWM frequency.
ICR1 = 0xffff;
}

void loop() {
// Use OCR1A and OCR1B to control the PWM
// duty cycle. Duty cycle = OCR1A / ICR1.
// OCR1A controls PWM on pin 9 (PORTB1).
// OCR1B controls PWM on pin 10 (PORTB2).
OCR1A = 0x0000;
delay(500);
OCR1A = 0x8000;
delay(500);
OCR1A = 0xffff;
delay(500);
}

PWM will be on pin 9 running around 250 Hz (16MHz / 2 ^ 16 = 244 Hz). This
assumes you don't care about correct phase, etc. If you do, hit up the data sheet.

This will break any Arduino library functions that depend on TIMER1 (the servo
library, and maybe some other stuff?).

You might also like