我们在马路上看到的红绿灯,就是由数码管来实现的,就是其中可能加入了一些延时和转换
数码管是通过控制138译码器与74HC245来控制数码管的亮灭与数字的显示
电路原理图
我们先讨论一个数码管
数码管有共阳极和共阴极,我们现在使用的STC89C52是共阴极的,说明数码管共用阴极
上面是阴极,下面我们给阳极,即给1,就可以亮了
说这么多,我们来是通过实例来看吧
首先我们要选灯的位置,假如我们要选择,左手边第一个灯,我们怎么设置
灯的位置通过138译码器来控制
通过原理图也可以看出,左手边第一个灯LED8是通过Y7来确定的,那么怎么控制呢
Y7即对应的数字为7,二进制表示为111
这个111又赋给谁
我们规定P24是高位,P23是中间的一位,P22是最低位
这个111就是赋值给P24~P22
灯的位置在哪里我们知道控制了
数字的显示又怎么控制
我们是通过控制74HC245来控制信号的,先了解一下74HC245
我们给P0给值就可以控制信号了
我们在前面知道5对应在数码管信号为10110110
因为低位放在放在P0_0,所以我们在P0赋值是5的信号二进制的倒过来,即01101101对应的16进制0x6D
我们看看代码的实现吧
下面我们再来控制一个灯试一试,就LDE4吧,对应的是Y3,二进制011,显示数字为8,则对应的为
1111 1110,我们给P0的是0111 1111 对应16进制0x7F
点亮一个灯的步骤应该我们已经熟悉了
1.选位置,LED8~Y7,以此类推,Y后面的数字,对应P24~P22的二进制
2.选数字,根据共阴极来确定0或者1
3.在P0中存(倒过来)
如果我们要点亮很多个灯怎么实现,138编码器好像只能控制一个灯的亮灭啊
如果我们想点亮多个数字,eg
这个代码可以在屏幕显示12吗
好像不怎么行啊
这个代码的功能是什么,可以在不断的显示1和2,中间间隔0.5秒
那么我们让它一直显示怎么操作
我们把时间间隔改成0.001秒会怎么样
好像结果不怎么令人满意
出现这个原因是什么
我们怎么消除影响
我们可以将P0置为0
我们将P0置为0,这样就可以消除影响了,这时可以显示12
我们假如Delay的作用是什么,不加会怎么样
我们去除是怎么样的
我们去除了,显示会变暗一点,加了延时1毫秒我们可以让1或者2显示更久一点这样就会亮一点
总结:
我们显示多个数字操作和显示一个数字的操作大同小异
但是我们显示多个数字的时候,在显示下一个数字的时候,我们需要消除P0的影响,即把P0置空
我们138译码器只能控制一个灯的亮灭,我们利用人眼的视觉差,其实我们一个时间只能显示一个数字,我们看到两个数字是因为,这两个数字之间在不断转换,转换得很快,我们肉眼觉得它们没有变化,起到以假乱真得效果
我们每次设置显示的位置,都要定义,数字也要定义,显得十分不方便
我们构造一个函数来实现他会事半功倍
#include <REGX52.H>
void Delay(long xms) //延时函数
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
void Nixietube_number(int position,int number)//对应的位置左手边为第一个显示屏
{
unsigned char numberSize[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
switch(position)
{
case 1:
P2_4=1;P2_3=1;P2_2=1;break;//对应138译码器Y7 LED8
case 2:
P2_4=1;P2_3=1;P2_2=0;break;//??138???Y6 LED7
case 3:
P2_4=1;P2_3=0;P2_2=1;break;//??138???Y5 LED6
case 4:
P2_4=1;P2_3=0;P2_2=0;break;//??138???Y4 LED5
case 5:
P2_4=0;P2_3=1;P2_2=1;break;//??138???Y3 LED4
case 6:
P2_4=0;P2_3=1;P2_2=0;break;//??138???Y2 LED3
case 7:
P2_4=0;P2_3=0;P2_2=1;break;//??138???Y1 LED2
case 8:
P2_4=0;P2_3=0;P2_2=0;break;//??138???Y0 LED1
}
P0=numberSize[number];
Delay(1);//稳定显示数字
P0=0;//消除数字
}
利用这个函数,我们可以快速设置数码管上的数字
我们调用这个函数就可以显示数字了