[PIC32/SAM] ATmega328P 定时器中断不触发

[复制链接]
 楼主| 四十四次日落 发表于 2025-7-20 18:45 | 显示全部楼层 |阅读模式
配置了定时器溢出中断,但 ISR 就是不执行。已经检查了预分频器和中断使能位,求有经验的朋友指点
幸福小强 发表于 2025-7-22 17:42 | 显示全部楼层
你应该晒出代码啊
幸福小强 发表于 2025-7-22 17:43 | 显示全部楼层
以下是一个基于 ATmega328P 的定时器溢出中断(Timer Overflow Interrupt)示例代码,使用 Timer1(16位定时器)实现周期性中断,并在中断服务程序(ISR)中翻转LED状态(假设LED连接在 PB5,即Arduino的D13引脚)。
  1. #include <avr/io.h>
  2. #include <avr/interrupt.h>

  3. #define LED_PIN    PB5   // Arduino D13 (ATmega328P的PB5)

  4. void initTimer1() {
  5.     // 1. 设置定时器1为普通模式(Normal Mode),计数到最大值0xFFFF后溢出
  6.     TCCR1A = 0; // 普通模式,无需波形生成
  7.     TCCR1B = 0; // 先停止定时器

  8.     // 2. 设置预分频器(Prescaler)为1024,启动定时器
  9.     // 计算公式:溢出时间 = (65536 / F_CPU) * 分频系数
  10.     // 例如:16MHz时钟,分频1024 → 溢出时间 ≈ 4.096秒
  11.     // 若需更短时间,可设置初始计数值(TCNT1)
  12.     TCCR1B |= (1 << CS12) | (1 << CS10); // 分频1024 (CS12:CS10 = 101)

  13.     // 3. 使能定时器1溢出中断
  14.     TIMSK1 |= (1 << TOIE1);

  15.     // 4. 全局中断使能
  16.     sei();
  17. }

  18. // 定时器1溢出中断服务程序
  19. ISR(TIMER1_OVF_vect) {
  20.     // 翻转LED状态
  21.     PORTB ^= (1 << LED_PIN);

  22.     // 可选:重新加载定时器初值(如需精确周期)
  23.     // TCNT1 = 65536 - (目标计数值);
  24. }

  25. int main() {
  26.     // 初始化LED引脚为输出
  27.     DDRB |= (1 << LED_PIN);
  28.     PORTB &= ~(1 << LED_PIN); // 初始状态低电平

  29.     // 初始化定时器1
  30.     initTimer1();

  31.     while (1) {
  32.         // 主循环可执行其他任务
  33.         // 中断会异步触发LED翻转
  34.     }
  35. }
幸福小强 发表于 2025-7-22 17:43 | 显示全部楼层
其他定时器:若需更短周期,可使用8位定时器(如Timer0或Timer2),或调整预分频。

CTC模式:通过 OCR1A 设置比较值,触发中断而非溢出(模式更精确)。
lcczg 发表于 2025-7-25 11:20 | 显示全部楼层
本帖最后由 lcczg 于 2025-7-25 11:32 编辑

幸福小强的代码可以运行。我在板子上可以看到LED灯在闪烁,闪的比较慢,大概8秒翻转一下。
yiyigirl2014 发表于 2025-7-27 10:19 | 显示全部楼层
定时器是很基础的应用,参考一下楼上的代码,或者发出来自己的。
穷得响叮当侠 发表于 2025-7-28 18:15 | 显示全部楼层
检查一下你的中断使能代码是否正确,有时候一个小小的错误就可能导致中断无法触发。
暖心小太阳 发表于 2025-7-28 20:09 | 显示全部楼层
检查一下你的中断使能代码是否正确,有时候一个小小的错误就可能导致中断不被触发。
probedog 发表于 2025-7-30 17:04 | 显示全部楼层
检查中断向量名称
powerantone 发表于 2025-7-30 17:05 | 显示全部楼层
中断向量冲突?
classroom 发表于 2025-7-30 17:06 | 显示全部楼层
参考ATmega328P数据手册。
stormwind123 发表于 2025-7-30 17:35 | 显示全部楼层
在配置定时器寄存器前禁用中断(cli()),配置完成后再启用(sei())。
flycamelaaa 发表于 2025-7-30 18:05 | 显示全部楼层
在配置中断前,必须通过sei()指令启用全局中断。若未启用,即使定时器中断已配置,ISR也不会执行。
复古留声机 发表于 2025-8-2 11:30 | 显示全部楼层
检查一下是否正确设置了定时器的模式和初始值,有时候设置不当也会导致中断不触发。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5

主题

10

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部