1.3 流水灯实验
学习目标:掌握延时函数设计、循环移位操作,实现 8 颗 LED 依次点亮的流水灯效果。
实验原理
流水灯思想
8 颗 LED 依次点亮再熄灭,形成"流水"视觉效果。实现方法:
- 输出模式字:控制 P1 口输出特定电平组合
- 延时:每步之间延时一段时间(如 200ms),人眼才能分辨
- 循环:不断循环移位,形成动态效果
流水模式
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和判断语句处理
实验任务
- 实现 8 颗 LED 从 P1.0 到 P1.7 依次点亮的流水灯
- 扩展:实现"反向流水"(从 P1.7 到 P1.0)
- 扩展:实现"呼吸灯"效果(提示:需用 PWM 思想,改变占空比)
考核点 / 验收标准
| 考核项 | 验收标准 | 分值 |
|---|---|---|
| 延时函数 | 能正确编写延时函数并理解时间计算 | 25 |
| 流水实现 | 8 颗 LED 实现流水效果(循环移位或查表) | 30 |
| 速度调节 | 能通过修改延时参数调节流水速度 | 20 |
| 代码规范 | 代码注释清晰、命名规范 | 25 |
实操要求:现场实现"反向流水"(P1.7→P1.0)。