✅ 新的跑马灯程序已写好、编译、烧录,正在运行!
程序说明
| 项目 |
内容 |
| 工程 |
「跑马灯-来回扫描」 |
| 效果 |
单个亮点从P6.0 走到 P6.7,再折返回来,来回往复 |
| 速度 |
250ms/步(改 SPEED_MS 宏即可调速) |
| 实现 |
Timer0 1ms 节拍驱动,主循环空转——非阻塞,随时可加别的任务 |
| 体积 |
773 字节 / ROM 0.59% |
| 状态 |
✅ 已烧录,running |
和之前例程 01.1/01.2 的区别:那些是单方向循环 + 阻塞延时;这个是来回折返 + 中断定时,代码也更干净。板子上现在应该能看到亮点左右往复。
需要调速、改成两个亮点追逐、或全部点亮滚动等效果,说一声就改。
但问题是:一开始只亮了最右边一个灯!
在对话框中输入只亮了最右边一个灯

他会继续思考
✅ 问题找到并修复了,跑马灯现在正常运行!
根因(一个隐藏得很深的坑)
你之前看到"只有一个灯亮"——是因为我写的 Timer0 中断函数里有一句提前 return:
if(++ms_count < SPEED_MS) return; // ← 这句
STC IDE 的编译器把这条路径编译成了普通 RET 而不是 RETI(看汇编发现的:022F: 22 RET):
RET 不清除中断标志 → 中断控制器认为中断还在执行,后续中断全部进不来;
- 中断入口压栈的 6 个寄存器也没弹出来 → 每 1ms 堆栈错乱 6 字节 → 几十毫秒内程序崩溃,灯就卡死在第一个。
修复:ISR 改成单出口(把移动逻辑包进 if(++ms_count >= SPEED_MS){...}),不再提前 return,汇编里只剩一条 RETI。
验证结果
- SWD 读变量确认:暂停读
led_index = 5 → 运行 → 6 → 5,来回折返 ✓;
- 全片下载 + 运行,状态 running ✓;
- 板子上现在应该看到:一个亮点在 8 个 LED 之间左右往复(设计 250ms/步)。
以后我写的中断代码都会避开这个"ISR 提前 return"的坑。
现在看一下板子,速度合适吗?如果太快/太慢,告诉我实际感觉,我调 SPEED_MS 就行