/*
Phase-Correct PWM for a smoother, symmetric waveform
This mode is particularly useful when:
1. You want symmetry in the waveform, like for motor control, analog signal emulation, or reducing harmonics
2. The slight loss in frequency (vs Fast PWM) is acceptable
What Is Phase-Correct PWM?
Unlike Fast PWM, which counts from 0 → 255 and jumps back to 0…
Phase-Correct PWM counts up (0→255) and then back down (255→0) — a full up/down cycle.
1. Slower frequency
2. Symmetric signal edges
3. Works well for motor driver H-bridges, DAC simulation, etc.
*/
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <TinyDebug.h>
#define LED1 PB0 // OC0A
#define LED2 PB1 // OC0B
int main(void) {
Debug.begin();
// Set PB0 and PB1 as outputs
DDRB |= (1 << LED1) | (1 << LED2);
// === Timer0 Setup: Phase-Correct PWM ===
TCCR0A =
(1 << COM0A1) | // Non-inverting PWM on OC0A (PB0)
(1 << COM0B1) | // Non-inverting PWM on OC0B (PB1)
(1 << WGM00); // Phase-Correct PWM mode (WGM00 = 1, WGM01 = 0)
TCCR0B = (1 << CS01); // Prescaler = 8 → slower, stable PWM
// Start with different brightness levels
OCR0A = 0; // ~25% duty 64
OCR0B = 0; // ~75% duty 192
while (1) {
// Optional: smoothly crossfade LEDs
for (uint8_t i = 0; i < 255; i++) {
OCR0A = i;
Debug.print("TCNT0:"); Debug.println(TCNT0);
OCR0B = 255 - i;
_delay_ms(5);
}
}
}