数码管扫描显示-单片机通用模板 一、数码管扫描的原理 二、display.c的实现 1、void Display(void) 各模式界面定义数据 2、void BackupRamToDisRam(void)从缓存区刷新显示映射Ram 3、void FreshDisplay(void) 映射显示Ram到主控的IO口 4、void LcdDisplay_8bit(void) 映射显示Ram到主控的IO口 三、display.h的外部接口 四、显示功能的使用、Note
一、数码管扫描的原理
①人的眼睛中的画面在0.02S(50Hz)左右,光源的闪烁频率高于50-60赫兹时,人眼通常无法察觉到光的闪烁; ②通过控制LED的亮灭透过模具贴纸从而控制数字和图案的亮灭;
二、display.c的实现
1、void Display(void) 各模式界面定义数据
u8 CxSegData[ ] = { 0 , 0 , 0 , 0 } ;
void Display ( void )
{ if ( b_Display_Flag== 0 ) return ; b_Display_Flag= 0 ; switch ( Mode) { case 0 : CxSegData[ 0 ] = 0x00 ; CxSegData[ 1 ] = 0x00 ; CxSegData[ 2 ] = 0x00 ; CxSegData[ 3 ] = 0x00 ; b_Fresh_Flag= 1 ; break ; case 1 : CxSegData[ 0 ] = 0xff ; CxSegData[ 1 ] = 0xff ; CxSegData[ 2 ] = 0xff ; CxSegData[ 3 ] = 0xff ; b_Fresh_Flag= 1 ; break ; case 2 : CxSegData[ 3 ] = Unb_Red; CxSegData[ 3 ] = Unb_Inf; CxSegData[ 3 ] = Unb_Twi; b_Fresh_Flag= 1 ; break ; case 3 : CxSegData[ 3 ] = b_Red; CxSegData[ 3 ] = b_Inf; CxSegData[ 3 ] = b_Twi; b_Fresh_Flag= 1 ; break ; case 4 : LcdDisplay_8bit ( LzLcdNum1, LedNumCoding[ 6 ] ) ; LcdDisplay_8bit ( LzLcdNum2, LedNumCoding[ 6 ] ) ; b_Fresh_Flag= 1 ; break ; case 5 : b_Fresh_Flag= 1 ; break ; case 6 : b_Fresh_Flag= 1 ; break ; }
}
2、void BackupRamToDisRam(void)从缓存区刷新显示映射Ram
u8 CxSeg[ ] = { 0 , 0 , 0 , 0 } ;
void BackupRamToDisRam ( void )
{ if ( b_Fresh_Flag) { b_Fresh_Flag= 0 ; CxSeg[ 0 ] = CxSegData[ 0 ] ; CxSeg[ 1 ] = CxSegData[ 1 ] ; CxSeg[ 2 ] = CxSegData[ 2 ] ; CxSeg[ 3 ] = CxSegData[ 3 ] ; }
}
3、void FreshDisplay(void) 映射显示Ram到主控的IO口
sbit b_Com1 = P3^ 4 ;
sbit b_Com2 = P3^ 5 ;
sbit b_Com3 = P3^ 6 ;
sbit b_Com4 = P3^ 7 ; sbit b_Seg1 = P1^ 4 ;
sbit b_Seg2 = P1^ 2 ;
sbit b_Seg3 = P1^ 1 ;
sbit b_Seg4 = P1^ 0 ;
sbit b_Seg5 = P0^ 3 ;
sbit b_Seg6 = P0^ 2 ;
void FreshDisplay ( void )
{ static u8 disIndex= 0 ; P3 |= 0xf0 ; if ( disIndex== PwmLevel) disIndex= 0 ; disIndex++ ; b_Seg1 = CxSeg[ 0 ] & 0x01 ; b_Seg2 = CxSeg[ 0 ] & 0x02 ; b_Seg3 = CxSeg[ 0 ] & 0x04 ; b_Seg4 = CxSeg[ 0 ] & 0x08 ; b_Seg5 = CxSeg[ 0 ] & 0x10 ; b_Seg6 = CxSeg[ 0 ] & 0x20 ; switch ( disIndex) { case 1 : b_Com1 = 0 ; break ; case 2 : b_Com2 = 0 ; break ; case 3 : b_Com3 = 0 ; break ; case 4 : b_Com4 = 0 ; break ; }
}
4、void LcdDisplay_8bit(void) 映射显示Ram到主控的IO口
# define b_Red CxSegData[ 3 ] | 0x01
# define b_Inf CxSegData[ 3 ] | 0x02
# define b_Twi CxSegData[ 3 ] | 0x04
# define b_P1 CxSegData[ 2 ] | 0x04
# define b_P2 CxSegData[ 2 ] | 0x08
# define b_P3 CxSegData[ 2 ] | 0x10
# define b_P4 CxSegData[ 2 ] | 0x20 # define Unb_Red CxSegData[ 3 ] & ~ 0x01
# define Unb_Inf CxSegData[ 3 ] & ~ 0x02
# define Unb_Twi CxSegData[ 3 ] & ~ 0x04
# define Unb_P1 CxSegData[ 2 ] & ~ 0x04
# define Unb_P2 CxSegData[ 2 ] & ~ 0x08
# define Unb_P3 CxSegData[ 2 ] & ~ 0x10
# define Unb_P4 CxSegData[ 2 ] & ~ 0x20 u8 code LzLcdNum1[ ] = { COM1, SEG1, COM1, SEG2, COM1, SEG3, COM1, SEG4, COM1, SEG5, COM1, SEG6, COM3, SEG1, 0xff , 0xff
} ; u8 code LzLcdNum2[ ] = { COM2, SEG1, COM2, SEG2, COM2, SEG3, COM2, SEG4, COM2, SEG5, COM2, SEG6, COM3, SEG2, 0xff , 0xff
} ; unsigned char code LedNumCoding[ ] = { 0x3F , 0x06 , 0x5B , 0x4F , 0x66 , 0x6D , 0x7D , 0x07 , 0x7F , 0x6F , 0x00 , 0x40 , 0x76 , 0x38 , 0x50 , 0x39 , 0x37 , 0x77 , 0x71 , 0x7F } ;
void LcdDisplay_8bit ( u8 * Table_Seg, u8 Value)
{ u8 i= 0 , j= 0 ; u8 Seg, Com; Com= Table_Seg[ i] ; Seg= Table_Seg[ i+ 1 ] ; i+= 2 ; for ( ; Com!= 0xff ; ) { if ( ( Value & 0x01 ) == 1 ) CxSegData[ Com] = CxSegData[ Com] | Seg; else CxSegData[ Com] = CxSegData[ Com] & ~ Seg; Value= Value>> 1 ; Com= Table_Seg[ i] ; Seg= Table_Seg[ i+ 1 ] ; i+= 2 ; }
}
三、display.h的外部接口
extern bit b_Display_Flag;
extern void Display ( void ) ;
extern void BackupRamToDisRam ( void ) ;
extern void FreshDisplay ( void ) ;
四、显示功能的使用、Note
在主函数main的while循环里调用,等标志更新显示
void main ( void )
{
while ( 1 ) { Display ( ) ; BackupRamToDisRam ( ) ; if ( b_16Hz_Flag) { F_16HzTask ( ) ; } if ( b_2Hz_Flag) { F_2HzTask ( ) ; } }
}
在2~4kHz的定时器里面调用FreshDisplay() 映射到IO功能函数,频率偏低可能观察到有闪烁,可以调节PwmLevel 的大小从而调节亮度,降低功耗;
void TIM2_INT ( void ) interrupt 5
{ TF2= 0 ; FreshDisplay ( ) ;
该框架可使用于LCD、数码管、LED显示,可以通过修改映射关系进而移植到其它项目上; 数码管显示难点是如何建立映射关系?如何将IO和显示Ram建立关系?如何控制每个LED的亮灭关系?如何显示数字和字母? 需要更新屏幕显示注意b_Display_Flag 是否需要更新缓存区CxSegData的数据,需要更新缓存数据到硬件IO注意b_Fresh_Flag 标志; 显示功能基本战项目的50%的代码量,模块化功能程序可以很好定位Bug的位置,缩短开发周期;