52单片机四种方法实现流水灯


欢迎你的到来!这里是我的单片机学习笔记,希望我的笔记可以在你学习的道路上对你有所帮助!

流水灯电路分析

流水灯电路图

在这里插入图片描述

电源→限流电阻→发光二极管→74HC573输出端→单片机P1组IO口

因为单片机的IO口输出电流非常小,无法直接用IO口驱动发光二极管,所以我们需要用到74HC573这个芯片(可以理解为电流放大的芯片)。

74HC573

芯片图

芯片图

从图中可以看出74HC573有20个引脚,Vcc和GND是电源的正负极,2 ~ 9的引脚是输入端,12 ~ 19的引脚是输出端

电极特性

电极特性

①我们的电路板一般的工作电压是5V,根据表中数据可以得知,芯片高电平的输入电压为≥3.15V,低电平输入电压为0~1.35V。我们使用的单片机STC89C52输出的电压为5V或者0V,满足上面的条件。
②再看高低电平的转换时间,Vcc=4.5V对应的是500ns,单片机执行一条指令最少的时间为1.08微秒,大于500纳秒,不需要额外加入延时就能达到芯片的要求。
③工作温度在-45摄氏度和85摄氏度之间。

真值表

真值表

L表示低点平,H表示高电平,X表示任意
Q0表示保持上一次的状态,Z表示保持高阻状态

由图可得:
①当输入OE的电平为低电平,LE为高电平时,输出电平的高低与输入电平相同。
②当输入OE的电平为低电平,LE也为低电平时,输出电平保持原来的电平高低。
③当输入OE的电平为高电平时,输出电平为高阻状态。
跳线帽

由于我的OE始终时接地的,所以OE始终为低电平,不会出现上述第③种情况
我把跳线帽接在了1和2(如上图),则LE为高电平,符合上述第①种情况

二进制十进制和十六进制转换

进制图表

进制表

表示方法:
二进制:0B 十六进制:0X 十进制数直接表示

示例:
十进制:15➡二进制:0B1111➡十六进制:0X0F

二进制转十六进制

一位十六进制数由四位二进制数表达,通过8421码来计算。(重点)
计算示例:
2转16

二进制转十进制

二转十

十进制转二进制

十转二

十进制转十六进制

十转十六

十六进制转十进制

十六转十

IO口的总线程控制方式

单片机IO口控制方式

位控制:对单独的每个IO口进行控制 例:led0=0(我的上一篇文章点亮led用的这种方法)
总线控制:对八个IO口通知进行控制 例:P1=0XFE
下面是通过总线控制点亮单个led对应的十六进制数是什么
总线控制

参考代码

1、简单粗暴法

上面我有提到单片机运行这一条代码的时间是微秒级别的,而我们人眼对于每11毫秒闪烁一次约83赫兹就已经基本感觉不到了。所以我们要在上面代码的基础上加上延时

int i = 40000;
while(i--);//延时

我们知道程序运行时需要时间,运行一次的时间很短,但我们可以用while循环让它多运行几次,从而达到延时的效果

#include<reg52.h>
#define led_time 40000
void main()
{
    
    
	unsigned int i;
	while(1)
	{
    
    
		P1 = 0XFE;//点亮第1个led
		i = led_time;
		while(i--);//延时(下同)
		P1 = 0XFD;//点亮第2个led
		i = led_time;
		while(i--);
		P1 = 0XFB;//点亮第3个led
		i = led_time;
		while(i--);
		P1 = 0XF7;//点亮第4个led
		i = led_time;
		while(i--);
		P1 = 0XEF;//点亮第5个led
		i = led_time;
		while(i--);
		P1 = 0XDF;//点亮第6个led
		i = led_time;
		while(i--);
		P1 = 0XBF;//点亮第7个led
		i = led_time;
		while(i--);
		P1 = 0X7F;//点亮第8个led
		i = led_time;
		while(i--);
	}
}

2、左移法简化程序

#include<reg52.h>
void main()
{
    
    
	unsigned int X = 0;
	unsigned int i;
	while(1)
	{
    
    
		P1 = ~( 0X01 << X );//左移并取反
		X++;
		if( X >= 8 )
		{
    
    
			X = 0;    //左移7次后清零
		}
		i = 40000;
		while(i--);
	}
}

3、调用库函数法

#include<intrins.h>
这个库函数包含了循环左移或者右移的子程序和_nop_延时函数
_nop_();//空操作,延迟一个机器周期时间
机器周期时间长短取决于晶振频率

#include<reg52.h>
#include<intrins.h>
void main()
{
    
    
	unsigned int i;
	P1 = 0XFE;//点亮第1个led
	while(1)
	{
    
    
		i = 40000;
		while(i--);//延时
		P1 = _crol_(P1,1);//每次循环左移一格
	}
}

4、数组法

#include<reg52.h>
unsigned char code LED[8]={
    
    0XFE,0XFD,0XFB,0XF7,0XEF,0XDF,0XBF,0X7F};
//点亮led的数组(加code为只读,不可修改,节省内存)
void main()
{
    
    
	unsigned int i;
	unsigned char j=0;//自加变量
	while(1)
	{
    
    	
	  P1 = LED[j++];
		if(j>=8)
			j=0;
		i = 40000;
		while(i--);//延时
	}
}

总结

四种方法实现流水灯
第一种:简单粗暴法
特点:思路简单明了,程序过于繁杂。
第二种:左移法
特点:运用了左移的运算,简化了第一种的方法的程序。
第三种:调用库函数
特点:程序上最简便的方法,一条语句实现了流水灯的功能。
第四种:数组法
特点:控制流水灯最灵活的方法,可以实现任意花样流水灯的效果。

参考内容链接: https://www.bilibili.com/video/BV1Kt411Q7aV?t=6824&p=5.

如有错误,还望斧正!感谢你的观看!

嘿~我亲爱的伙计!我想慷慨大方的你一定不会吝啬给我这个可怜的博主点赞的。

猜你喜欢

转载自blog.csdn.net/chuxiqianye2020/article/details/112802999