52单片机IO口输出-流水灯
欢迎你的到来!这里是我的单片机学习笔记,希望我的笔记可以在你学习的道路上对你有所帮助!
流水灯电路分析
流水灯电路图
电源→限流电阻→发光二极管→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码来计算。(重点)
计算示例:
二进制转十进制
十进制转二进制
十进制转十六进制
十六进制转十进制
IO口的总线程控制方式
单片机IO口控制方式
位控制:对单独的每个IO口进行控制 例:led0=0(我的上一篇文章点亮led用的这种方法)
总线控制:对八个IO口通知进行控制 例:P1=0XFE
下面是通过总线控制点亮单个led对应的十六进制数是什么
参考代码
1、简单粗暴法
上面我有提到单片机运行这一条代码的时间是微秒级别的,而我们人眼对于每11毫秒闪烁一次约83赫兹就已经基本感觉不到了。所以我们要在上面代码的基础上加上延时
int i = 40000;
while(i--);//延时
我们知道程序运行时需要时间,运行一次的时间很短,但我们可以用while循环让它多运行几次,从而达到延时的效果
#include<reg52.h>
void main()
{
unsigned int i;
while(1)
{
P1 = 0XFE;//点亮第1个led
i = 40000;
while(i--);//延时(下同)
P1 = 0XFD;//点亮第2个led
i = 40000;
while(i--);
P1 = 0XFB;//点亮第3个led
i = 40000;
while(i--);
P1 = 0XF7;//点亮第4个led
i = 40000;
while(i--);
P1 = 0XEF;//点亮第5个led
i = 40000;
while(i--);
P1 = 0XDF;//点亮第6个led
i = 40000;
while(i--);
P1 = 0XBF;//点亮第7个led
i = 40000;
while(i--);
P1 = 0X7F;//点亮第8个led
i = 40000;
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--);//延时
}
}
总结
四种方法实现流水灯
第一种:简单粗暴法
特点:思路简单明了,程序过于繁杂。
第二种:左移法
特点:运用了左移的运算,简化了第一种的方法的程序。
第三种:调用库函数
特点:程序上最简便的方法,一条语句实现了流水灯的功能。
第四种:数组法
特点:控制流水灯最灵活的方法,可以实现任意花样流水灯的效果。