当前位置: 首页 > news >正文

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仿真,做一个爱心的流水灯送给你的女神哦(开玩笑的)。另外,若本篇博客有任何问题欢迎指出。下面是本篇博客的思维导图:

在这里插入图片描述

相关文章:

51单片机之LED灯

51单片机之LED灯 &#x1f334;前言&#xff1a;&#x1f3ee;点亮LED灯的原理&#x1f498;点亮你的第一个LED灯&#x1f498;点亮你的八个LED灯 &#x1f4cc;让LED灯闪烁的原理&#x1f3bd; LED灯的闪烁&#x1f3d3;错误示范1&#x1f3d3;正确的LED闪烁代码应该是这样&am…...

操作系统内存碎片

大家好&#xff0c;我叫徐锦桐&#xff0c;个人博客地址为www.xujintong.com&#xff0c;github地址为https://github.com/jintongxu。平时记录一下学习计算机过程中获取的知识&#xff0c;还有日常折腾的经验&#xff0c;欢迎大家访问。 一、前言 内存碎片是指无法被利用的内…...

三菱plc学习入门(二,三菱plc指令,触点比较,计数器,交替,四则运算,转换数据类型)

今天&#xff0c;进行总结对plc的学习&#xff0c;下面是对plc基础的学习&#xff0c;希望对读者有帮助&#xff0c;欢迎点赞&#xff0c;评论&#xff0c;收藏&#xff01;&#xff01;&#xff01; 目录 触点比较 当数据太大了的时候&#xff08;LDD32位&#xff09; CMP比…...

Spring学习之——代理模式

Proxy代理模式 介绍 为其他对象提供一种代理以控制对这个对象的访问。在某些情况下&#xff0c;一个对象不适合或者不能直接引用另一个对象&#xff0c;而代理对象可以在客户端和目标对象之间起到中介的作用 2. 组成 抽象角色&#xff1a;通过接口或抽象类声明真实角色实现的…...

【Linux】之搭建 PostgreSQL 环境

前言 在 Linux 系统下安装 PostgreSQL&#xff0c;可以选择快捷方便的 Docker 安装&#xff0c;但正常的服务器都是直接原生安装的&#xff0c;所以&#xff0c;这里我将讲解如何正常安装 PostgreSQL 以及安装之后的一些配置。如果想了解 Docker 安装的话&#xff0c;可以查看我…...

docker 安装elasticsearch、kibana、cerebro、logstash

安装步骤 第一步安装 docker 第二步 拉取elasticsearch、kibana、cerebro、logstash 镜像 docker pull docker.elastic.co/elasticsearch/elasticsearch:7.10.2 docker pull docker.elastic.co/kibana/kibana:7.10.2 docker pull lmenezes/cerebro:latest docker pull l…...

C/C++ 联合体

目录 联合体概述 联合体的内存分配 联合体大小计算 联合体概述 联合与结构非常的相似&#xff0c;主要区别就在于联合这两个字。 联合的特征&#xff1a;联合体所包含的成员变量使用的是同一块空间。 联合体定义 //联合类型的声明 union Un {char c;int i; }; //联合变量…...

基于SSM的基金投资交易管理网站的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…...

JS数据类型转换成Boolean型

在javaScript中 布尔值用到的很频繁 接下来让我稍微为大家介绍一下数据类型转换为布尔型 转换成布尔值为false的类型 console.log(Boolean("")) //falseconsole.log(Boolean(0)) //falseconsole.log(Boolean(undefined)) //falseconsole.log(Boolean(null)) //false…...

uni-app页面数据传参方式

uni-app 是一个使用 Vue.js 开发所有前端应用的框架&#xff0c;可以编译到 iOS、Android、H5、小程序等多个平台。当你在多个页面间传递参数时&#xff0c;通常有多种方法&#xff0c;例如通过 uni.navigateTo、路由参数、本地存储等方式。下面是一些方法的说明和示例代码。 …...

计算机网络实验(二):Wireshark网络协议分析

一、实验名称&#xff1a;Wireshark网络协议分析 二、实验原理 HTTP协议分析 1.超文本传输协议&#xff08;Hypertext Transfer Protocol, HTTP&#xff09;是万维网&#xff08;World Wide Web&#xff09;的传输机制&#xff0c;允许浏览器通过连接Web服务器浏览网页。目…...

Spark内核解析-数据存储5(六)

1、Spark的数据存储 Spark计算速度远胜于Hadoop的原因之一就在于中间结果是缓存在内存而不是直接写入到disk&#xff0c;本文尝试分析Spark中存储子系统的构成&#xff0c;并以数据写入和数据读取为例&#xff0c;讲述清楚存储子系统中各部件的交互关系。 1.1存储子系统概览 …...

ASP.NET Core高级之认证与授权(一)--JWT入门-颁发、验证令牌

阅读本文你的收获 了解认证和授权的作用了解在ASP.NET Core中实现身份认证的技术都有哪些学习基于JWT认证并学会颁发和验证JWT令牌 一、重要的前置概念 在一个系统中&#xff0c;不是所有的功能和资源都能够被自由地访问&#xff0c;比如你存在银行系统里面的资金&#xff0c…...

实例:NodeJS 操作 Kafka

本人是C#出身的程序员&#xff0c;c#很简单就能实现&#xff0c;有需要的可以加我私聊。但是就目前流行的开发语言&#xff0c;尤其是面向web方向应用的&#xff0c;我感觉就是Nodejs最简单了。下面介绍&#xff1a; 本文将会介绍在windows环境下启动Kafka&#xff0c;并通过n…...

AI实景无人直播创业项目:开启自动直播新时代,一部手机即可实现增长

在当今社会&#xff0c;直播已经成为了人们日常生活中不可或缺的一部分。无论是商家推广产品、明星互动粉丝还是普通人分享生活&#xff0c;直播已经渗透到了各行各业。然而&#xff0c;传统直播方式存在着一些不足之处&#xff0c;如需现场主持人操作、高昂的费用等。近年来&a…...

YOLOv5改进 | 损失函数篇 | InnerIoU、InnerSIoU、InnerWIoU、FocusIoU等损失函数

一、本文介绍 本文给大家带来的是YOLOv5最新改进,为大家带来最近新提出的InnerIoU的内容同时用Inner的思想结合SIoU、WIoU、GIoU、DIoU、EIOU、CIoU等损失函数,形成 InnerIoU、InnerSIoU、InnerWIoU等新版本损失函数,同时还结合了Focus和AIpha思想,形成的新的损失函数,其…...

构建高效PythonWeb:GraphQL+Sanic

1.1 简介&#xff1a;在当今快速发展的技术时代&#xff0c;Web应用的性能和灵活性变得越来越重要。在众多技术中&#xff0c;GraphQL和Sanic以其独特的优势脱颖而出。GraphQL&#xff0c;作为一个强大的数据查询语言&#xff0c;为前端和后端之间的通信提供了极大的灵活性。而…...

【通义千问】大模型Qwen GitHub开源工程学习笔记(5)-- 模型的微调【全参数微调】【LoRA方法】【Q-LoRA方法】

摘要: 训练数据的准备 你需要将所有样本放到一个列表中并存入json文件中。每个样本对应一个字典,包含id和conversation,其中后者为一个列表。示例如下所示: [{"id": "identity_0","conversations": [{"from": "user",…...

PCL 大地坐标转空间直角坐标(C++详细过程版)

目录 一、算法原理二、代码实现三、结果展示四、测试数据本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT生成的文章。 一、算法原理 二、代码实现 头文件及读取保存函数见:PCL 空间直角坐标转大地坐标(直接求解法C…...

Linux之Shell编程

shell是什么 shell是一个命令行解释器&#xff0c;他为用户提供一个向linux内核发送请求以便运行程序的界面系统级程序&#xff0c;用户可以用shell来启动&#xff0c;挂起&#xff0c;停止甚至编写一些程序。 shell脚本的执行方式 脚本格式要求 脚本以#!/bin/bash开头脚本需…...

Android Wi-Fi 连接失败日志分析

1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分&#xff1a; 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析&#xff1a; CTR…...

Appium+python自动化(十六)- ADB命令

简介 Android 调试桥(adb)是多种用途的工具&#xff0c;该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具&#xff0c;其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利&#xff0c;如安装和调试…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

MySQL账号权限管理指南:安全创建账户与精细授权技巧

在MySQL数据库管理中&#xff0c;合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号&#xff1f; 最小权限原则&#xf…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...

return this;返回的是谁

一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请&#xff0c;不同级别的经理有不同的审批权限&#xff1a; // 抽象处理者&#xff1a;审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

基于Java+MySQL实现(GUI)客户管理系统

客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息&#xff0c;对客户进行统一管理&#xff0c;可以把所有客户信息录入系统&#xff0c;进行维护和统计功能。可通过文件的方式保存相关录入数据&#xff0c;对…...

LRU 缓存机制详解与实现(Java版) + 力扣解决

&#x1f4cc; LRU 缓存机制详解与实现&#xff08;Java版&#xff09; 一、&#x1f4d6; 问题背景 在日常开发中&#xff0c;我们经常会使用 缓存&#xff08;Cache&#xff09; 来提升性能。但由于内存有限&#xff0c;缓存不可能无限增长&#xff0c;于是需要策略决定&am…...