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.mzph.cn/news/586722.shtml

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

相关文章

PythonTSK Study for first day (paper read)

HTSK model Study AbstractIntroductionII TSK for high-dimentional datasetIII ResultsA DatesetB AlgorithmC性能评估 Abstract The TSK Fuzzy System with Gaussian membership functions can not address high dimentional datasets, if add softmax function to solve i…

day14--JDK8~17新特性(下):

第18章_JDK8-17新特性&#xff08;下&#xff09; 讲师&#xff1a;尚硅谷-宋红康&#xff08;江湖人称&#xff1a;康师傅&#xff09; 官网&#xff1a;http://www.atguigu.com 6. 新语法结构 新的语法结构&#xff0c;为我们勾勒出了 Java 语法进化的一个趋势&#xff0c…

CSP CCF 202305-1 重复局面 C++满分题解

#include<iostream> using namespace std;int judge(char arr[][64],int m) {int a1;for(int i0;i<m;i){int flag0;for(int j0;j<64;j){if(arr[i][j]!arr[m][j]){flag1;break;}}if(flag0)a;}return a; }int main() {int n;cin>>n;char arr[n][64]; //直接看…

SpringMVC源码解析——DispatcherServlet初始化

在Spring中&#xff0c;ContextLoaderListener只是辅助功能&#xff0c;用于创建WebApplicationContext类型的实例&#xff0c;而真正的逻辑实现其实是在DispatcherServlet中进行的&#xff0c;DispatcherServlet是实现Servlet接口的实现类。Servlet是一个JAVA编写的程序&#…

Nacos 基础篇:Nacos简介、基本概念、基本架构、Standalone单机搭建部署

文章目录 什么是Nacos基本架构逻辑架构及其组件介绍领域模型数据模型服务领域模型配置领域模型 下载目录结构配置启动 什么是Nacos Nacos&#xff1a;(Dynamic) Naming and Configuration Service&#xff0c;动态的服务发现和配置的服务&#xff0c;是一个更易于构建云原生应…

<PDF-Pics> support

If get any questions,email me caohechunhotmail.com

力扣LeetCode第26题 删除有序数组中的重复项

一、题目 给你一个有序数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使每个元素 只出现一次 &#xff0c;返回删除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。 示例 1&#xff1…

[Angular] 笔记 24:ngContainer vs. ngTemplate vs. ngContent

请说明 Angular 中 ngContainer&#xff0c; ngTemplate 和 ngContent 这三者之间的区别。 chatgpt 回答&#xff1a; 这三个在 Angular 中的概念是关于处理和组织视图的。 1. ngContainer&#xff1a; ngContainer 是一个虚拟的 HTML 容器&#xff0c;它本身不会在最终渲染…

WPF+Halcon 培训项目实战(12):WPF导出匹配模板

文章目录 前言相关链接项目专栏运行环境匹配图片WPF导出匹配模板如何了解Halcon和C#代码的对应关系逻辑分析&#xff1a;添加截取ROI功能基类矩形圆形 生成导出模板运行结果&#xff1a;可能的报错你的文件路径不存在你选择的区域的内容有效信息过少 前言 为了更好地去学习WPF…

DFS BFS

用DFS和BFS分别实现 //这边给出DFS的模版 void dfs(int x,int y) {//判断是否到达终点&#xff08;只有给出结束点的时候需要&#xff09; if (x ex && y ey) {if (min_steps > step) {min_steps step;}return;}//给出移动方向int move[4][2] {{0, 1}, {0, -1}…

php学习06-魔术常量

有九个魔术常量它们的值随着它们在代码中的位置改变而改变。例如 LINE 的值就依赖于它在脚本中所处的行来决定。这些特殊的常量不区分大小写&#xff0c;如下&#xff1a; 参考

[Angular] 笔记 20:NgContent

chatgpt: 在Angular中&#xff0c;NgContent是用于内容投影&#xff08;Content Projection&#xff09;的一个重要概念。它允许你在一个组件中插入内容&#xff0c;并将这些内容投影到另一个组件中。 当你在一个组件中使用<ng-content></ng-content>标签时&…

基于轻量级GhostNet模型开发构建生活场景下生活垃圾图像识别系统

轻量级识别模型在我们前面的博文中已经有过很多实践了&#xff0c;感兴趣的话可以自行移步阅读&#xff1a; 《移动端轻量级模型开发谁更胜一筹&#xff0c;efficientnet、mobilenetv2、mobilenetv3、ghostnet、mnasnet、shufflenetv2驾驶危险行为识别模型对比开发测试》 《基…

【用户增长】引言:浅析游戏运营用户增长概念

1 游戏发行运营中的主要职能&#xff1a; ​ 一、发行运营通识l 运营介绍&#xff1a;职能分工、发行运营流程、职业发展能力及要求l 品类认知&#xff1a;行业品类布局、品类用户画像、运营节奏及特性&#xff0c;包含不同品类核心打法及长线运营思路l 海外运营&#xff1a;海…

GO学习记录 —— 创建一个GO项目

文章目录 前言一、项目介绍二、目录介绍三、创建过程1.引入Gin框架、创建main2.加载配置文件3.连接MySQL、redis4.创建结构体5.错误处理、返回响应处理 前言 代码地址 下载地址&#xff1a;https://github.com/Lee-ZiMu/Golang-Init.git 一、项目介绍 1、使用Gin框架来创建项…

论文阅读<Contrastive Learning-based Robust Object Detection under Smoky Conditions>

论文链接&#xff1a;https://openaccess.thecvf.com/content/CVPR2022W/UG2/papers/Wu_Contrastive_Learning-Based_Robust_Object_Detection_Under_Smoky_Conditions_CVPRW_2022_paper.pdf Abstract 目标检测是指有效地找出图像中感兴趣的目标&#xff0c;然后准确地确定它们…

springboot 项目新建流程

一、新建工程 二、工程建好后&#xff0c;在pom文件中加入springboot 依赖 <dependencies><!--SpringBoot启动依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>&l…

python+django在线学习教学辅助作业系统gp6yp

本课题使用Python语言进行开发。基于web,代码层面的操作主要在PyCharm中进行&#xff0c;将系统所使用到的表以及数据存储到MySQL数据库中 技术栈 后端&#xff1a;pythondjango 前端&#xff1a;vue.jselementui 框架&#xff1a;django/flask Python版本&#xff1a;python3.…

RobotFrameWork环境搭建及使用

RF环境搭建 首先安装python并且配置python环境变量pip install robotframeworkpip install robotframework-ride 生产桌面快捷方式 不行换豆瓣源检查一下pip list RF类库和扩展库 标准库 按F5快捷键查询&#xff0c;可以看到rf自带的库不需要额外安装这些标准库在python的 …

DragonEnglish:COCA20000+单词+释义

去年的时候接触到了 COCA20000 单词&#xff0c;对这种给单词特定顺序的方式蛮感兴趣的。因为我当时接触的版本只有单词或者单词释义的版本&#xff0c;所以我直接通过各种方式给它搭配了音标例句发音&#xff0c;然后每100个切割成1份&#xff0c;分成了 202 个文件来学习&…