2026-08-08 周五 · LED 驱动练习
2026-08-08
技术
嵌入式 — LED 控制练习(STC8G)
今天在 Keil 里写了 5 个 C 程序,全部基于 STC8G 单片机,通过 P3 口控制 LED:
| 程序 | 功能 | 关键技术 |
|---|---|---|
| Running_LED | 3 个 LED 流水灯(正序 + 逆序) | sbit 位定义,软件延时 |
| Strobe_LED | 单 LED 频闪(10ms 间隔) | P3 |= (1<<7) 直接操作端口寄存器 |
| Strobe_LED + Buzzer | 频闪 + 无源蜂鸣器同时工作 | 两个 sbit 分别控制不同引脚 |
| Breathing_LED | 呼吸灯 — 定时器中断产生 PWM | Timer0 中断,cnt < pwm 比较输出 |
| Breathing_LED2 | 呼吸灯 — 纯软件延时版 | 双层 for 循环,渐亮 + 渐暗 |
核心代码片段
流水灯(正序 + 逆序来回):
while (1) {
// 正序:LED1→LED2→LED3
LED1 = 1; LED2 = 0; LED3 = 0; delay_ms(200);
LED1 = 0; LED2 = 1; LED3 = 0; delay_ms(200);
LED1 = 0; LED2 = 0; LED3 = 1; delay_ms(200);
// 逆序:LED3→LED2→LED1
LED1 = 0; LED2 = 0; LED3 = 1; delay_ms(200);
LED1 = 0; LED2 = 1; LED3 = 0; delay_ms(200);
LED1 = 1; LED2 = 0; LED3 = 0; delay_ms(200);
}
呼吸灯 — 软件 PWM 原理:
// 定时器每 0.1ms 中断一次
LED = (cnt < pwm) ? 1 : 0; // cnt < pwm 时亮,否则灭
if (++cnt >= 100) { // 100 级为一个完整周期
cnt = 0;
if (++cycle >= 5) { // 每 5 个周期改一次占空比
cycle = 0;
if (dir) { if (++pwm >= 100) dir = 0; } // 渐亮
else { if (--pwm == 0) dir = 1; } // 渐暗
}
}
PWM 原理:通过调节亮/灭的时间比例(占空比)实现 LED 亮度的平滑变化。
pwm值从 0 到 100 再到 0,对应 LED 从灭到最亮再到灭。
寄存器配置笔记
// P3 口推挽输出
P3M0 |= 0x80; // P37 推挽输出(0x80 = 1000 0000)
P3M1 &= ~0x80;
// 定时器 0 配置
AUXR |= 0x80; // 12T 模式
TMOD = 0x01; // 定时器 0,16 位模式
TH0 = 0xFB; TL0 = 0xB4; // 0.1ms 定时初值
ET0 = 1; EA = 1; TR0 = 1; // 开中断,启动定时器
Rust
今天没写 Rust。
明日计划
周末(周六、周日)休息,不安排学习任务。
思考
周五到周日休息,无深入思考。这三天给自己留白——之前聊到的"持续运行不等于持续成长",休息本身就是成长的一部分。