一、数码管的原理
数码管的每一段都由一个单独的发光二极管控制,亮的地方不同就可以表示不同的数字。但需要按照一定的顺序点亮。数码管分两种,一种是共阳极,另一种是共阴极。注意:如果是共阳极数码管我们单片机是可以直接驱动的,如果是共阴极数码管单片机的IO是不能直接驱动数码管的,需要外部提供大电流驱动芯片来处理。比如74HC245芯片就是一个驱动芯片。
二、什么是静态和动态数码管
静态数码管和动态数码管是驱动上的差异,而不是数码管本身的差异。因为我们同一时间只能让一个数码管亮,但是我们有时候会使用不止一个数码管,来组合的显示数字。因此我们就利用人眼的视觉暂留效应,在很短的时间内,切换数码管的亮灭,这样我们就能看到所有的数码管都是亮的。
三、静态数码管的驱动
通过看原理图发现,只需要将J8和P0端口连接起来,就完成了接线。通过看原理图我们还发现,我们这里使用的数码管是共阳极数码管。所以我们哪个引脚输出是0,那么这个位控制的数码管段就是亮的。输出1,则这个数码管段是灭的。需要注意的是,我们接线的时候,注意P0端口的高位和数码管高位的对应,简单地说就是P0^0对应数码管的DP端。依次类推然后接线。
四、静态数码管实战编程
#include <reg52.h>
#include <intrins.h>
void delay1s(void) //误差 0us
{
unsigned char a,b,c;
for(c=46;c>0;c--)
for(b=152;b>0;b--)
for(a=70;a>0;a--);
_nop_(); //if Keil,require use intrins.h
}
void main(void)
{
unsigned char shuma[10] = {0x03, 0x9f, 0x25, 0x0d, 0x99, 0x49, 0x41, 0x1f, 0x01, 0x09};
//从0-9对应的数码管显示数字
unsigned char shuma1[16] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e};
//对应的是顺着的时候,数码管对应数字的编码 也就是P0.0对应 a 依次对应即可
unsigned char i = 0;
while(1)
{
for (i=0; i<10; i++)
{
P0 = shuma[i];
delay1s();
}
}
}
这个程序的主要目标是,在静态数码管上面依次显示0到9的数字,首先我们通过前面的原理和看数据手册,先手工计算出来,不同的数字对应的不同的数码管亮灭。然后再用一个循环每间隔 1秒,给P0端口,放一个不同的值,这样我们就可以显示不同的数字了。
五、动态数码管实战
通过看原理图,我们就可以发现,动态数码管是共阴极的,因此我们在静态数码管获得的每个数字对应的段码,是不能直接用在动态数码管上面的,想要使用 按位取反即可。我们还可以看到所有的数码管所对应的码段,都被并联到了一起,因此如果在J6这边,给定一组数据,那么所有数码管得到的都是一样的,那么我们就需要在J1端,去控制只要J1端在同一时间,只让其中的一个引脚是低电平,其他的都是高电平,那么就能保证在同一时间段只亮一个数码管。在极短的时间内进行切换,我们就可以在不同的数码管上进行显示了。
通过看原理图和实物图我们发现,J1和J10是通过很多跳线帽连到了一起,然后J10连接的是一个38译码器,他的主要功能是用3根线,就可以控制8个位的不同的0和1的状态。下面是他的3根线和8个输出引脚电平的关系。
通过看图我们发现他的A0, A1, A2对应的就是我们的A,B,C三个引脚,也就是对应J9插座的3,2,1,然后我们通过接线将3 2 1分别接到P1.0 P1.1 P1.2三个引脚上面,也就是说我们的P1.0, P1.1, P1.2分别对应上图的A0, A1, A2。然后我们就可以进行编程了。
sbit A0 = P1^0;
sbit A1 = P1^1;
sbit A2 = P1^2;
#define SHUMAGUAN P0
void DuanXuan(unsigned char num)
{
switch (num){
case 0: A0 = 0,A1 = 0, A2 = 0;break;
case 1: A0 = 1,A1 = 0, A2 = 0;break;
case 2: A0 = 0,A1 = 1, A2 = 0;break;
case 3: A0 = 1,A1 = 1, A2 = 0;break;
case 4: A0 = 0,A1 = 0, A2 = 1;break;
case 5: A0 = 1,A1 = 0, A2 = 1;break;
case 6: A0 = 0,A1 = 1, A2 = 1;break;
case 7: A0 = 1,A1 = 1, A2 = 1;break;
}
}
void delay1ms(void) //误差 0us
{
unsigned char a,b;
for(b=199;b>0;b--)
for(a=1;a>0;a--);
}
/*
*函数功能:在特定的位上显示特定的数字
*输入参数:bits:要在哪一位数码管上显示 数码管从左往右 依次是0到7
* num:需要显示的数字
*/
void ShuMaGuanShow(unsigned char bits, unsigned char num)
{
unsigned char shuma[16] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e};
DuanXuan(bits); //用来选择数码管需要显示的位置
SHUMAGUAN = ~shuma[num];
delay1ms();
SHUMAGUAN = 0; //用来进行消隐,不理解的话将这行,去掉看结果就懂了
}
当我们想要在某一位进行显示时,我们只需要调用这个函数即可。