以下是一个基于 ATmega328P 的定时器溢出中断(Timer Overflow Interrupt)示例代码,使用 Timer1(16位定时器)实现周期性中断,并在中断服务程序(ISR)中翻转LED状态(假设LED连接在 PB5,即Arduino的D13引脚)。
- #include <avr/io.h>
- #include <avr/interrupt.h>
- #define LED_PIN PB5 // Arduino D13 (ATmega328P的PB5)
- void initTimer1() {
- // 1. 设置定时器1为普通模式(Normal Mode),计数到最大值0xFFFF后溢出
- TCCR1A = 0; // 普通模式,无需波形生成
- TCCR1B = 0; // 先停止定时器
- // 2. 设置预分频器(Prescaler)为1024,启动定时器
- // 计算公式:溢出时间 = (65536 / F_CPU) * 分频系数
- // 例如:16MHz时钟,分频1024 → 溢出时间 ≈ 4.096秒
- // 若需更短时间,可设置初始计数值(TCNT1)
- TCCR1B |= (1 << CS12) | (1 << CS10); // 分频1024 (CS12:CS10 = 101)
- // 3. 使能定时器1溢出中断
- TIMSK1 |= (1 << TOIE1);
- // 4. 全局中断使能
- sei();
- }
- // 定时器1溢出中断服务程序
- ISR(TIMER1_OVF_vect) {
- // 翻转LED状态
- PORTB ^= (1 << LED_PIN);
- // 可选:重新加载定时器初值(如需精确周期)
- // TCNT1 = 65536 - (目标计数值);
- }
- int main() {
- // 初始化LED引脚为输出
- DDRB |= (1 << LED_PIN);
- PORTB &= ~(1 << LED_PIN); // 初始状态低电平
- // 初始化定时器1
- initTimer1();
- while (1) {
- // 主循环可执行其他任务
- // 中断会异步触发LED翻转
- }
- }
|