【C51基础实验 LED流水灯】

news2024/9/22 21:13:32

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	P2

typedef 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 1110
	delay_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.coloradmin.cn/o/959139.html

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

相关文章

Nano编辑器安装使用指南

关于nano Nano编辑器是一个命令行文本编辑器&#xff0c;具有简单易用的界面和一些基本功能。 Nano小巧友好&#xff0c;提供许多额外的特性&#xff0c;例如交互式的查找和替换、定位到指定的行列、自动缩进、特性切换、国际化支持、文件名标记完成等。 Nano是为了代替闭源的…

Benchmarking Chinese Text Recognition: Datasets, Baselines| OCR 中文数据集【论文翻译】

基础信息如下 https://arxiv.org/pdf/2112.15093.pdfhttps://github.com/FudanVI/benchmarking-chinese-text-recognition Abstract 深度学习蓬勃发展的局面见证了近年来文本识别领域的迅速发展。然而&#xff0c;现有的文本识别方法主要针对英文文本。作为另一种广泛使用的语…

携程 2024秋招内推 火热进行中!

携程 2024秋招 内推火热进行中&#xff01;~ 公司简介:携程校园招聘是为携程集团招募和培养未来的技术专家、业务骨干、管理人员的培训生成长项目。进入携程后&#xff0c;公司会为每位培训生量身拟定双轨四维驱动培养计划&#xff0c; 施行双通道成长模式&#xff0c;可自由选…

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

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

Yao框架浏览器打开后Cannot read properties of undefined (reading ‘search‘)

Yao创建项目后浏览器打开报 undefined 错误&#xff0c;是因为 Yao 框架语言包的问题&#xff0c;只支持浏览器的【中文&#xff08;简体&#xff09;】【英语&#xff08;美国&#xff09;】&#xff0c;如果浏览器排第一的语言不是这两个就会出现这个错误。临时解决方案是在浏…

这个 AI 机器人会怼人,它是怎么做到的?

近期&#xff0c;机器人“Ameca”接入了 Stable Diffusion&#xff0c;它一边与旁边的人类工程师谈笑风生&#xff0c;一边熟练地用马克笔在白板上画出一只简笔的猫&#xff0c;最后还在白板右下角签名。 当 Ameca 询问工程师是否对它的作品是否满意时&#xff0c;工程师回答“…

Effie for Mac - 简约而不简单的跨平台写作软件

在写作的道路上&#xff0c;我们都需要一些工具来帮助我们提高效率&#xff0c;更加流畅地表达思想。Effie for Mac 就是这样一款值得推荐的应用。它不仅拥有简洁、美观的界面设计&#xff0c;还具有丰富的功能&#xff0c;可以满足不同用户的需求。 首先&#xff0c;Effie 的…

再也不怕错漏爱校的PDF校对让每个文件都达到完美标准

在数字时代&#xff0c;PDF文件越来越成为传达专业信息和知识的首选格式。但与此同时&#xff0c;一个小小的错字或格式错误就可能影响到 整体的专业形象。现在&#xff0c;有了「爱校的PDF校对」工具&#xff0c;你可以轻松确保每个文件的完美与专业&#xff01; 为什么选择「…

中阿新时代,动漫创未来 | 蓝海彤翔助燃国漫走向世界

8月30日下午&#xff0c;首届中国-阿拉伯国家动漫产业论坛在苏州启幕。作为国内知名的文化科技产业集团&#xff0c;蓝海彤翔应邀出席此次论坛并进行现场签约&#xff0c;与中阿双方行业大咖、专家以及资深从业者深入探讨了未来合作的前景&#xff0c;共同为中阿动漫产业发展建…

记录layui数据表格使用文件上传按钮

一、前言 虽然用到这种的情况不多&#xff0c;但是还是记录下 二、相关代码 <!DOCTYPE html> <html> <head><meta http-equiv"Content-Type" content"text/html;charsetutf-8"/><meta name"renderer" content&quo…

Linux:编译遇到 Please port gnulib freadahead.c to your platform ,怎么破

问题背景 编译m4时遇到以下错误&#xff0c;该怎么解决呢&#xff1f; 解决方法 进入m4的build目录&#xff1a;build/host-m4-1.4.17 输入命令&#xff1a; sed -i s/IO_ftrylockfile/IO_EOF_SEEN/ lib/*.c echo "#define _IO_IN_BACKUP 0x100" >> lib/std…

伦敦金之路,如何开启?

要开启伦敦金投资之路&#xff0c;当然第一步是需要投资者找到一个正规的途径进行开户。但是开户之后&#xff0c;我们如何下手进行伦敦金投资呢&#xff1f;恐怕很多投资者都暂时对其有所迷茫。下面&#xff0c;笔者就从自己的角度&#xff0c;对这些问题进行讨论。 资深人士引…

好用的GIF工具分享

【工具链接】 链接&#xff1a;https://pan.baidu.com/s/1gX3Tjf-r0vrOwhinQjYKhA?pwd5upe 提取码&#xff1a;5upe 下载好的图标是 我们点击&#xff0c;会出现4个选项 1、录像机 &#xff08;录制GIF&#xff09; 录制过程中可以点击暂停和停止 点击停止我们会跳转到下…

浙江绿农环境:将废弃矿山变耕地,为生态文明贡献力量

近年来&#xff0c;随着可持续发展理念在中国乃至全球的日益普及&#xff0c;浙江绿农生态环境有限公司以其独特的创新和实践&#xff0c;成为了绿色发展的典范&#xff0c;在奋进新时代、建设新天堂的背景下&#xff0c;绿农环境在杭州市固废治理行业迈出坚实的步伐&#xff0…

【LeetCode】剑指 Offer <二刷>(3)

目录 题目&#xff1a;剑指 Offer 06. 从尾到头打印链表 - 力扣&#xff08;LeetCode&#xff09; 题目的接口&#xff1a; 解题思路&#xff1a; 代码&#xff1a; 过啦&#xff01;&#xff01;&#xff01; 题目&#xff1a;剑指 Offer 07. 重建二叉树 - 力扣&#xf…

如何为大面积实景三维建模“减负”?我们这样做

当前&#xff0c;各地加速布局实景三维中国建设&#xff0c;而面对任务量大、空域敏感、环境复杂等难题&#xff0c;传统工艺已无法满足需求。千寻位置推出的航测三维实景建模解决方案&#xff0c;融合终端、软件、应用和服务能力&#xff0c;为高精度、大面积地理信息数据应用…

Scrum工作模式及Scrum工具

Scrum工作模式是一种敏捷软件开发方法&#xff0c;其核心是团队合作和自我组织&#xff0c;旨在通过短周期的迭代开发&#xff0c;实现快速反馈和持续改进。 Scrum工作模式包括以下角色和活动&#xff1a; 1、产品负责人&#xff08;Product Owner&#xff09;&#xff1a;负…

非科班菜鸡算法学习记录 | 代码随想录算法训练营第52天||300.最长递增子序列 674.最长连续递增序列

300.最长递增子序列300. Longest Increasing Subsequence(英文力扣连接) 知识点&#xff1a;动规 状态&#xff1a;不会 思路&#xff1a; dp为取到i时的最长序列数字 dpi的值取决于前面比他小的数字&#xff08;dpj&#xff09;1&#xff1b;并实时更新最大值 class Soluti…

C语言----详解socket通信

一&#xff1a;什么是socket 刚接触socket的同学想必也知道socket的中文名&#xff0c;套接字&#xff0c;与其说是中文名倒不如说这是什么玩意&#xff0c;我们先不要管中文名的实际意义&#xff0c;我们先来了解一下什么是socket。 我们上网产生的数据都是经过协议栈一层一层…

linux并发服务器 —— 多进程并发 - 进程间的通信及实践(五)

进程间的通信 进程是一个独立的资源分配单元&#xff0c;不能在一个进程中直接访问另一个进程的资源&#xff1b; 进程间通信&#xff08;IPC&#xff09;的目的&#xff1a; 1. 数据传输 - A进程发送数据给B进程 2. 通知事件 - eg. 进程终止通知父进程 3. 资源共享 - 多个…