#include <avr/io.h>
#include <avr/interrupt.h>
#define LED_PIN PB1 // Assuming you're using PB1 for the LED
volatile uint16_t cycle_time_ms = 500; // Total cycle time in milliseconds
volatile uint16_t ramp_up_time_ms; // Time for ramping up in milliseconds
volatile uint16_t ramp_down_time_ms; // Time for ramping down in milliseconds
volatile uint8_t brightness = 0; // Current brightness level
volatile uint8_t direction = 1; // Ramp direction: 1 for ramping up, 0 for ramping down
volatile uint16_t ramp_interval = 10; // Interval for changing brightness, in milliseconds
void init_PWM() {
// Set PB1 (Arduino pin 9) as output
DDRB |= (1 << DDB1);
// Configure Timer1 for PWM generation, phase-correct mode
TCCR1A |= (1 << COM1A1) | (1 << WGM11);
TCCR1B |= (1 << WGM13) | (1 << CS10); // Prescaler 1
// Set PWM frequency to 976.5625 Hz (16000000 / (1 * 510))
ICR1 = 255; // TOP value for 8-bit PWM
// Enable Timer1 overflow interrupt
TIMSK1 |= (1 << TOIE1);
}
// Timer1 overflow interrupt handler
ISR(TIMER1_OVF_vect) {
static uint16_t time_counter = 0;
time_counter += ramp_interval;
if (time_counter >= cycle_time_ms) {
time_counter = 0;
// Update brightness level based on ramp direction
if (direction) {
brightness++;
if (brightness >= 255) {
direction = 0; // Change direction to ramp down
}
} else {
brightness--;
if (brightness == 0) {
direction = 1; // Change direction to ramp up
}
}
}
// Update PWM duty cycle
OCR1A = brightness;
}
int main() {
init_PWM();
// Enable global interrupts
sei();
while (1) {
// Do nothing, let the interrupt handle the ramping
}
return 0;
}