以下是一个基于 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翻转
}
}
|