彻底玩转LED流水灯系列之(四)-4个独立按键控制8个LED四种花样显示:基于Keil5+Proteus仿真全解析
本文介绍了基于51单片机的LED流水灯控制系统实现方法。通过Proteus仿真和Keil C51开发环境,使用4个独立按键控制8个LED实现四种不同显示效果:高低4位交替、奇偶位交替、正向流水和反向流水。详细讲解了电路设计(电源、时钟、复位、LED和按键电路)及程序实现原理,包括按键扫描、LED控制函数和延时函数。程序通过检测P1端口电平判断按键状态,调用相应LED显示函数控制P2端口输出。文章还
在嵌入式开发的学习过程中,LED流水灯无疑是一个经典的入门项目,它就像是编程领域的“Hello World”。通过对LED流水灯项目的灵活编程实践,对刚刚入手单片机开发的小白来说无异于打通任督二脉。今天,我们将继续通过Proteus仿真,在上一篇实现独立按键控制切换不同花样流水灯显示效果基础上,深入探究如何利用4个独立按键分别控制LED流水灯实现四种不同的滚动显示效果,从而达到编程的深入理解与能力提升。
这里直接给出干货,proteus仿真电路和所有程序代码,更多单片机仿真项目学习案例,请搜索并关注小智单片机微信公众号获取工程源文件。这里将使用经典的AT89C51单片机,配合Keil C51开发环境,在Proteus中完成从电路设计到程序编写的全流程实现。此项目代码具有较强移植性,非常方便移植到开发板实物上完成相关流水灯实验。
该项目实现的目标是制作一个节日彩灯控制器,通过按下不同按键控制8个LED发光二极管的显示规律,在P1.0-P1.3引脚上接4个按键K1-K4,8个LED连接P2端口,按键按下功能如下:
- K1按下时,D1-D4与D5-D8交替点亮。
- K2按键按下时,D1/D3/D5/D7与D2/D4/D6/D8交替点亮显示。
- K3按键按下时,彩灯从上到下正向点亮显示。
- K4按键按下时,彩灯由下到上反向点亮显示。
一、具体电路连接如下:

二、电路工作原理
电源部分:5V电源为整个系统提供能量。LED通过限流电阻连接到VCC,当单片机引脚输出低电平时,形成电流通路,LED点亮。
时钟电路:12MHz晶振与两个30pF电容构成振荡电路,为单片机提供稳定的时钟信号,决定程序执行的速度和定时器的计时基准。
复位电路:上电时,电容充电过程会在RST引脚产生一个短暂的高电平脉冲,使单片机复位,程序从起始位置开始执行。
LED控制:当P2端口的某个引脚输出低电平(0)时,对应的LED两端形成电位差,电流流过LED使其发光;输出高电平(1)时,LED两端电位接近,没有电流,LED熄灭。
按键控制:按键与P1端口连接,当按键按下时,检测端口为低电平,通过检测端口电平判断按键是否按下。
三、程序设计原理与代码解析
3.1 程序源码如下:
#include <reg51.h> // 包含51单片机的头文件,用于访问单片机的特殊功能寄存器
// 定义按键连接的P1端口引脚
sbit K1 = P1^0; // 按键K1连接到P1.0引脚
sbit K2 = P1^1; // 按键K2连接到P1.1引脚
sbit K3 = P1^2; // 按键K3连接到P1.2引脚
sbit K4 = P1^3; // 按键K4连接到P1.4引脚
unsigned char keyval; // 定义键值存储变量单元,用于存储按键对应的值
// 延时函数
void led_delay(void)
{
unsigned char i, j; // 定义循环变量
for (i = 0; i < 220; i++) // 外层循环
for (j = 0; j < 220; j++); // 内层循环,通过两层循环消耗时间实现延时
}
// 高4位与低4位交替点亮的函数
void LedFlow1(void)
{
P2 = 0x0f; // P2端口低4位输出低电平,高4位输出高电平,点亮低4位LED
led_delay(); // 调用延时函数
P2 = 0xf0; // P2端口高4位输出低电平,低4位输出高电平,点亮高4位LED
led_delay(); // 调用延时函数
}
// 奇数位与偶数位交替点亮的花样显示
void LedFlow2(void)
{
P2 = 0x55; // P2端口奇数位输出低电平,偶数位输出高电平,点亮奇数位LED
led_delay(); // 调用延时函数
P2 = 0xaa; // P2端口偶数位输出低电平,奇数位输出高电平,点亮偶数位LED
led_delay(); // 调用延时函数
}
// 正向流水灯点亮显示效果
void LedFlow3(void)
{
unsigned char i; // 定义循环变量
unsigned char led_state = 0xfe; // 初始状态,从左到右依次点亮LED,0xfe表示第一个LED点亮
for (i = 0; i < 8; i++) // 循环8次,点亮8个LED
{
P2 = led_state; // 设置P2端口的值,控制LED的点亮状态
led_delay(); // 调用延时函数,使LED保持点亮状态一段时间
led_state = (led_state << 1) | 0x01; // 左移一位,并在最低位补1,实现下一个LED点亮的效果
}
}
// 反向流动的流水灯效果
void LedFlow4(void)
{
unsigned char i; // 定义循环变量
unsigned char led_state = 0x7f; // 初始状态,从右到左依次点亮LED,0x7f表示第一个LED点亮
for (i = 0; i < 8; i++) // 循环8次,点亮8个LED
{
P2 = led_state; // 设置P2端口的值,控制LED的点亮状态
led_delay(); // 调用延时函数,使LED保持点亮状态一段时间
led_state = (led_state >> 1) | 0x80; // 右移一位,并在最高位补1,实现下一个LED点亮的效果
}
}
// 按键扫描函数
void key_scan(void)
{
P1 = 0xFF; // 将P1端口所有位设置为高电平
if ((P1 & 0x0F) != 0x0F) // 检测P1端口低4位是否有按键按下
{
if (K1 == 0) // 检测按键K1是否被按下(低电平表示按下)
keyval = 1; // 如果K1按下,设置keyval为1
if (K2 == 0)
keyval = 2; // 如果K2按下,设置keyval为2
if (K3 == 0)
keyval = 3; // 如果K3按下,设置keyval为3
if (K4 == 0)
keyval = 4; // 如果K4按下,设置keyval为4
}
}
// 主函数
void main(void)
{
keyval = 0; // 初始化keyval为0
while (1) // 无限循环
{
key_scan(); // 调用按键扫描函数
switch (keyval) // 根据keyval的值选择对应的LED显示效果
{
case 1: LedFlow1(); break; // 如果keyval为1,执行LedFlow1
case 2: LedFlow2(); break; // 如果keyval为2,执行LedFlow2
case 3: LedFlow3(); break; // 如果keyval为3,执行LedFlow3
case 4: LedFlow4(); break; // 如果keyval为4,执行LedFlow4
}
}
}
3.2 编程原理介绍
这段代码实现了一个基于51单片机的LED流水灯控制系统,通过4个独立按键控制8个LED灯实现四种不同的显示效果。程序的核心逻辑是通过按键扫描函数检测按键状态,并根据按键值调用对应的LED显示函数。
按键扫描函数key_scan通过读取P1端口的电平状态,判断哪个按键被按下,并设置对应的keyval值。主函数main中不断调用按键扫描函数,并通过switch语句根据keyval的值选择执行不同的LED显示函数。每个LED显示函数通过控制P2端口的高低电平来实现不同的LED点亮效果,延时函数led_delay用于控制LED点亮的时间,使效果更明显。Led1Flow实现高4位与低4位交替点亮,LedFlow2实现奇数位与偶数位交替点亮,LedFlow3实现从左到右的流水灯效果,LedFlow4实现从右到左的流水灯效果。
程序结构清晰,易于理解和扩展,在你移植到开发板上时,尤其注意开发板上的按键连接单片机的端口和LED小灯连接的单片机端口,如果跟本程序不同,要把程序中的这几句及时更改,
// 定义按键连接的P1端口引脚
sbit K1 = P1^0; // 按键K1连接到P1.0引脚
sbit K2 = P1^1; // 按键K2连接到P1.1引脚
sbit K3 = P1^2; // 按键K3连接到P1.2引脚
sbit K4 = P1^3; // 按键K4连接到P1.4引脚
- 实验结果及现象




到这里整个实验过程就结束了,文中给出了详细的电路设计和代码编写,并深入阐述了实现原理,下一篇将在此篇基础上实现心形流水灯的变换仿真制作过程,敬请期待《彻底玩转LED流水灯系列》的后续文章!如果需要本篇的proteus工程源文件和Keil 程序完整版,请收藏点赞本文并搜索关注微信公众号:小智单片机,自动回复“流水灯四”获取完整工程资源链接。
更多推荐




所有评论(0)