【C51基础实验 LED流水灯】

51单片机项目基础篇

  • LED流水灯
    • 1、硬件电路设计和原理分析
    • 2、软件设计
      • 2.1、利用循环和移位操作符功能实现:LED流水灯
      • 2.2、利用利用封装好的库函数功能实现:LED流水灯
    • 3、编译结果
    • 4、结束语

LED流水灯

前言:
前几篇学会了LED驱动原理,并且成功点亮了一颗LED和实现了LED的闪烁,那么这篇紧接着就来解锁LED的新功能,LED流水灯。当然这里前提是基于肉眼余晖可见光达成的效果。

1、硬件电路设计和原理分析

开发板上 LED 模块电路原理图如下图所示:
在这里插入图片描述
看上图中 LED 采用共阳接法,D1-D8 连接到单片机的 P20-P27 口,即所有LED 阳极管脚接电源 VCC,阴极管脚通过一个 470 欧的限流电阻接到 P2 口上。
原理分析
根据前面篇章 点亮一颗LED 的介绍我们知道,要让 LED 发光即对应的阴极管脚应该为低电平,若为高电平则熄灭。
根据前面篇章 LED闪烁 的介绍我们知道,要让 LED 闪烁,主要引用延时函数。

所以如果要想 51 单片机控制 LED实现流水灯的效果,就必须通过单片机管脚在 P2 口上反复循环的调用寄存器控制对应D1~D8引脚的高低电平,当第一颗LED点亮,则其它LED处于熄灭状态,当第二颗LED点亮时,其它LED处于熄灭状态,同理,其余的LED都是这个逻辑,其次MCU执行程序语句都会有一定的时间,为了达到人肉眼的余晖效应,因此只需编写一个循环函数,让CPU 不干其它事,专门在那循环运行即可实现延时功能。

2、软件设计

程序这边主要介绍两种思路的写法:
(1)、利用循环和移位操作符,实现反复改写对应LED端口高低电平的改写。实验效果:单向流水灯
(2)、利用封装好的库函数:左移_crol_、右移_cror_函数实现流水灯效果。实验效果:双向流水灯

2.1、利用循环和移位操作符功能实现:LED流水灯

//1.利用循环和移位操作符<< >>
/**/
#include <reg52.h>#define LED_PORT	P2//使用宏定义--- P2端口
typedef unsigned int u16;void delay_10us(u16 ten_us)
{while(ten_us--);
}void main()
{int i = 0;//LED_PORT = 0xfe;//LED_PORT = 0x01;while(1){for(i=0;i<8;i++){LED_PORT = ~(0x01<<i);//i=0时,D1灯亮,i++依次点亮//移位后自动补0,当7次移位后,高位的1被移走,低位就自动补0//导致同时会亮两个灯,那么就采取取反操作符。以移动1然后取反来解决移位补0的这个问题delay_10us(50000);}}
}

解释说明
前面章节已经介绍了的内容,这里的 delay_10us延时函数 和 typedef 类型重命名,就一笔带过了。具体参考:前面篇章 点亮一颗LED 的介绍
然后这里简单说一下,#define关键字,是C语言中的一个宏定义预处理指令(“#”开头的均为预处理命令)命令,它用来将一个标识符定义为一个字符串,语法格式如:#define LED_PORT P2,该LED_PORT标识符被称为宏名,被定义的字符串P2称为替换文本。
大概描述一下,主要的作用就是,在遇见大量重复又需要经常改变的参数,常常用宏定义一个新的字符串替换标识符,从而实现便捷的更换程序参数。
最后,主函数main:进入 main 函数后首先定义一个变量 i,然后进入 while 循环,由于要实现 8个 LED 从 D1->D8 循环点亮,因此可以使用 for 循环语句循环 8 次,每循环一次,点亮的小灯向右移动一个,而 D1-D8 是连接到 P2.0-P2.7 的,因此输出的低电平要左移一位,因此可以使用 LED_PORT=~(0x01<<i);语句实现。
主要解释一下,~(0X01<<i):
表示 i 循环 1 次,则0x01 中的 1 就移动多少位。另外,因为 1(高电平)不会让 LED 点亮,需要取反后变为低电平 0 才能点亮,所以最后的结果需要取反后给 LED_PORT 口,并且每次循环都要延时一段时间,这样才能分辨出来 LED 在流水形式显示。
如果不取反这里以二进制表示就是
0000 0001 << 1 得到 0000 0010 左移1位后最低位自动补0,当7次移位后1000 0000,第八次最高位的1被移走,最低位就自动补0,则为0000 0000,又根据开发板的LED硬件原理图,LED 采用共阳接法,给0为亮,所以最后的移位后的值,需要取反使得对应的灯亮,其它灯灭。

2.2、利用利用封装好的库函数功能实现:LED流水灯

//2.利用_crol_库函数
/**/
#include <reg52.h>
#include <intrins.h>
//当调用_cror_右移库函数和_crol_左移库函数时,需调用头文件<intrins.h>
//注意:库函数的移位不会自动补0,是最高位向最低位,进行移位的
//了解函数的参数:extern unsigned char _crol_  (unsigned char, unsigned char);
//第一个参数是移动的值,第二个参数是移动的位数
#define LED_PORT	P2typedef unsigned int u16;
typedef unsigned char u8;void delay_10us(u16 ten_us)
{while(ten_us--);
}void main()
{u8 i = 0;LED_PORT = 0xfe;//1111 1110delay_10us(50000);//LED_PORT = ~0x01;//等价while(1){for(i=0;i<7;i++)//当我们给LED_PORT赋初值,0xfe时,只需要循环7次即可{LED_PORT = _crol_(LED_PORT,1);delay_10us(50000);}//右移同理for(i=0;i<7;i++)//当我们给LED_PORT赋初值,0xfe时,只需要循环7次即可{LED_PORT = _cror_(LED_PORT,1);delay_10us(50000);}}

解释说明
以库函数的写法就相对更简单了,因为只需要会用就行,直接调用已经封装好的左移_crol_、右移_cror_函数,然后查阅对应的用法和参数,以及对应的头文件即可。
以左移_crol_函数为例,其主要作用就是
实现的移位功能就相当于一个队列内循环移动,如果是左移,那么最高位就被移到最低位了,次高位变为最高位,依次类推的循环排列。
最后,主函数main:进入 main 函数后首先定义一个变量 i,LED_PORT=~0x01,因为 LED 是低电平
点亮,所以 0X01 取反后的结果是 0XFE,对应二进制数为 1111 1110,即最低位为 0,因此最开始的 D1 指示灯会点亮,然后进入 while 循环,使用 for 循环_crol_和_cror_移位函数实现 LED 左右流水显示。

注意到的是:此处每个 for 循环只有 7 次,为什么不是 8 次呢,这是因为在进入 main 开始,就已经将 LED_PORT 端口设置了一次状态,即让 D1 点亮,并且我们是想让 LED 从左至右依次点亮,然后继续又从右至左依次点亮,这样形成左右流水效果。
假如将循环次数改为 8 次,我们列举下第一个 for 循环的LED_PORT 端口状态值,如下所示:

初始状态:LED_PORT=1111 1110
i=0:LED_PORT=1111 1101
i=1:LED_PORT=1111 1011
i=2:LED_PORT=1111 0111
i=3:LED_PORT=1110 1111
i=4:LED_PORT=1101 1111
i=5:LED_PORT=1011 1111
i=6:LED_PORT=0111 1111
i=7:LED_PORT=1111 1110

可以很直观的查看到,当i = 7时,再次回到了初始状态的显示,可这里我们是想实现的是:LED从左流动过来,又从右流动回去的流水灯效果。所以,i = 6只需要for循环7次即可。

3、编译结果

至此,两个程序就编写完成,我们编译一下,如下图所示
在这里插入图片描述

从上图编译信息可以看出,我们的代码占用FLASH 大小为:code = 65 字节,所用的 SRAM 大小为:data = 9 个字节(9.0),xdata指是扩展的外部存储XSRAM所占的大小,并没有使用XSRAM所以为0。
在这里插入图片描述
从上图编译信息可以看出,我们的代码占用FLASH 大小为:code = 98 字节,所用的 SRAM 大小为:data = 9 个字节(9.0),xdata指是扩展的外部存储XSRAM所占的大小,并没有使用XSRAM所以为0。

硬件实验效果如图所示

C51基础实验 LED流水灯实验效果展示1

C51基础实验 LED流水灯实验效果展示2

4、结束语

写这篇文章记录作为自己学习的笔记,笔者水平有限,希望有错误的地方还请多多指教,各抒己见交流学习,同时希望笔者的内容有帮助到你。如果有所帮助还请点点赞,表示支持哦。最后感谢各位的阅读(不喜勿喷)。

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

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

相关文章

爬虫逆向实战(二十六)--某某学堂登录

一、数据接口分析 主页地址&#xff1a;某某学堂 1、抓包 通过抓包可以发现数据接口是Account/LoginPost 2、判断是否有加密参数 请求参数是否加密&#xff1f; 通过查看“载荷”模块可以发现pass是加密参数 请求头是否加密&#xff1f; 无响应是否加密&#xff1f; 无co…

【zookeeper】zookeeper集群安装

环境规划 实际的生产使用中&#xff0c;我们一般推荐搭建奇数多节点的zookeeper集群&#xff0c;如3/5/7。在本次测试中&#xff0c;我使用了centos7 三台服务器搭建&#xff0c;复用了我搭建k8s集群的环境&#xff0c;如下表。 IPhostname192.168.2.140k8s-m1192.168.2.141k…

YOLOv5算法改进(7)— 添加SimAM注意力机制

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。SimAM&#xff08;Similarity-based Attention Mechanism&#xff09;是一种基于相似度的注意力机制&#xff0c;它的原理是通过计算查询向量与每个键向量之间的相似度&#xff0c;从而确定每个键向量对于查询向量的重要性…

对HashMap的value做升序、降序

public class MapUtils {// Map的value值降序排序public static <K, V extends Comparable<? super V>> Map<K, V> sortDescend(Map<K, V> map) {List<Map.Entry<K, V>> list new ArrayList<>(map.entrySet());list.sort((o1, o2)…

【高级程序设计语言C++】C++11

1. lambda表达式2. 移动构造函数和移动赋值运算符重载3. default关键字4. delete关键字5. 可变参数模板6. push_back和emplace_back的区别6.1. emplace_back的优势 7. 包装器7.1. 包装器的语法格式 1. lambda表达式 在C中&#xff0c;lambda表达式是一种用于创建匿名函数的语法…

时序预测 | Matlab实现CNN-XGBoost卷积神经网络结合极限梯度提升树时间序列预测

时序预测 | Matlab实现CNN-XGBoost卷积神经网络结合极限梯度提升树时间序列预测 目录 时序预测 | Matlab实现CNN-XGBoost卷积神经网络结合极限梯度提升树时间序列预测效果一览基本描述程序设计参考资料 效果一览 基本描述 时序预测 | Matlab实现CNN-XGBoost卷积神经网络结合极限…

Web安全——信息收集下篇

Web安全 一、网络空间搜索引擎二、扫描敏感目录/文件1、御剑2、7kbstorm3、bbscan4、dirmap5、dirsearch6、gobuster7、网站文件 三、扫描网页备份四、网站头信息收集五、敏感文件搜索1、GitHub搜索2、Google-hacking3、wooyun漏洞库4、网盘搜索5、社工库6、网站注册信息7、js敏…

【Linux操作系统】信号量实现生生产者消费者模型

当涉及到多线程编程时&#xff0c;经常会遇到生产者消费者问题。在Linux系统编程中&#xff0c;我们可以使用信号量来实现生产者消费者模型&#xff0c;以确保线程之间的同步和互斥。 文章目录 什么是生产者消费者问题&#xff1f;使用信号量实现生产者消费者模型信号量的原理信…

java的ide有哪些(含代码示例)

java的ide有哪些(含代码示例 编辑功能编辑功能常用的Java IDE有&#xff1a;Eclipse&#xff1a;Eclipse是一个开放源代码的、基于Java的可扩展开发平台。它提供了强大的代码编辑功能&#xff0c;包括语法高亮显示、自动补全、代码折叠、智能代码导航以及调试功能等。 编辑功…

iPhone 14 Plus与iPhone 14 Pro:你应该买哪一款

又到了iPhone季,这意味着你可能会在几种不同的机型之间左右为难,无法决定买哪一款。更令人困惑的是,苹果推出的iPhone变体——iPhone 14 Plus,只比老款iPhone 14 Pro低100美元。 有这么多选择,你可能想知道哪款iPhone最适合你。你应该买一部大屏幕的iPhone 14 Plus并节省…

Jenkins自动化部署-Jenkins的安装

首先我们需要安装docker 安装 yum-utils包 yum install -y yum-utils \ device-mapper-persistent-data \ lvm2 --skip-broken 设置镜像地址 yum-config-manager \ --add-repo \ https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce…

【ES6】Promise的入门介绍

Promise 是 JavaScript 中的一个对象&#xff0c;用于处理异步操作。Promise 对象代表一个最终可能完成&#xff08;并得到结果&#xff09;或失败&#xff08;并被拒绝&#xff09;的操作&#xff0c;以及其结果的值。 一个 Promise 有三种状态&#xff1a; Pending&#xf…

包含文心一言在内的首批国产大模型 全面开放

8月31起&#xff0c;国内 11 家通过《生成式人工智能服务管理暂行办法》备案的 AI 大模型产品将陆续上线&#xff0c;面向全社会开放。北京 5 家大模型产品分别是百度的 “文心一言”、抖音的 “云雀”、百川智能的 “百川大模型”、清华系 AI 公司智谱华章旗下的 “智谱清言”…

python爬虫入门教程(非常详细):如何快速入门Python爬虫?

示例示例Python爬虫入门教程什么是爬虫爬虫&#xff08;又称网络爬虫&#xff09;是一种按照一定的规则&#xff0c;自动地抓取万维网信息的程序或者脚本。它可以自动地抓取网页内容&#xff0c;并从中提取有用的数据&#xff0c;存储到本地文件或数据库中。 Python爬虫入门教…

vue3 Table 分页保留选中状态

//指定id值,数据更新之后保留之前选中的数据 const getRowKeys (row) > {return row.siteId; }; // 这存的是选中的数据 const userSelectionChange (values) > {state.selectedData [...values]; }; // 两个数组对比&#xff0c;判断表格中的数据是否开启选中 cons…

linux EOF 用法

这篇文章主要讲解了“linux的eof怎么使用”&#xff0c;文中的讲解内容简单清晰&#xff0c;易于学习与理解&#xff0c;下面请大家跟着小编的思路慢慢深入&#xff0c;一起来研究和学习“linux的eof怎么使用”吧&#xff01; linux的eof是自定义终止符&#xff0c;其全称是“E…

chrono学习(一)

我想用chrono进行沙土的仿真&#xff0c;首先学习demo_GPU_ballCosim.cpp&#xff0c;这个例子仿真了一些沙土的沉降过程。 首先&#xff0c;运行编辑完成的文件demo_GPU_ballCosim&#xff1a; (base) eowyneowyn-MS-7D20:~/build_chrono/bin$ ./demo_GPU_ballCosim 运行完得…

编译链接的流程

编译链接的流程 编译链接是将源代码转换为可执行程序的过程&#xff0c;一般包括以下几个步骤&#xff1a; 预处理&#xff08;Preprocessing&#xff09;&#xff1a;预处理器根据以字符 ‘#’ 开头的预处理指令&#xff0c;对源代码进行处理。这些指令可以包括宏定义、头文…

Spring源码分析(十)Bean实例化(下)

目录 1.1 循环依赖1.2 属性填充1.2.1 populateBean方法1.2.2 initializeBean方法执行Aware方法执行BeanPostProcessor后置处理器的前置处理方法执行初始化方法执行BeanPostProcessor后置处理器的后置处理方法&#xff1a;postProcessAfterInitialization()&#xff0c;允许对be…

MySQL数据库基本操作

目录 一、数据库中常用的数据类型 二、常用命令与操作 1.DDL数据库定义语言 1、登录用户的数据库 2、查看当前服务器中的数据库 3、切换/进入数据库 并 查看数据库中包含的表 4、查看数据库中表的结构 5、创建数据库 7、展示创建数据表时的结构 8、创建表&#xff0c…