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

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

一、代码编写

(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和j
    for (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;			//左移初值赋给temp
		    for(i=0; i<8; i++)	
	 	      {	
             P1=~temp;			// temp中的数据取反后送P1口
	 	         delay(  );			// 延时
	 	         temp=temp<<1; 		// temp 中数据左移一位
	       	}	
		    temp=0x80; 			// 赋右移初值给temp
	 	    for(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;		 	// 初值为11111110
 		  for(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.kler.cn/news/342741.html

相关文章:

  • 控制台java原生工具打包jar文件
  • 51c自动驾驶~合集3
  • 模块化沙箱的功能特点
  • 数据结构之——树形结构
  • 多线程实践(一)——# 基于多线程实现的并发服务器
  • 计算机毕业设计 基于Python的豆果美食推荐系统的设计与实现 Python+Django+Vue 前后端分离 附源码 讲解 文档
  • Python知识点:基于Python工具,如何使用PyTorch进行图像分类
  • 仿IOS桌面悬浮球(支持拖拽、自动吸附、自动改变透明度与点击、兼容PC端与移动端)
  • Java项目: 基于SpringBoot+mybatis+maven+vue健身房管理系统(含源码+数据库+毕业论文)
  • 查询数据库绘制历史曲线
  • C++ socket编程(1)
  • 你知道C++多少——栈和队列
  • Pr 视频效果:元数据和时间码刻录
  • 数据仓库拉链表
  • 7.并发编程之并发安全问题
  • 【Linux】Linux 环境变量中 LOGNAME 和 USER 有什么本质区别
  • 通义灵码-----阿里巴巴推出的 AI 编程助手,一站式安装使用教程。 我自己就是在用,感觉写代码会高效很多
  • 基于STM32的智能门锁
  • 日志分析(二)
  • 洗衣店订单处理:Spring Boot系统的优势