打印
[PIC32/SAM]

ATmega328P 定时器中断不触发

[复制链接]
710|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
配置了定时器溢出中断,但 ISR 就是不执行。已经检查了预分频器和中断使能位,求有经验的朋友指点

使用特权

评论回复
沙发
幸福小强| | 2025-7-22 17:42 | 只看该作者
你应该晒出代码啊

使用特权

评论回复
板凳
幸福小强| | 2025-7-22 17:43 | 只看该作者
以下是一个基于 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翻转
    }
}

使用特权

评论回复
地板
幸福小强| | 2025-7-22 17:43 | 只看该作者
其他定时器:若需更短周期,可使用8位定时器(如Timer0或Timer2),或调整预分频。

CTC模式:通过 OCR1A 设置比较值,触发中断而非溢出(模式更精确)。

使用特权

评论回复
5
lcczg| | 2025-7-25 11:20 | 只看该作者
本帖最后由 lcczg 于 2025-7-25 11:32 编辑

幸福小强的代码可以运行。我在板子上可以看到LED灯在闪烁,闪的比较慢,大概8秒翻转一下。

使用特权

评论回复
6
yiyigirl2014| | 2025-7-27 10:19 | 只看该作者
定时器是很基础的应用,参考一下楼上的代码,或者发出来自己的。

使用特权

评论回复
7
穷得响叮当侠| | 2025-7-28 18:15 | 只看该作者
检查一下你的中断使能代码是否正确,有时候一个小小的错误就可能导致中断无法触发。

使用特权

评论回复
8
暖心小太阳| | 2025-7-28 20:09 | 只看该作者
检查一下你的中断使能代码是否正确,有时候一个小小的错误就可能导致中断不被触发。

使用特权

评论回复
9
probedog| | 2025-7-30 17:04 | 只看该作者
检查中断向量名称

使用特权

评论回复
10
powerantone| | 2025-7-30 17:05 | 只看该作者
中断向量冲突?

使用特权

评论回复
11
classroom| | 2025-7-30 17:06 | 只看该作者
参考ATmega328P数据手册。

使用特权

评论回复
12
stormwind123| | 2025-7-30 17:35 | 只看该作者
在配置定时器寄存器前禁用中断(cli()),配置完成后再启用(sei())。

使用特权

评论回复
13
flycamelaaa| | 2025-7-30 18:05 | 只看该作者
在配置中断前,必须通过sei()指令启用全局中断。若未启用,即使定时器中断已配置,ISR也不会执行。

使用特权

评论回复
14
复古留声机| | 2025-8-2 11:30 | 只看该作者
检查一下是否正确设置了定时器的模式和初始值,有时候设置不当也会导致中断不触发。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5

主题

7

帖子

0

粉丝