制作一个流水灯,控制发光二极管由上至下再由下至上反复循环点亮显示,每次点亮一个发光二级管(Proteus 与Keil uVision联合仿真)

embedded/2024/12/22 10:57:12/

一、代码编写

(1)编写程序来控制发光二极管由上至下的反复循环流水点亮,每次点亮一个发光二极管。

#define uchar unsigned char // 定义uchar为unsigned char类型uchar tab[] = {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f, 0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe}; // 定义一个数组,用于存储LED灯的亮灭模式// 延时函数,用于产生一定的延时效果
void delay(void)
{uchar i, j; // 声明两个无符号字符型变量i和jfor (i = 0; i < 255; i++) // 外层循环,循环255次for (j = 0; j < 255; j++); // 内层循环,也循环255次,这样会产生一个较长的延时
}// 主函数,程序从这里开始执行
void main()
{uchar i; // 声明一个无符号字符型变量i,用于循环计数while (1) // 无限循环,因为流水灯效果是一直持续的{for (i = 0; i < 16; i++); // 循环16次,对应数组tab中的16种LED灯亮灭模式{P1 = tab[i]; // 将数组tab中的第i个元素赋值给P1口,即改变LED灯的亮灭状态delay(); // 调用延时函数,使LED灯的亮灭状态保持一段时间}}
}

(2) 使用移位运算符“>>”、“<<”,把送P1口显示控制数据进行移位,从而实现发光二极管依次点亮;

#include <reg51.h>
#define uchar unsigned char		  			
void  delay(  )
{	uchar i,j;for(i=0; i<255; i++)for(j=0; j<255; j++);
}void  main(  )				//主函数
{	uchar i,temp;while (1) {	temp=0x01;			//左移初值赋给tempfor(i=0; i<8; i++)	{	P1=~temp;			// temp中的数据取反后送P1口delay(  );			// 延时temp=temp<<1; 		// temp 中数据左移一位}	temp=0x80; 			// 赋右移初值给tempfor(i=0; i<8; i++){	P1=~temp;			// temp中的数据取反后送P1口 delay(  );			// 延时temp=temp>>1; 		// temp 中数据右移一位}}
}

(3)使用C51提供的库函数,即循环左移n位函数和循环右移n位函数,控制发光二极管点亮;

#include <reg51.h>
#include <intrins.h>		    //包含循环左、右移位函数的头文件
#define uchar unsigned char
void  delay(  )
{	uchar i,j;for(i=0; i<255; i++)for(j=0; j<255; j++);
}void  main(  )				// 主函数
{	uchar i,temp;while (1){	temp=0xfe;		 	// 初值为11111110for(i=0; i<7; i++)	{	P1=temp;		// temp中的点亮数据送P1口,控制点亮显示delay(  ); 				// 延时temp=_crol_( temp,1) ;		//  temp 数据循环左移1位}for(i=0; i<7; i++)	{	P1=temp;				// temp中的数据送P1口输出delay(  ); 				// 延时temp=_cror_( temp,1) ;		//temp中数据循环右移1位}}
}

二、硬件仿真

(1)原理图

(2)仿真结果

注意使用移位运算符“>>”、“<<”与使用循环左移函数“_crol_”和循环右移函数“_cror_” 区别。左移移位运算“<<”是将高位丢弃,低位补0 ;右移移位运算、“>>”是将低位丢弃,高位补0。而循环左移函数“_crol_” 是将移出的高位再补到低位,即循环移位;同理循环右移函数“_cror_” 是将移出的低位再补到高位。

三、思考题

1、如何改变流水灯的流动速度?

答:在本次实验中,可以通过更改延时程序delay里的i,j的值来改变流水灯的流动速度。

2、AT89S52单片机任何一个端口要想获得较大的驱动能力,要采用什么电平输出?

答:为了获得较大的驱动能力,通常会选择推挽输出模式。在推挽输出模式下,端口的高电平和低电平都可以通过外部上拉电阻和下拉电阻来实现,这样可以提供更强的驱动能力,适合连接到需要较高电流的外部设备。


http://www.ppmy.cn/embedded/125025.html

相关文章

如何保证 Redis 与数据库的数据一致性

在现代的应用开发中&#xff0c;Redis 作为一种高性能的内存数据库&#xff0c;常常被用来缓存热点数据&#xff0c;以提高系统的响应速度和吞吐量。然而&#xff0c;由于 Redis 是内存数据库&#xff0c;与传统的关系型数据库&#xff08;如 MySQL&#xff09;在数据存储和管理…

第五章:软件工程 (5.1软件工程定义--5.2软件需求)

5.1 软件工程定义 软件工程由方法、工具和过程3个部分组成。 方法&#xff1a; 完成软件项目的技术手段&#xff0c;支持整个软件生命周期 工具&#xff1a; 是人们在开发软件的活动中智力和体力的扩展与延伸&#xff0c;它自动或半自动地支持软件的开发和管理&#xff0c;支…

Sym-NCO:利用对称性进行神经组合优化

文章目录 Abstract1 Introduction2 组合优化马尔可夫决策过程中的对称性2.1 组合马尔可夫决策过程2.2 CO-MDP中的对称性3 对称神经组合优化3.1 通过LSym-RL正则化REINFORCE的问题和解决方案对称性3.2 通过预先识别的对称性学习不变表示: L i n v L_{inv} Linv​4 相关工作5 Ex…

回到原点再出发

原文What Goes Around Comes Around作者Michael Stonebraker & Joseph M. Hellerstein其他译文https://zhuanlan.zhihu.com/p/111322429 1. 摘要 本文总结了近35年来的数据模型方案&#xff0c;分成9个不同的时代&#xff0c;讨论了每个时代的方案。我们指出&#xff0c;…

Golang | Leetcode Golang题解之第456题132模式

题目&#xff1a; 题解&#xff1a; func find132pattern(nums []int) bool {candidateI, candidateJ : []int{-nums[0]}, []int{-nums[0]}for _, v : range nums[1:] {idxI : sort.SearchInts(candidateI, 1-v)idxJ : sort.SearchInts(candidateJ, -v)if idxI < idxJ {ret…

【Vue】Vue 快速教程

Vue tutorial 参考&#xff1a;教程 | Vue.js (vuejs.org) 该教程需要前置知识&#xff1a;HTML, CSS, JavaScript 学习前置知识&#xff0c;你可以去 MDN Vue framework 是一个 JavaScript framework&#xff0c;以下简称 Vue&#xff0c;下面是它的特点 声明式渲染&#xff…

【CTF Web】Pikachu 本地文件包含 Writeup(文件包含漏洞+GET请求)

File Inclusion(文件包含漏洞)概述 文件包含&#xff0c;是一个功能。在各种开发语言中都提供了内置的文件包含函数&#xff0c;其可以使开发人员在一个代码文件中直接包含&#xff08;引入&#xff09;另外一个代码文件。 比如 在PHP中&#xff0c;提供了&#xff1a; includ…

Ubuntu22.04 获取docker 镜像失败如何处理

最近在使用docker 获取镜像发现 如下错误 无法正常的访问 如果能正常上网的情况下&#xff0c;可以尝试如下操作 首先进入/etc/docker/daemon.json文件 然后在里面加入下面的配置 { "registry-mirrors": ["https://docker.registry.cyou", "htt…