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

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

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

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

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

在单片机学习的初期,LED灯的控制是一个基础且重要的实验项目。本文将详细介绍如何通过STC15F2K60S2单片机控制LED灯的点亮和流水灯的实现。通过本文的学习,读者将掌握单片机控制LED灯的基本原理和编程方法。

一、前言

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

二、原理图

基本原理

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

74HC573
可容易看出来,原理图上面的LED灯L1
L8的最右边接了VCC,就是接了电源,我们知道要一个电路形成通路,我们需要有电流,电压,所以很明显在L1L8的左端需要给低电平,就是Q0Q7需要给低电平,LED灯才可以接通,LED才可以亮。在图Q0Q7之前,电路经过了74HC573
74HC573是拥有八路输出的透明锁存器,输出为三态门。当锁存使能端LE为高时,这些器件的锁存对于数据是透明的(也就是说输出同步)。当锁存使能变低时,符合建立时间和保持时间的数据会被锁存。

OE,LE的状态不同,产生的效果不同
OE,LE的状态
从74HC573这个图不难看出,OE端口接了GND,所以我们只需要控制LE为高电平,我们输入什么(D1
D7),输出就是什么(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号