彻底玩转LED流水灯系列之(三)-独立按键控制流水灯四种花样滚动显示:基于Keil5+Proteus仿真全解析
本文介绍了一个基于51单片机的LED流水灯控制项目,通过独立按键实现四种不同的LED滚动显示效果。项目使用了AT89C51单片机,LED连接到P2口,按键连接到P3.0端口。通过按键控制LED的显示模式,包括从上到下依次点亮、从下到上依次点亮、交替闪烁和两两一组交替点亮。程序通过定时器和中断实现延时和状态切换,确保按键操作的实时响应。代码详细解析了按键扫描、延时函数和主循环中的模式切换逻辑,帮助初
在嵌入式开发的学习过程中,LED流水灯无疑是一个经典的入门项目,它就像是编程领域的“Hello World”。今天,我们将通过Proteus仿真,在上一篇实现从上到下从下到上双向流水灯滚动的基础上,深入探究如何利用独立按键控制LED流水灯实现四种不同的滚动显示效果。
这个项目不仅能够帮助初学者更好地理解单片机的基本操作,还能让大家掌握如何通过按键实现功能切换,为后续的复杂项目打下坚实的基础。这里直接给出干货,proteus仿真电路和所有程序代码,更多单片机仿真项目学习案例,请搜索并关注小智单片机微信公众号获取工程源文件。
这里将使用经典的AT89C51单片机,配合Keil C51开发环境,在Proteus中完成从电路设计到程序编写的全流程实现。此项目代码具有较强移植性,非常方便移植到开发板实物上完成相关流水灯实验。
一、具体电路连接如下:

二、电路工作原理
电源部分:5V电源为整个系统提供能量。LED通过限流电阻连接到VCC,当单片机引脚输出低电平时,形成电流通路,LED点亮。
时钟电路:12MHz晶振与两个30pF电容构成振荡电路,为单片机提供稳定的时钟信号,决定程序执行的速度和定时器的计时基准。
复位电路:上电时,电容充电过程会在RST引脚产生一个短暂的高电平脉冲,使单片机复位,程序从起始位置开始执行。
LED控制:当P2端口的某个引脚输出低电平(0)时,对应的LED两端形成电位差,电流流过LED使其发光;输出高电平(1)时,LED两端电位接近,没有电流,LED熄灭。
按键控制:按键与P3.0端口连接,当按键按下时,检测P3.0端口为低电平,通过检测端口电平判断按键是否按下。
三、程序设计原理与代码解析
3.1 程序源码如下:
#include <reg51.h> //引用头文件
#define uchar unsigned char //宏定义
#define uint unsigned int //宏定义
sbit key = P3^0; // 定义按键连接的P3.0端口
uchar key_flag = 0; // 按键标志位,用于记录按键按下次数
uchar led_state = 0; // LED状态变量,用于控制LED的显示模式
uchar led_data = 0x00; // LED数据变量,用于存储LED的点亮状态
bit key_pressed = 0; // 按键按下标志位
void delay(uint z) // 延时函数
{
uint x, y;
for(x=z; x>0; x--)
for(y=110; y>0; y--);
}
void key_scan() // 按键扫描函数
{
if(key == 0) // 检测按键是否按下
{
delay(20); // 消抖延时
if(key == 0) // 再次确认按键是否按下
{
key_pressed = 1; // 设置按键按下标志位
while(!key); // 等待按键释放
}
}
else
{
key_pressed = 0; // 清除按键按下标志位
}
}
void main() //主函数
{
key = 1; // 初始化按键端口为高电平
while(1)
{
key_scan(); // 调用按键扫描函数
if(key_pressed) // 如果按键被按下
{
key_flag++; // 按键标志位加1
key_pressed = 0; // 清除按键按下标志位
}
switch(key_flag % 4) // 根据按键标志位的值切换LED显示模式
{
case 0: // 模式0:从上到下依次点亮
if(led_state < 8)
{
led_data = 1 << led_state; // 设置LED数据
P2 = ~led_data; // 输出到P2口,点亮对应的LED
delay(500); // 延时
led_state++; // LED状态变量加1
}
else
{
led_state = 0; // 重置LED状态变量
led_data = 0x00; // 清空LED数据
P2 = ~led_data; // 关闭所有LED
}
break;
case 1: // 模式1:从下到上依次点亮
if(led_state < 8)
{
led_data = 1 << (7 - led_state); // 设置LED数据
P2 = ~led_data; // 输出到P2口,点亮对应的LED
delay(500); // 延时
led_state++; // LED状态变量加1
}
else
{
led_state = 0; // 重置LED状态变量
led_data = 0x00; // 清空LED数据
P2 = ~led_data; // 关闭所有LED
}
break;
case 2: // 模式2:交替闪烁
if(led_state == 0)
{
led_data = 0x55; // 设置LED数据,点亮第1、3、5、7个LED
P2 = ~led_data; // 输出到P2口
delay(500); // 延时
led_state = 1; // 改变LED状态变量
}
else
{
led_data = 0xAA; // 设置LED数据,点亮第2、4、6、8个LED
P2 = ~led_data; // 输出到P2口
delay(500); // 延时
led_state = 0; // 改变LED状态变量
}
break;
case 3: // 模式3:两两一组交替点亮
if(led_state == 0)
{
led_data = 0x33; // 设置LED数据,点亮第1、2、5、6个LED
P2 = ~led_data; // 输出到P2口
delay(500); // 延时
led_state = 1; // 改变LED状态变量
}
else
{
led_data = 0xCC; // 设置LED数据,点亮第3、4、7、8个LED
P2 = ~led_data; // 输出到P2口
delay(500); // 延时
led_state = 0; // 改变LED状态变量
}
break;
}
}
}
3.2 关键代码解析
让我们深入分析程序的关键部分:
1、#include <reg51.h>:包含51单片机的头文件,该文件定义了51单片机的特殊功能寄存器(如P0、P1、P2、P3等端口),以及一些其他与硬件相关的定义。这是编写基于51单片机的C语言程序时必须包含的头文件。
宏定义:uchar和uint分别定义为unsigned char和unsigned int,这是为了简化代码,使代码更简洁易读。
2、sbit key = P3^0;:定义了一个特殊功能位变量key,它对应于P3.0端口,用于检测按键是否被按下。uchar key_flag = 0;:定义了一个无符号字符变量key_flag,用于记录按键按下的次数。每次按键按下时,该变量会增加。
uchar led_state = 0;:定义了一个无符号字符变量led_state,用于控制LED的显示模式。它在不同的模式下有不同的作用。
uchar led_data = 0x00;:定义了一个无符号字符变量led_data,用于存储LED的点亮状态。通过改变这个变量的值,可以控制哪些LED点亮。
bit key_pressed = 0;:定义了一个位变量key_pressed,用于标记按键是否被按下。当按键被按下时,该变量被设置为1;当按键释放时,该变量被清除。
3、按键扫描函数:void key_scan():功能:检测按键是否被按下,并在按键按下时设置标志位。原理:首先检查key是否为0(低电平,表示按键被按下)。如果按键被按下,调用delay(20)进行消抖处理,以避免误判。再次确认按键是否仍然被按下,如果是,则设置key_pressed标志位为1,并等待按键释放。如果按键未被按下,则清除key_pressed标志位。
4、 主函数:功能:主函数负责初始化按键端口,并在无限循环中调用按键扫描函数,根据按键次数切换LED的显示模式。
原理:首先将按键端口key初始化为高电平。无限循环:在while(1)循环中,不断调用key_scan()函数来检测按键状态。按键处理:如果检测到按键被按下(key_pressed为1),则增加key_flag的值,并清除key_pressed标志位。模式切换:根据key_flag % 4的值,切换不同的LED显示模式:
模式0:从上到下依次点亮LED。通过左移操作1 << led_state来控制LED的点亮顺序。
模式1:从下到上依次点亮LED。通过右移操作1 << (7 - led_state)来控制LED的点亮顺序。
模式2:交替闪烁。通过设置led_data为0x55和0xAA来控制LED的闪烁模式。
模式3:两两一组交替点亮。通过设置led_data为0x33和0xCC来控制LED的点亮模式。
四、实验结果及现象

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




所有评论(0)