在嵌入式开发的学习过程中,LED流水灯无疑是一个经典的入门项目,它就像是编程领域的“Hello World”。通过对LED流水灯项目的灵活编程实践,对刚刚入手单片机开发的小白来说无异于打通任督二脉。今天,我们将继续通过Proteus仿真,在上一篇实现独立按键控制切换不同花样流水灯显示效果基础上,深入探究如何利用4个独立按键分别控制LED流水灯实现四种不同的滚动显示效果,从而达到编程的深入理解与能力提升。

        这里直接给出干货,proteus仿真电路和所有程序代码,更多单片机仿真项目学习案例,请搜索并关注小智单片机微信公众号获取工程源文件。这里将使用经典的AT89C51单片机,配合Keil C51开发环境,在Proteus中完成从电路设计到程序编写的全流程实现。此项目代码具有较强移植性,非常方便移植到开发板实物上完成相关流水灯实验。

        该项目实现的目标是制作一个节日彩灯控制器,通过按下不同按键控制8个LED发光二极管的显示规律,在P1.0-P1.3引脚上接4个按键K1-K4,8个LED连接P2端口,按键按下功能如下:

  1. K1按下时,D1-D4与D5-D8交替点亮。
  2. K2按键按下时,D1/D3/D5/D7与D2/D4/D6/D8交替点亮显示。
  3. K3按键按下时,彩灯从上到下正向点亮显示。
  4. 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 程序完整版,请收藏点赞本文并搜索关注微信公众号:小智单片机,自动回复“流水灯四”获取完整工程资源链接。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐