51单片机之LED灯

在这里插入图片描述

51单片机之LED灯

  • 🌴前言:
  • 🏮点亮LED灯的原理
    • 💘点亮你的第一个LED灯
    • 💘点亮你的八个LED灯
  • 📌让LED灯闪烁的原理
    • 🎽 LED灯的闪烁
      • 🏓错误示范1
      • 🏓正确的LED闪烁代码应该是这样:
      • 🏓错误示范2
      • 🏓错误示范3
  • 📞点亮LED流水灯的原理
    • 🤠循环左移函数_crol_()
    • 🤠循环右移函数_cror_()
    • 🤠 LED流水灯
  • ⭕总结

🌴前言:

我们在学习单片机的时候,最好还是以实物的学习为主,因为兴趣是最好的老师,实物的视觉冲突比仿真的效果要更好,每一个系列的开发板由于原理图不同,他们对应的IO口控制的东西就不一样,如果你是使用实物来学习51单片机,在进行软件编程前,一定要学会看原理图,即找到某一个器件是由哪个IO口来控制的。
今天给大家带来点亮LED灯的原理及对应的程序讲解和实物演示效果展示。

🏮点亮LED灯的原理

点亮一个LED灯,我们在初中物理电路中应该就学习过,很简单的电路就可以实现,即一个电阻、一个电源、一个LED灯、一个连通的回路。
在这里插入图片描述
这个电路图相信大家都很容易理解,那在用单片机IO口控制LED灯的点亮原理也是类似,我们看我们板子的的LED模块的原理图:
在这里插入图片描述
我们板子的LED模块一共有8个LED小灯,由P2口的每一个小的IO口控制,由于P2口可以进行位寻址,所以我们可以操作它的每一位,进而控制每一个LED灯的亮灭。

另外观察电路图,他们是共阳的,意思是有共同的正极,我们只需要让每一个LED电路的另一端IO口输出低电平就可以了,因为有上拉电阻(这个电阻的功能是让IO口处于高电平,下次我们在具体的分析),每个小的IO口的初始状态都是高电平,与VCC的电压相同,所以每一个LED的电路没有电压差就不会导通,我们想点亮其中一个,只需要将那一个接的IO口设置为低电平0就可以点亮。

💘点亮你的第一个LED灯

#include<reg52.h>
typedef unsigned int u16;
typedef unsigned char u8;
sbit LED = P2^0;//设置需要点亮的LED灯的IO口int main()
{while(1){LED = 0;//将其设置为低电平,使电路导通}return 0;
}

实物效果演示:

在这里插入图片描述
当我们使用烧录软件把程序烧录进去之后,你会发现此时D1灯亮了,当然你也可以编写一个程序,让他们全亮。

💘点亮你的八个LED灯

点亮一个LED的原理和代码都清楚了,我们来试试点亮8个LED灯吧。

#include<reg52.h>
typedef unsigned int u16;
typedef unsigned char u8;
#define LED P2//将P2口宏定义为LED,增强代码可读性和健壮性int main()
{while(1){LED = 0;//将整个P2口都设置为低电平}return 0;
}

实物演示:

在这里插入图片描述

可以看到和我们预期的一样全部点亮了,当然你也可以分别设置P2口的每个位地址为0,但是这样的话代码量会增加很多。

📌让LED灯闪烁的原理

理解了点亮的原理,控制LED闪烁就非常简单了,你只需要知道,当对应IO口输出高电平的时候LED就会亮,输出低电平的时候就会灭。你可能会这样写:

🎽 LED灯的闪烁

🏓错误示范1

#include<reg52.h>
typedef unsigned int u16;
typedef unsigned char u8;
sbit LED = P2^0;//设置需要点亮的LED灯的IO口int main()
{while(1){LED = 0;//将其设置为低电平,使电路导通LED = 1;将其设置为高电平,使电路截止}return 0;
}

我可以很负责任的告诉你,这段代码的的确确实现了闪烁,但是你会发现,当你去将这段代码通过下载软件下载到板子中时,板子的效果是D1常亮,这是为什么呢?
LED从点亮到熄灭的时间就是程序执行一条语句的实现,计算机的速度是很快的,我们可以使用keil调试来测试一下:
我们设置断点,启动调试,程序执行到LED = 1;时的时间是 0.00038900 0.00038900 0.00038900秒,我们不需要这个时间,我们只需要执行当前语句的时间,我们点击下图左上角RST将时间归0,下图左边调试窗口sec显示的有程序执行到当前语句的时间,你可以手动归0
在这里插入图片描述
此时我们已经成功归0了,接下来执行这条语句。

在这里插入图片描述



在这里插入图片描述

所以执行这条语句的时间是 0.00039 0.00039 0.00039人眼正常的极限分辨率是50hz或60hz,从亮到灭这个过程,频率是一个吓人的数字2500hz大概是,人眼是不可能看到这个变化的过程的,因为实在是太快了!

我们想解决这个问题,就需要自己写一个延时函数

void delay(u16 i)
{while(i--);
}

i为1的时候大概是延时了1us,大家可以自己去调试。

🏓正确的LED闪烁代码应该是这样:

typedef unsigned int u16;
typedef unsigned char u8;
sbit LED =  P2^0;//将P2口宏定义为LED,增强代码可读性和健壮性void delay(u16 i)
{while(i--);
}
int main()
{while(1){LED = 0;//将其设置为低电平,使电路导通delay(50000);//0.5s左右LED = 1;将其设置为高电平,使电路截止delay(50000);//0.5s左右}return 0;

实物演示:

在这里插入图片描述
注意:我们每设置一个状态,都必须延时一段时间,否则从这个状态到另外一个状态太快了,人眼无法观测到前一个状态,就会一直维持那个可以观察到的状态。

🏓错误示范2

看下面代码,试思考其展示结果:

#include<reg52.h>
typedef unsigned int u16;
typedef unsigned char u8;
sbit LED =  P2^0;//将P2口宏定义为LED,增强代码可读性和健壮性void delay(u16 i)
{while(i--);
}
int main()
{while(1){LED = 0;//将其设置为低电平,使电路导通delay(50000);//延时0.5sLED = 1;将其设置为高电平,使电路截止}return 0;
}

实物效果展示:

在这里插入图片描述
可以看到亮的效果,但是看不到灭的效果,这是因为从亮到灭有延时我们可以观察到亮的过程,但是从灭到亮太快了,我们眼睛还没察觉到灭,这个灯就已经亮了。

🏓错误示范3

同样的我们在来看这段代码,思考它的实物效果:

#include<reg52.h>
typedef unsigned int u16;
typedef unsigned char u8;
sbit LED =  P2^0;//将P2口宏定义为LED,增强代码可读性和健壮性void delay(u16 i)
{while(i--);
}
int main()
{while(1){LED = 0;//将其设置为低电平,使电路导通LED = 1;将其设置为高电平,使电路截止delay(50000);}return 0;
}

实物效果展示:

在这里插入图片描述
可以看到,眼睛并没有看见灯亮,这是因为在设置完D1 IO口为高电平后延时了一段0.5s,所以我们可以看到灭的效果,但是延时之后执行LED= 0;LED = 1,由于没有延时,所以我们还没有察觉到灯亮,它就已经熄灭了。

相信现在你应该可以很好的理解LED闪烁的原理了,那如果我们想控制所有的灯点亮闪烁该怎么办呢?你可以这样去写:

#include<reg52.h>
typedef unsigned int u16;
typedef unsigned char u8;
#define LED  P2//将P2口宏定义为LED,增强代码可读性和健壮性void delay(u16 i)
{while(i--);
}
int main()
{while(1){LED = 0;//将其设置为低电平,使电路导通delay(50000);LED = 0xff;将其设置为高电平,使电路截止delay(50000);}return 0;
}

实物效果演示:

在这里插入图片描述

可能又有小伙伴有疑惑了,这个0我可以理解,但是你这个0xff是什么意思呢?P20~P27对应8个小的IO口,一共有8个bit位,把他们都设置为1就是,1111 1111,表示为16进制就是0xff。

如果你不想用十六进制来赋值你还可以使用十进制,但是必须先用计算器把这个值算出来,0xff十进制表示是255。 那样的话代码也可以改成这样:

#include<reg52.h>
typedef unsigned int u16;
typedef unsigned char u8;
#define LED  P2//将P2口宏定义为LED,增强代码可读性和健壮性void delay(u16 i)
{while(i--);
}
int main()
{while(1){LED = 0;//将其设置为低电平,使电路导通delay(50000);LED = 255;将其设置为高电平,使电路截止delay(50000);}return 0;
}

📞点亮LED流水灯的原理

流水灯,顾名思义,就是这些灯看起来像在流水一样,我们的板子里面有八个灯,我们可以设计一个程序让他们依次点亮,但是记得延时,如果没有延时那就是全亮了,因为流动的太快了,就好像他们都一直亮着一样。

我们先来认识两个函数:

🤠循环左移函数_crol_()

这个函数的功能是把一个变量大小的二进制代码进行循环左移,举个例子:
在这里插入图片描述

这个函数有两个参数,第一个参数是需要进行循环左移变量,第二参数是循环左移的次数。

🤠循环右移函数_cror_()

这个函数的功能是把一个变量大小的二进制代码进行循环右移,参数和上面一个函数类似。

这个函数的定义在头文件"intrins.h"中,我们在调用这两个函数时需要加这个#include"intrins.h",双引号可以换为尖括号。

流水灯程序设计思路:

在这里插入图片描述

🤠 LED流水灯

#include"reg52.h"
#include"intrins.h"
typedef unsigned int u16;
typedef unsigned int u8;
#define led P2void delay(u16 i)
{while(i--);
}
int main()
{u8 i;led = 0xfe;//1111 1110while(1){led = 0xfe;delay(25000);//0.25sfor(i = 0;i < 7;++i){led = _crol_(led,1); //0xfe 0x1111 1110 -> 0x1111 1011 0x1110 1111 0x1011 1111delay(25000);//0.25s}for(i = 0;i < 6;++i){led = _cror_(led,1); //0xfe 0x1111 1110 -> 0x1111 1011 0x1110 1111 0x1011 1111delay(25000);//0.25s}}return 0;
}

实物演示效果:

在这里插入图片描述

可能有小伙伴有一些疑惑,为什么第二个循环右移只循环了6次呢?也就是最后一次执行完是0x11111101,这是因为最后一次和初始化重复了,如果执行7次这次D1亮的时间就变成了了0.5秒,和预期不符。当然你也可以通过if条件语句来控制,让其执行7次,效果却不受影响。

⭕总结

这篇博客主要谈到了使用51控制LED的一些状态,如果你有兴趣的话,可以利用proteus仿真,做一个爱心的流水灯送给你的女神哦(开玩笑的)。另外,若本篇博客有任何问题欢迎指出。下面是本篇博客的思维导图:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/232585.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ASP.NET可视化流程设计器源码

源码介绍: ASP.NET可视化流程设计器源码已应用于众多大型企事业单位。拥有全浏览器兼容的可视化流程设计器、表单设计器、基于角色的权限管理等系统开发必须功能&#xff0c;大大为您节省开发时间&#xff0c;是您开发OA.CRM、HR等企事业各种应用管理系统和工作流系统的最佳基…

蓝桥杯练习题(一)

&#x1f4d1;前言 本文主要是【算法】——蓝桥杯练习题&#xff08;一&#xff09;的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是听风与他&#x1f947; ☁️博客首页&#xff1a;CSDN主页听风与他 …

CentOS7部署Kafka

CentOS7部署Kafka 一、部署1、前置条件2、下载与解压3、修改配置4、启动kafka二、使用详解1、创建一个主题2、展示所有主题3、启动消费端接收消息4、生产端发送消息三、代码集成pom.xmlapplication.propertiesKafkaConfiguration.javaKafkaConsumer.javaKafkaProducer.javaVehi…

微服务-OpenFeign-工程案例

Ribbon 前置知识 是NetFlix的开源项目&#xff0c;主要来提供关于客户端的负载均衡能力。从多个服务提供方&#xff0c;选取一个节点发起调用。 Feign:NetFlix,SpringCloud 的第一代LB&#xff08;负载均衡&#xff09;客户端工具包。 OpenFeign:SpringCloud自研&#xff0c…

Windows11 - Ubuntu 双系统及 ROS、ROS2 安装

系列文章目录 前言 一、Windows11 - Ubuntu 双系统安装 硬件信息&#xff1a; 设备名称 DESKTOP-B62D6KE 处理器 13th Gen Intel(R) Core(TM) i5-13500H 2.60 GHz 机带 RAM 40.0 GB (39.8 GB 可用) 设备 ID 7673EF86-8370-41D0-8831-84926668C05A 产品 ID 00331-10000-0000…

58.网游逆向分析与插件开发-游戏增加自动化助手接口-游戏菜单文字资源读取的逆向分析

内容来源于&#xff1a;易道云信息技术研究院VIP课 之前的内容&#xff1a;接管游戏的自动药水设定功能-CSDN博客 码云地址&#xff08;master分支&#xff09;&#xff1a;https://gitee.com/dye_your_fingers/sro_-ex.git 码云版本号&#xff1a;34b9c1d43b512d0b4a3c395b…

R304S 指纹识别模块功能实现示例

1 基本通信流程 1.1 UART 命令包的处理过程 1.2 UART 数据包的发送过程 UART 传输数据包前&#xff0c;首先要接收到传输数据包的指令包&#xff0c;做好传输准备后发送成功应答包&#xff0c;最后才开始传输数据包。数据包主要包括&#xff1a;包头、设备地址、包标识、包长…

app store里面的构建版本在线上传

开发苹果ios应用&#xff0c;无论是用原生开发、用hbuilderx开发还是用其他h5框架开发的app&#xff0c;都需要将打包好的ipa文件上传到app store。 在上架app store的过程中&#xff0c;我们会遇到下图的这样一个问题&#xff1a; 就是它要求我们上传一个构建版本&#xff0c…

opencv期末练习题(5)附带解析

根据R、G、B的值实时修改图像的颜色 import cv2 import numpy as np""" 滑动块调整图像灰度1. 读取图片&#xff0c;并转为灰度图 2. 定义启动滑块和R、G、B滑块 3. 只有启动滑块的值为1时&#xff0c;拖动R、G、B滑块才生效 4. 根据R、G、B的值实时对修改图片的…

【VSCode】关闭双击shift出现搜索

原因 有时候总是手滑按两下shift&#xff0c;每次都会弹出如下图的搜索框&#xff0c;导致很不方便 解决办法 找到该文件 C:\Users\admin\.vscode\extensions\k--kato.intellij-idea-keybindings-1.5.12\package.json&#xff08;admin是自己的用户名&#xff09; 然后关键字…

【大数据面试知识点】Spark中的累加器

Spark累加器 累加器用来把Executor端变量信息聚合到Driver端&#xff0c;在driver程序中定义的变量&#xff0c;在Executor端的每个task都会得到这个变量的一份新的副本&#xff0c;每个task更新这些副本的值后&#xff0c;传回driver端进行merge。 累加器一般是放在行动算子…

基于多反应堆的高并发服务器【C/C++/Reactor】(中)线程池的启动和从线程池中取出一个反应堆实例

一、线程池的启动 &#xff08;主线程&#xff09; // 启动线程池 &#xff08;主线程&#xff09; void threadPoolRun(struct ThreadPool* pool) {/*线程池被创建出来之后&#xff0c;接下来就需要让线程池运行起来&#xff0c;其实就是让线程池里的若干个子线程运行起来*//…

Docker mysql 主从复制

目录 介绍&#xff1a;为什么需要进行mysql的主从复制 主从复制原理&#xff1a; ✨主从环境搭建 主从一般面试问题&#xff1a; 介绍&#xff1a;为什么需要进行mysql的主从复制 在实际的生产中&#xff0c;为了解决Mysql的单点故障已经提高MySQL的整体服务性能&#xff…

python入门,list列表详解

目录 1.list的定义 2.index查找某元素的下标 3.修改 ​编辑 4.插入 ​编辑 5.追加元素 1.append,追加到尾部 2.extend,追加一批元素 ​编辑 6.删除元素 1.del 列表[下标] 2.列表.pop(下标) 3.列表.remove(元素) 7.清空列表 8.统计某一元素在列表内的数量 9.计算…

探索 OceanBase 中图数据的实现

在数据管理和处理的现代环境中&#xff0c;对能够处理复杂数据结构的复杂数据模型和方法的需求从未如此迫切。图数据的出现以其自然直观地表示复杂关系的独特能力&#xff0c;开辟了数据分析的新领域。 虽然 Neo4j 等成熟的图形数据库为处理图形数据提供了强大的解决方案&…

PPT插件-大珩助手-文字整理功能介绍

删空白行 删除文本中的所有空白行 清理编号 删除文本中的段落编号 清理格式 删除文本中的换行、空格符号 清理艺术 删除文本的艺术字效果 清理边距 删除文本框与文字之间的间隙 软件介绍 PPT大珩助手是一款全新设计的Office PPT插件&#xff0c;它是一款功能强大且实…

linux 01 centos镜像下载,服务器

01.使用的版本 国内主要使用的版本是centos 02.centos镜像下载 这里的是centos7 一.阿里云官网地址&#xff1a;https://www.aliyun.com/ 二. -----【文档与社区】 —【镜像站】。 三. 选择centos 四.点击下载链接 五.选择版本 六.选择镜像isos 点击-DVD-下载镜像。

Java技术栈 —— Hadoop入门(一)

Java技术栈 —— Hadoop入门&#xff08;一&#xff09; 一、Hadoop第一印象二、安装Hadoop三、Hadoop解析3.1 Hadoop生态介绍3.1.1 MapReduce - 核心组件3.1.2 HDFS - 核心组件3.1.3 YARN - 核心组件3.1.4 其它组件3.1.4.1 HBase3.1.4.2 Hive3.1.4.3 Spark 一、Hadoop第一印象…

MATLAB插值函数

一、MATLAB插值函数概览 1&#xff09;本节重点介绍的插值函数 MATLAB插值函数适用情况基础句式interp1 函数interp1 主要用于一维数据的插值interp1(x, y, x_interp, ‘linear’); 其中 x 和 y 是已知数据点&#xff0c;x_interp 是要插值的目标点。interp2 函数interp2 用于…

vue3 的内置组件汇总

官方给出的说明&#xff1a; Fragment: Vue 3 组件不再要求有一个唯一的根节点&#xff0c;清除了很多无用的占位 div。Teleport: 允许组件渲染在别的元素内&#xff0c;主要开发弹窗组件的时候特别有用。Suspense: 异步组件&#xff0c;更方便开发有异步请求的组件。 一、fr…