CD107D板载的是8位共阳数码管,所谓共阴共阳的区别,这里稍作解释,我们都清楚数码管显示有段选和位选之分,每位数码管都包含八段发光二极管用于显示,而二极管必定有阴阳两极,如果八段显示二极管为阳极,那么公共端则为阴极,当公共端为低电平时数码管可以显示对应段码,同理,共阳数码管是指公共端为阳极,即位选为高电平时才具备导通能力。

OpenCV 数码管识别 单片机数码管扫描_OpenCV 数码管识别

共阳极数码管显示0-9的段码为

{0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}//0-9


多位数码管一般我们肯定希望能够在任意位显示任意数那么必须对数码管进行动态扫描,其实就是分时对数码管逐位进行扫描,要想达到较好的显示效果(闪烁不明显),扫描频率越高越好,但人眼能够分辨的闪烁极限也就60Hz左右,所以频率适当即可。


在实际编程中,一般用定时器中断来进行数码管扫描效率较高,不容易受其他程序干扰,假如在while循环里来做这件事的话,很可能由于某些耗时程序占用线程导致数码管闪烁频率下降,影响显示和观感。

用定时器来进行数码管扫描同样有两种方式,一种是将数码管8位扫描做成一个函数,丢到中断服务函数中,而动态扫描每位的数能够停留让人看到是因为加了延时,否则数码管显示会非常暗,并且在中断服务函数中再进行延时处理是非常不可取的,严重影响程序运行效率。因此实际编程中效率较高的是第二种方法,那就是:


在每次进入中断服务函数后只扫描数码管的一位,在下次进入中断后再扫描接下来的一位,循环往复,这样做的好处是在下一次中断到来之前上一次赋值的数能够得到保留,显示时常为相邻两次中断的时间,是不是感觉这样做好多了?


在实际编程中我习惯将定时器中断设为2ms,那么将8位数码管扫描一次需要花16ms,在1s内数码管能够刷新62次,这个显示频率已经和目前大多数智能手机屏幕刷新率相当了,并且要注意中断服务函数内容要尽可能少,让程序能够尽快回到主线程上。

以下是定时器的一般配置

void Timer0Init(void)		//2毫秒@11.0592MHz
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x01;		//设置定时器模式
	TL0 = 0x9A;		//设置定时初值
	TH0 = 0xA9;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
}


数码管单次扫描函数:

void smg_display(void)
{
	static u8 i=0;
	P0=0x01<<i;
	Y138(6); //送入位选数据
	P0=disp[buff[i]];
	Y138(7); //送入段选数据
	if(++i==8)i=0;
}

中断服务函数:

void timer0() interrupt 1
{
	TL0=0x9A;
	TH0=0xA9;
	smg_display();
}