定时器动态扫描数码管LED矩阵显示

矩阵led显示,采用三级扫描,可以实现多级调亮度,动态扫描所有led灯亮度同一,不会出现一组led灯点亮的个数不同导致亮度不同,8*8矩阵的单个led灯闪烁(牺牲了亮度,整体亮度会下降一个级别,但是如果io口的驱动能力比较好的的话是不影响的)
三级扫描思路:
第一级扫描位扫描:一段数码管或者一行led 每个灯都执行相同的时间
第二级扫描段扫描:当扫描完一段之后,将段号或者行号加一,扫描下一段
第三级亮度扫描:当扫描完所有段之后亮度cnt加一,从新开始位扫描

/*   LED分布
     1
 2       3
     4
 5       6
     7   
*/ 
//阳极 码  阴极取反
// 0~f 数码管 ,不带点
const u8 table1[]={
	0x77,0x24,0x5d,0x6d,
	0x2e,0x6b,0x7b,0x25,
	0x7f,0x2f,0x3f,0x7a,
	0x53,0x7c,0x5b,0x1b
};
// 0~f 数码管 ,带点
const u8 table2[]={
	0xf7,0xa4,0xdd,0xed,
	0xae,0xeb,0xfb,0xa5,
	0xff,0xaf,0xbf,0xfa,
	0xd3,0xfc,0xdb,0x9b
}; 

定时器中断中 2ms一次,使用了一个变量用于判断led是否需要闪烁

if(250==Count_2ms_Blinking){   //500ms定时
	Count_2ms_Blinking = 0;
	flag.Blinking = ~flag.Blinking;//闪烁标志
}
	
void led_scan(void)
{
//一级扫描,段扫描 //PB0是SDA,从PB1开始算显示位
	LEDPositive &= 0x00; //bit[7:1]置0				
	LEDNegative = 0xff; //消隐
	if(display_duty < display_light_rate){ //计数小于 显示占空比的时候亮
		if(flag.Blinking) LEDNegative = DisplaydData_B2[display_section] |(~(0x01<<display_bit)) ;//只要B2.bn为0就亮
		else LEDNegative = DisplaydData_B1[ display_section ] |(~(0x01<<display_bit)); //只要B1.bn为0就亮
	} 	
	/*当前扫描段号对应bit置1 bit[7:1]*/	
	LEDPositive |= 0x01<<(display_section);
	if((++display_bit) < LED_BIT_SUM){
		return ;
	} 
	//二级扫描 位扫描	
	display_bit= 0;			
	if((++display_section) < LEDGroupSum){
		return ;
	} 
	//三级扫描 亮度扫描	
	display_section= 0; //扫描完一轮
	//多级调光 
	if((++display_duty) >= BRIGHT_MAX_RATE){
		display_duty = 0;
	} 
}
	


你可能感兴趣的:(单片机常用驱动)