51单片机从零到实战(2)——流水灯
·
第 2 篇:流水灯——从 1 个 LED 到 8 个 LED
上一篇你点亮了 1 个 LED。这篇来点好玩的——8 个 LED 排队跑起来。
1. 硬件连接
把 8 个 LED 的负极分别接到 P1.0 ~ P1.7,每个 LED 的正极通过 220Ω 电阻接 VCC。
VCC ── 220Ω ── LED0 ── P1.0
VCC ── 220Ω ── LED1 ── P1.1
VCC ── 220Ω ── LED2 ── P1.2
...
VCC ── 220Ω ── LED7 ── P1.7
2. 位操作——sbit 关键字
sbit LED0 = P1^0; // 把 P1.0 这个引脚命名为 LED0
sbit LED1 = P1^1;
sbit LED2 = P1^2;
// ... 以此类推
// 现在你可以单独控制每个 LED:
LED0 = 0; // P1.0 输出低电平 → LED0 亮
LED0 = 1; // P1.0 输出高电平 → LED0 灭
3. 单灯左移流水灯
#include <reg52.h>
void delay(unsigned int ms) {
unsigned int i, j;
for (i = ms; i > 0; i--)
for (j = 120; j > 0; j--);
}
void main() {
unsigned char led = 0xFE; // 1111 1110 → 只有 P1.0 亮
while (1) {
P1 = led;
delay(200);
// 左移一位
led = (led << 1) | 0x01;
// 0xFE << 1 = 0xFC → 1111 1100
// 0xFC | 0x01 = 0xFD → 1111 1101
// 效果:亮的那个灯往左移动一个位置
if (led == 0xFF) // 移到最左边了
led = 0xFE; // 回到最右边,重新开始
}
}
4. 更多流水灯特效
来回流水灯(乒乓灯)
unsigned char led = 0xFE;
char dir = 1; // 1 = 左移, -1 = 右移
while (1) {
P1 = led;
delay(100);
if (led == 0x7F) dir = -1; // 碰到最左边,回头
if (led == 0xFE) dir = 1; // 碰到最右边,回头
if (dir == 1)
led = (led << 1) | 0x01; // 左移
else
led = (led >> 1) | 0x80; // 右移
}
跑马灯(4 个灯一起跑)
unsigned char led = 0xF0; // 高 4 位亮,低 4 位灭 → 1111 0000
while (1) {
P1 = led;
delay(200);
led = ~led; // 取反 → 0000 1111 → 低 4 位亮,高 4 位灭
// 再取反 → 1111 0000 → ... 来回交替
}
5. 用数组存花样——更优雅的写法
unsigned char code patterns[] = {
0xFE, 0xFD, 0xFB, 0xF7, // 单灯右移
0xEF, 0xDF, 0xBF, 0x7F,
0x7F, 0xBF, 0xDF, 0xEF, // 单灯左移(回)
0xF7, 0xFB, 0xFD, 0xFE,
0x00, 0xFF, 0x00, 0xFF, // 全亮全灭 ×2
};
void main() {
unsigned char i;
while (1) {
for (i = 0; i < sizeof(patterns); i++) {
P1 = patterns[i];
delay(150);
}
}
}
code 关键字把数组存到 Flash(程序存储器),不占用宝贵的 512 字节 RAM。
6. 知识点总结
sbit让一个引脚变成一个变量名,操作更直观<<和>>是左移/右移运算符,流水灯的核心~是按位取反,0 变 1、1 变 0code关键字把常量存 Flash,省 RAM- 用数组存花样,代码简洁漂亮
下一篇:按键——让单片机"听话"
下一篇:按键——让单片机"听话"
更多推荐



所有评论(0)