数码管动态显示
/* 数码管编码表 */ const uint16_t LedTable2[]={0,1,2,3,4,5,6,7,8,9}; // const关键字将变量定义在ROM中 /* 动态显示注意点: * 1、占空比与LED的显示亮度有关 —— delay(100) * 2、扫描周期要大于20ms,即扫描频率大于50Hz */ void LedDisplay(uint16_t Led1,uint16_t Led2,uint16_t Led3,uint16_t Led4m,uint16_t Led5) { // /* 消影 */ // SendData_74HC595(0xFFFF); /* 送段选数据*/ SendData_74HC595(Led1); /* 打开Wei1显示 */ TurnOnWei1; /* 显示延时 */ delay(100); /* 关闭Wei1显示 */ TurnOffWei1; // /* 消影 */ // SendData_74HC595(0xFFFF); /* 送段选数据*/ SendData_74HC595(Led2Num); /* 打开Wei2显示 */ TurnOnWei2; /* 显示延时 */ delay(100); /* 关闭Wei2显示 */ TurnOffWei2; // /* 消影 */ // SendData_74HC595(0xFFFF); /* 送段选数据 */ SendData_74HC595(Led3Num); /* 打开Wei3显示 */ TurnOnWei3; /* 显示延时 */ delay(100); /* 关闭Wei3显示 */ TurnOffWei3; // /* 消影 */ // SendData_74HC595(0xFFFF); /* 送段选数据 */ SendData_74HC595(Led4Num); /* 打开Wei4显示 */ TurnOnWei4; /* 显示延时 */ delay(100); /* 关闭Wei4显示 */ TurnOffWei4; // /* 消影 */ // SendData_74HC595(0xFFFF); /* 送段选数据 */ SendData_74HC595(Led5Num); /* 打开Wei5显示 */ TurnOnWei5; /* 显示延时 */ delay(100); /* 关闭Wei5显示 */ TurnOffWei5; }
数码管动态扫描流程图
本例中LedDisplay函数共需要5358个指令周期,我们把显示函数放在定时器中断服务程序中,通过控制定时间隔来完成对LED数码管的显示扫描。
/* 初始化TimeA_01 */ void TimerA_01_Initialize(void) { P1DIR |= BIT6; // P1.0 output CCTL0 = CCIE; // CCR0 interrupt enabled /* 调节CCRO的值可以控制的LED闪烁频率 */ CCR0 = 10752; // 10ms左右中断扫描一次 TACTL = TASSEL_2 + MC_2; // SMCLK, contmode _BIS_SR(GIE); // Eable interrupt } // Timer A0 interrupt service routine #pragma vector=TIMER0_A0_VECTOR __interrupt void Timer_A (void) { /* Add Offset to CCR0 */ CCR0 += 10752; //CycleCounter=17; /* LED数码管动态扫描,每次点亮1位 */ LedDisplay(1,2,3,4,5); //CycleCounter=5358; }
有以下几点需要注意:
- 定时器的中断服务程序的执行时间要小于中断间隔时间,最好控制在 70% 的中断间隔时间,要给CPU留下足够的时间来执行别的程序。中断服务程序执行时间大于70%定时间隔的话,程序会出现问题
- 用于数码管显示扫描时,定时器的定时间隔不能大于20ms(频率50Hz)
- 此处中断服务程序的时间约为17+5358+1≈5376个MCLK时钟。
- 故CCR0应大于5376/70%=7680;此处我们取CCR0=5376/50%=10752,即预留约50%的时间给CPU处理其他事情,此时定时器的扫描周期约为9.7ms
- 有时候显示程序放到主程序中会跟好,这个要根据需要自行调整,不能生搬硬套。

浙公网安备 33010602011771号