Skip to content

1.3 流水灯实验 ​

学习目标:掌握延时函数设计、循环移位操作,实现 8 颗 LED 依次点亮的流水灯效果。

实验原理 ​

流水灯思想 ​

8 颗 LED 依次点亮再熄灭,形成"流水"视觉效果。实现方法:

  1. 输出模式字:控制 P1 口输出特定电平组合
  2. 延时:每步之间延时一段时间(如 200ms),人眼才能分辨
  3. 循环:不断循环移位,形成动态效果

流水模式 ​

8 颗 LED 接在 P1 口,低电平点亮:

P1 = 1111 1110 (0xFE)  →  P1.0 亮
P1 = 1111 1101 (0xFD)  →  P1.1 亮
P1 = 1111 1011 (0xFB)  →  P1.2 亮
...依次循环

电路设计 ​

与 1.2 类似,但 P1.0~P1.7 各接一颗 LED + 限流电阻:

AT89C51
┌──────┐     ┌──[R0]──[LED0]──┐
│ P1.0 ├─────┤                │
│ P1.1 ├─────┼──[R1]──[LED1]──┤  ...共8路
│ P1.2 ├─────┤                │   全部接 VCC
│  ... │     │                │
│ P1.7 ├─────┼──[R7]──[LED7]──┘
└──────┘

程序设计 ​

方法一:循环移位(推荐) ​

c
/****************************************************
 * 实验名称:流水灯——循环移位法
 ****************************************************/
#include <reg51.h>

// 软件延时函数,约延时 x ms(12MHz 晶振)
void delay(unsigned int ms)
{
    unsigned int i, j;
    for (i = ms; i > 0; i--)
        for (j = 120; j > 0; j--);
}

void main(void)
{
    unsigned char led = 0xFE;   // 初始:P1.0 亮

    while (1)
    {
        P1 = led;               // 输出到 P1 口
        delay(200);             // 延时 200ms
        led = (led << 1) | 0x01; // 左移一位,低位补 1(熄灭)
        if (led == 0xFF)        // 已全部熄灭(移完一圈)
            led = 0xFE;         // 重新从 P1.0 开始
    }
}

方法二:数组查表 ​

c
#include <reg51.h>

void delay(unsigned int ms)
{
    unsigned int i, j;
    for (i = ms; i > 0; i--)
        for (j = 120; j > 0; j--);
}

// 流水模式字表
code unsigned char table[] = {
    0xFE, 0xFD, 0xFB, 0xF7,
    0xEF, 0xDF, 0xBF, 0x7F
};

void main(void)
{
    unsigned char i;
    while (1)
    {
        for (i = 0; i < 8; i++)
        {
            P1 = table[i];     // 依次输出模式字
            delay(200);
        }
    }
}

关键知识点 ​

知识点说明
code 关键字将数组定义到程序存储区(ROM),节省 RAM
延时函数通过循环嵌套消耗 CPU 时间,实现软件延时
移位运算<< 左移,`
端口输出P1 = 0xFE; 一次输出 8 位电平

延时时间计算(12MHz 晶振) ​

  • 51 单片机 1 个机器周期 = 12 个时钟周期 = 1µs
  • for (j=120; j>0; j--); 约需 120 × 5µs ≈ 600µs
  • 外层 i 次循环,总延时 ≈ ms × 1ms(近似)

常见问题 ​

Q1:流水灯太快/太慢?

  • 调整 delay() 的参数值即可
  • 参数越大延时越长,速度越慢

Q2:移到最后一位后出错?

  • 循环移位法要注意判断移完一圈后重置
  • 建议用数组查表法,逻辑更清晰

Q3:unsigned char 溢出?

  • led << 1 后高位移出丢失,配合 | 0x01 和判断语句处理

实验任务 ​

  1. 实现 8 颗 LED 从 P1.0 到 P1.7 依次点亮的流水灯
  2. 扩展:实现"反向流水"(从 P1.7 到 P1.0)
  3. 扩展:实现"呼吸灯"效果(提示:需用 PWM 思想,改变占空比)

考核点 / 验收标准 ​

考核项验收标准分值
延时函数能正确编写延时函数并理解时间计算25
流水实现8 颗 LED 实现流水效果(循环移位或查表)30
速度调节能通过修改延时参数调节流水速度20
代码规范代码注释清晰、命名规范25

实操要求:现场实现"反向流水"(P1.7→P1.0)。

aioteer · 物联网专业课程群

💬AI 伴学配置