三.共阳数码管
共阳数码管
数码管就是由LED组成的。
每个数码管的代号如图所示,按abcd顺时针走一圈即可。我们让P0=0x00就能点亮所有数码管(per)。
如果我们要让数码管成为一个2,那么就是
dp | g | f | e | d | c | b | a |
---|---|---|---|---|---|---|---|
1 | 0 | 1 | 0 | 0 | 1 | 0 | 0 |
换算为十六进制就是(从右向左!!!!)
1 | P0=0xa4; |
同理,0的话就是
dp | g | f | e | d | c | b | a |
---|---|---|---|---|---|---|---|
1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
即:
1 | P0=0xc0; |
不过听说比赛的时候赛点资源包里面是有数码管数字的十六进制的…..
接下来我们看原理图。
控制数码管,我们是由com公共端控制的,
abcd口由U7控制。端口连接情况如图所示,依然存在锁存器,依然存在或非门。
com连接情况也是显而易见。由U8控制。
不过需要注意的是,我们一共有8个数码管,每个阴极a和a,b和b都是接在一起的,如果我们需要显示0,那所有数码管都会只显示0。
因此,需要的线不是72个,而是16根线。具体如何操作我们后面再说。
静态数码管
下面我们开始写代码:
1 | #include <reg52.h> |
当我们编译成功时,会看到下面状态栏里的内容
date是程序变量大小,xdate是外部存储器,code是存放了我们刚才的数组。
我们上一次学习了LED,蜂鸣器和继电器,每次我们都要重新定义573锁存器的输出,所以,我们写一个新的函数,用来调用我们需要的功能。
函数定义如下:
1 | void hc573(unchar channel) |
函数初始化
1 | void init () |
定义数码管函数:
1 | void SMG(uchar seg) |
主函数:
1 | void main() |
然后,我们的数码管就会全部显示数字7了。
动态数码管
首先,我们的数码管是没法同时显示不同数字的。
那我们该怎么样才能让数码管同时显示不同数字呢?
我们没法改变数码管,但能用数码管欺骗我们的眼睛。
我们可以让第一个数码管显示1,然后熄灭其他数码管,再过1ms.让第二个数码管显示2,同时熄灭第一个和其他数码管,如此循环往复,就能欺骗我们的眼睛了。
这个效果叫做,余晖效应。
我们开始改代码:
1 | void SMG(uchar pos,seg) |
定义显示数字:20240302
1 | void display() |
主函数
1 | void main() |
然后就完成了。
不过,我们会发现,没有亮的地方有残影。
这里,我们就需要进行数码管消隐。
数码管消隐
出现的原因就是先进行位选,再进行段选,进行第二次循环的时候,上一次段选的状态会延续到我下一次位选。这样就会出现残影。
解决方法就是直接在每一次循环的时候,在位选前面加一次段选,令P0 = 0xff;
于是,我们进行消隐处理后的代码就是:
1 | void SMG(uchar pos,seg) |
数码管特殊字符
字母
字母的话我们和数字方法一样,这里不过多赘述。
当我们需要调用的时候,记得在我们放入字母的segment数组中进行调用。
我们的数码管显示函数是这样的:
1 | void display() |
小数点
如果是显示小数点的话,那我们让dp输出为0就好了,这样的话我的数字要全部重新写。当然我们还有更加便捷的方法。
我们先举个狸子:
如果是显示数字1
11111001
变为
01111001
这里改变的只有最后一位,所以我们的思路就是保留前七位,更改最后一位。
这里我们使用&运算符。
&和1效果为保留,&0效果就是清除。
所以,我们搞出来一个
01111111就可以把最后一位的dp位置清除为0.
所以,我们的代码更改为:
1 | void SMG(uchar pos,seg) |
显示函数更改为:
1 | void display() |