问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

蓝桥杯单片机基础学习:LED灯点亮与流水灯实现

创作时间:
作者:
@小白创作中心

蓝桥杯单片机基础学习:LED灯点亮与流水灯实现

引用
CSDN
1.
https://blog.csdn.net/2201_75616203/article/details/137757108

在单片机开发中,无论是C51单片机还是STM32单片机,第一个项目通常是点灯。本文将详细介绍如何通过单片机控制LED灯的亮灭,包括点亮一盏LED灯和实现流水灯效果。

一、前言

关于单片机的开发,无论是C51单片机还是STM32单片机,或者其他类型的单片机。我们开发的第一个项目都是点灯,所以我们先进行点灯入门
单片机的学习最基础就是要会看开发板的原理图和型号的手册说明
这是两个很重要的资料,在蓝桥杯的比赛中,需要完成客观题,有时候客观题就是在这两个资料里面出的,所以笔者建议在学习的时候要经常查看这两个资料。
在这LED灯这个程序学习中,我们暂时不需要看手册,但是需要用到原理图

二、原理图

基本原理

在开发板上,LED灯是L1~L8,在原理图上对于就是这个

74HC573

可容易看出来,原理图上面的LED灯L1L8的最右边接了VCC,就是接了电源,我们知道要一个电路形成通路,我们需要有电流,电压,所以很明显在L1L8的左端需要给低电平,就是Q0Q7需要给低电平,LED灯才可以接通,LED才可以亮。在图Q0Q7之前,电路经过了74HC573

74HC573是拥有八路输出的透明锁存器,输出为三态门。当锁存使能端LE为高时,这些器件的锁存对于数据是透明的(也就是说输出同步)。当锁存使能变低时,符合建立时间和保持时间的数据会被锁存。

OE,LE的状态不同,产生的效果不同

OE,LE的状态

从74HC573这个图不难看出,OE端口接了GND,所以我们只需要控制LE为高电平,我们输入什么(D1D7),输出就是什么(Q0Q7)

在74HC573这个图中LE端口是连接了Y4C,Y4C连接的是74HC138译码器

74HC138译码器

74HC138译码器:三路输入控制八路互斥的低有效输出

三路输入为A0,A1,A2,用二进制控制输入启动

三路输入

在74HC138译码器原理图上面看出来,我们是只需要控制Y4~Y7即可。

所以我们只需要控制P25,P26,P27就可以控制74HC138译码器。

原理总结

单片机要通过74HC573锁存器控制LED灯,锁存器受74HC138译码器控制,而译码器受P25,P26,P27引脚控制。

三、代码实现功能

1、点亮一个LED灯


#include <STC15F2K60S2.H>  
void main()  
{  
    //选择锁存器通道4  
    P2 = (P2 & 0x1f) | 0x80;  
//    P2^0 = 0;  
//    P2^1 = 0;  
//    P2^2 = 0;  
//    P2^3 = 0;  
//    P2^4 = 0;  
//    P2^5 = 0;  
//    P2^6 = 0;  
//    P2^7 = 1;  
    //L1灯点亮  
    P0 = ~0x01; //0111 1111  
}  

(1)配置锁存器通道

通过上面是三路输入的图可以知道,我们要设置锁存器的4通道,需要设置P25=0,P26=0,P27=1三个引脚,我们可以直接写成


P2^5 = 0;  
P2^6 = 0;  
P2^7 = 1;  

但是再后面的程序中我们不只是用到一个锁存器通道,如果每一个都这么配置,一个是我们代码复杂化,难以表达,一个是单片机cpu运行了不必要的数据,大大影响效率。所以我们这里通过与或运算,把关于P2端口配置设置为P2 = (P2 & 0x1f) | 0x80;

& :X(任何数字)& 1(代表真)=1;

|:X(任何数字)| 0(代表假) = 0;

所以不难看出P2 = (P2 & 0x1f) | 0x80相当于

P2^0 = 0;

P2^1 = 0;

P2^2 = 0;

P2^3 = 0;

P2^4 = 0;

P2^5 = 0;

P2^6 = 0;

P2^7 = 1;

这样可以大大减少代码数量。

(2)控制LED灯亮灭


//L1灯点亮  
P0 = ~0x01;//1111 1110  

在上面提到,我们要L1灯亮,则需要配置P00引脚为低电平,这样电路才可以通,L1灯才可以亮,

所以关于P0引脚的配置是1111 1110(高位在左,低位在右),除了第一位为0,其他都为1。

二进制换成十六进制是每四位二进制数为一个十六进制数的一位,所以1111 1110就是F E。

~:取反 ~0x01 = 0xFE

所以实现点亮一个LED灯,只需要


#include <STC15F2K60S2.H>  
void main()  
{  
    P2 = (P2 & 0x1f) | 0x80;  
    P0 = ~0x01;  
}  

2、流水灯


#include <STC15F2K60S2.H>  
#include <intrins.H>  
sbit A0 = P2^5;  
sbit A1 = P2^6;  
sbit A2 = P2^7;  
unsigned char i;  
void Delay100ms(void)    //@11.0592MHz  
{  
    unsigned char data i, j, k;  
    _nop_();  
    _nop_();  
    i = 5;  
    j = 52;  
    k = 195;  
    do  
    {  
        do  
        {  
            while (--k);  
        } while (--j);  
    } while (--i);  
}  
void main()  
{  
    while(1)  
    {  
        A0 = 0;  
        A1 = 0;  
        A2 = 1;  
        for(i = 0;i < 8;i++)  
        {  
            P0 = ~(0x01 << i);  
            Delay100ms();  
        }  
    }  
}  

这个就是笔者上面提到的直接配置P25=0,P26=0,P27=1三个引脚,也可以这样配置

(1)流水灯形成

流水灯就是相隔的LED灯在一定时间内,依次点亮,L1亮,一段时间后灭,紧接着L2灯亮,L1灯灭,一段时间后,L3灯亮,L2灯灭......所以我们先要设置这个“一段时间”

一段时间就是我们的延时函数,在控制LED,数码管 延时都是不可缺少的。

我们可以在STC-ISP上面配置我们需要的延时函数

在上面一段,我们找到软件延时计算器,通过选择系统频率,定时长度,8051指令集进行函数选择,在8051指令集中,不同单片机型号是不一样的延时,一般选择STC-Y5

这里我们就选择100ms的延时函数,nop()是一个空指令函数,在头文件声明一个#include <intrins.H>即可。

(2)LED灯依次点亮

要依次点亮,最简单的方法就是使用循环,我们需要点亮8盏灯,所以就需要使用for(i = 0;i < 8;i++)循环8次,然后在每一盏灯亮灭交替时,我们延时一段时间,就可以实现流水灯。


for(i = 0;i < 8;i++)  
{  
    P0 = ~(0x01 << i);  
    Delay100ms();  
}  

使用P2 = (P2 & 0x1f) | 0x80,笔者把这个想法放在这里,给读者提供参考


#include <STC15F2K60S2.H>  
#include <intrins.H>  
unsigned char i;  
void Delay100ms(void)    //@11.0592MHz  
{  
    unsigned char data i, j, k;  
    _nop_();  
    _nop_();  
    i = 5;  
    j = 52;  
    k = 195;  
    do  
    {  
        do  
        {  
            while (--k);  
        } while (--j);  
    } while (--i);  
}  
void main()  
{  
    P2 = (P2 & 0x1f) | 0x80;  
    while(1)  
    {  
        for(i = 0;i < 8;i++)  
        {  
            P0 = ~(0x01 << i);  
            Delay100ms();  
        }  
    }  
}  
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号