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

基于ATMEGA328P使用TIMER1实现3路LED秒级二进制计数求助

实现方案

核心调整思路

  • 首先配置3颗LED对应IO为输出,这里选择PORTB的PB1、PB2、PB3引脚连接3颗LED,和原有PB0的LED功能不冲突。
  • 你当前的TIMER1配置完全可用:1MHz主频下预分频64,每秒计数正好是15625次,和你代码里写的判断阈值匹配,不需要修改定时器参数。
  • 新增3位计数变量led_cnt,每次TIMER1计数满1秒时变量自增,到8时自动清零,实现0-7的二进制循环。
  • 每次计数更新后,将计数变量的低3位输出到对应LED引脚即可。

提示:如果你的LED是共阳接法,输出电平需要取反,代码里对应输出行做对应修改即可。

完整可运行代码

#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 1000000UL 

// 原代码定义的溢出计数变量,未使用可自行删除
volatile uint8_t overflow0;
volatile uint8_t overflow1;
// 新增3颗LED的计数变量
volatile uint8_t led_cnt = 0;

void FirstTimer()  // 初始化TIMER0
{
    TCCR0B |= (1<<CS02) | (1<<CS00);  // 预分频1024
    TCNT0 = 0;
}

void SecondTimer() //初始化TIMER1
{
    TCCR1B |= (1<<CS11) | (1<<CS10); // 预分频64
    TCNT1 = 0;
}

int main(void)
{
    // 配置PB0(原5Hz闪烁LED)、PB1/PB2/PB3(3颗计数LED)为输出
    DDRB |= (1 << DDB0) | (1<<DDB1) | (1<<DDB2) | (1<<DDB3);
    
    FirstTimer();
    SecondTimer();
    
    while (1)
    {
        // 原有TIMER0实现的5Hz闪烁功能,完全保留
        if (TCNT0 >= 195)
        {
            PORTB ^= (1 << PORTB0);
            TCNT0 = 0;
        }
        
        // TIMER1实现1秒间隔的3LED二进制计数
        if (TCNT1 >= 15625)
        {
            TCNT1 = 0;
            led_cnt++;
            // 计数到8自动清零,实现0-7循环
            if(led_cnt >= 8)
            {
                led_cnt = 0;
            }
            // 计数输出到PB1-PB3,不影响其他引脚状态
            PORTB = (PORTB & ~(0b111 << 1)) | (led_cnt << 1);
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 11:15:03