3. 流水灯效果
任务目标
使用单片机控制8个LED,实现依次点亮、循环滚动的流水灯效果。核心练习点:循环移位操作与延时控制。
硬件与电路
- MCU:STC89C52(兼容8051)
- 8个LED阳极通过限流电阻接VCC(共阳接法),阴极分别接P1.0~P1.7
- LED点亮条件:对应引脚输出低电平(0)
完整代码(main.c)
#include <reg51.h>
void delay(unsigned int ms) {
unsigned int i, j;
for (i = 0; i < ms; i++)
for (j = 0; j < 123; j++); // 12MHz晶振下约延时1ms
}
void main() {
unsigned char led = 0xFE; // 初始:P1.0亮(1111 1110)
while (1) {
P1 = led; // 输出到LED端口
delay(200); // 延时200ms
led = (led << 1) | 0x01; // 左移一位,最低位置1(熄灭)
if (led == 0xFF) { // 若全部熄灭,则重新从P1.0开始
led = 0xFE;
}
}
}
代码要点
- 共阳接法:0xFE对应二进制1111 1110,即P1.0输出低电平,第一个LED点亮。
- 循环移位:
(led << 1) | 0x01将点亮位向左移动,同时将最低位置1(熄灭),实现“点亮位置右移”的视觉效果。 - 边界处理:当移位后led变为0xFF(全灭)时,重置为0xFE,形成无限循环。
- 延时控制:delay(200)使每个LED点亮持续约200ms,可通过调整参数改变流水速度。
编译与烧录
- 使用Keil C51新建工程,选择芯片型号AT89C52或STC89C52,将上述代码保存为main.c并加入工程。
- 编译生成HEX文件:Project → Target → Create HEX File。
- 使用STC-ISP软件将HEX文件烧录至单片机。
验证方法
接通电源后观察8个LED状态:
- LED从P1.0对应的LED开始点亮,依次向P1.7方向移动。
- 每个LED点亮约200ms后熄灭,下一个LED点亮,形成“流水”滚动效果。
- 当最后一个LED(P1.7)点亮后,下一次循环重新从第一个LED开始,持续往复。
通过标准:8个LED按顺序循环滚动,无跳变、无同时点亮多个LED的情况,速度均匀。
常见问题
- LED不亮:检查LED极性是否接反(共阳接法阳极接VCC),以及P1口是否虚焊。
- 流水方向相反:若希望从P1.7向P1.0方向流动,将初始值改为0x7F,移位改为右移
(led >> 1) | 0x80。 - 速度过快/过慢:调整delay()函数参数,数值越大速度越慢。