You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ATmega128 PORTB.4 LED每2秒明暗交替及按键触发故障求助

问题排查与代码修正

原代码核心问题

  • 变量复用导致逻辑冲突:同一个cnt变量同时用于2秒计时和PWM周期计数,2秒触发后cnt被重置为0,后续PWM逻辑无法正常循环。
  • PWM控制逻辑错误:仅在2秒触发的单次中断里修改LED状态和duration,没有在每次定时器中断中持续执行PWM输出逻辑,导致LED只会保持点亮状态。
  • 外部中断冗余判断:中断触发时已经对应按键电平,无需再判断PIND.x,且缺少按键消抖处理,可能引发误触发。

修正后的代码

#include <mega128.h>
#include <delay.h>

unsigned char direction = 0;
// 分离计时变量:timer2sec_cnt负责2秒周期计数,pwm_cnt负责PWM周期计数
unsigned int timer2sec_cnt = 0;
unsigned int pwm_cnt = 0;
unsigned int duration = 10; // 初始暗态占空比
const unsigned int MAX_PWM = 1000; // PWM周期总数
const unsigned int TIMER_2SEC_CNT = 62500; // 2秒对应的中断次数(匹配你的时钟配置)

interrupt [EXT_INT0] void ext_int0_isr(void)
{
    // 软件消抖:延时后再次确认按键电平
    delay_ms(20);
    if (PIND.0 == 1)
    {
        direction = 1;
    }
}

interrupt [EXT_INT1] void ext_int1_isr(void)
{
    delay_ms(20);
    if (PIND.1 == 1)
    {
        direction = 2;
    }
}

interrupt [TIM0_COMP] void time0_comp_isr(void)
{
    if (direction == 1)
    {
        // 处理2秒周期的占空比切换
        if (timer2sec_cnt++ >= TIMER_2SEC_CNT)
        {
            timer2sec_cnt = 0;
            // 交替切换duration值,实现亮暗交替
            duration = (duration == 10) ? 999 : 10;
        }
        
        // 每次中断都执行PWM亮度控制
        if (pwm_cnt < duration)
        {
            PORTB = 0x10; // LED点亮
        }
        else
        {
            PORTB = 0x00; // LED熄灭
        }
        
        // PWM周期计数循环
        if (pwm_cnt++ >= MAX_PWM)
        {
            pwm_cnt = 0;
        }
    }
    else
    {
        PORTB = 0x00;
        // 停止计时,重置计数变量
        timer2sec_cnt = 0;
        pwm_cnt = 0;
    }
}

void main(void)
{   
    DDRB = 0xff;
    DDRD = 0x00; 
    PORTD = 0xff; // 使能按键上拉电阻
    
    // 外部中断配置:INT0、INT1上升沿触发
    EIMSK |= 0x03;
    EICRA |= 0x0f;
    
    // 定时器0配置:CTC模式,分频64
    TIMSK |= 0x02; // 使能比较匹配中断
    TCCR0 = 0x0B; // 直接赋值替代两次或运算,避免冗余
    OCR0 = 15;    // 比较值
    
    SREG.7 = 1; // 全局中断使能
    
    for(;;);
}

关键修正点说明

  • 变量分离:用timer2sec_cnt专门计数2秒周期,pwm_cnt负责PWM周期循环,彻底解决变量复用的逻辑冲突。
  • PWM持续执行:每次定时器中断都执行LED状态判断,保证duration的占空比能持续控制LED亮度。
  • 周期切换逻辑:仅在2秒到达时切换duration的值,实现每2秒亮暗交替的需求。
  • 按键消抖:在外部中断中加入短延时后再次检测按键电平,避免抖动导致的误触发。
  • 定时器配置优化:直接赋值TCCR0替代两次或运算,代码更简洁清晰。

内容的提问来源于stack exchange,提问作者halli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 08:45:02