如下图:红框就是数码管
51单片机——数码管_38译码器
数码管原理
这里说的都是共阴极连接的
51单片机——数码管_单片机_0251单片机——数码管_38译码器_03
如果要显示数字0,我们只需要把G和dp置0,其他位置1即可,即ABCDEFG,DP=1111 1100

原理图
51单片机——数码管_单片机_04
假设我们需要控制LED8口显示数字0:
P2_2=1
P2_3=1
P2_4=1
a,b,c,d,e,f,g,dp=1111 1100,即P00~P07为1111 1100,因为P00是低位,所以得反过来就是0011 1111,即P0=0x3F

ps:74HC245在这里的作用是增大电流,之前LED是低电平点亮,现在这里是高电平点亮,不加74HC245灯很暗

例程1:LED8显示0

#include <REGX52.H>

unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
void Nixie(unsigned char Location,Number)
{
	switch(Location)		
	{
		case 1:P2_4=1;P2_3=1;P2_2=1;break;
		case 2:P2_4=1;P2_3=1;P2_2=0;break;
		case 3:P2_4=1;P2_3=0;P2_2=1;break;
		case 4:P2_4=1;P2_3=0;P2_2=0;break;
		case 5:P2_4=0;P2_3=1;P2_2=1;break;
		case 6:P2_4=0;P2_3=1;P2_2=0;break;
		case 7:P2_4=0;P2_3=0;P2_2=1;break;
		//这里LED8口取000而不是111是因为原理图的LED是反的,第一个led是LED8
		case 8:P2_4=0;P2_3=0;P2_2=0;break;
	}
	P0=NixieTable[Number];	
}

void main()
{
	Nixie(8,0);
	while(1)
	{
	}
}

例程2:LED8显示0 , LED1显示1

#include <REGX52.H>

unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
void Nixie(unsigned char Location,Number)
{
	switch(Location)		
	{
		case 1:P2_4=1;P2_3=1;P2_2=1;break;
		case 2:P2_4=1;P2_3=1;P2_2=0;break;
		case 3:P2_4=1;P2_3=0;P2_2=1;break;
		case 4:P2_4=1;P2_3=0;P2_2=0;break;
		case 5:P2_4=0;P2_3=1;P2_2=1;break;
		case 6:P2_4=0;P2_3=1;P2_2=0;break;
		case 7:P2_4=0;P2_3=0;P2_2=1;break;
		//这里LED8口取000而不是111是因为原理图的LED是反的,第一个led是LED8
		case 8:P2_4=0;P2_3=0;P2_2=0;break;
	}
	P0=NixieTable[Number];	
}

void main()
{
	Nixie(8,0);
	Nixie(1,1);
	while(1)
	{
		
	}
}

结果如下:
51单片机——数码管_51单片机_05
为什么LED8口不显示呢?观察原理图可以发现线路是共用的,所以相当于覆盖掉了,这也是为了节省引脚,为了解决这个问题,就要利用人眼的视觉暂留效应,cpu不停扫描数码管,先让第一个数字亮,然后再让第二个数字亮,再让第一个数字亮。。。。一直下去。

例程3:LED8显示0 , LED1显示1

#include <REGX52.H>

unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
void Delay(unsigned int xms)
{
	unsigned char i, j;
	while(xms--)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}
void Nixie(unsigned char Location,Number)
{
	switch(Location)		
	{
		case 1:P2_4=1;P2_3=1;P2_2=1;break;
		case 2:P2_4=1;P2_3=1;P2_2=0;break;
		case 3:P2_4=1;P2_3=0;P2_2=1;break;
		case 4:P2_4=1;P2_3=0;P2_2=0;break;
		case 5:P2_4=0;P2_3=1;P2_2=1;break;
		case 6:P2_4=0;P2_3=1;P2_2=0;break;
		case 7:P2_4=0;P2_3=0;P2_2=1;break;
		//这里LED8口取000而不是111是因为原理图的LED是反的,第一个led是LED8
		case 8:P2_4=0;P2_3=0;P2_2=0;break;
	}
	P0=NixieTable[Number];
	Delay(1);//如果想要观察扫描切换的过程,将此值调大			
	P0=0x00;	
}

void main()
{
	
	while(1)
	{
		Nixie(8,0);
		Nixie(1,1);
	}
}

例程3Delay(100)效果图:

 

51单片机动态数码管扫描