基于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
相关产品推荐
相关产品推荐

