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,可通过调整参数改变流水速度。

编译与烧录

  1. 使用Keil C51新建工程,选择芯片型号AT89C52或STC89C52,将上述代码保存为main.c并加入工程。
  2. 编译生成HEX文件:Project → Target → Create HEX File。
  3. 使用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()函数参数,数值越大速度越慢。