● 改编自国信长天蓝桥杯官方蓝皮书例程,按照自己的习惯进行了补充和修改
蓝桥杯单片机第九届省赛-彩灯控制器
2021.3.30
第九届省赛例程在官方蓝皮书上也有,由于模板用的就是官方的,也就没有粘贴一大段代码的必要性了。仅记录刷题过程中的感悟,和对比官方给出的第九届代码后自己写的代码的不足。
Notes1:动态LED亮度等级
基本原理依旧是PWM输出控制LED亮度,👉PWM控制LED基本原理
基本模板:
uchar Light_Grade; //亮度等级
uchar PWM_High;
uchar PWM_Low = 4;
//以下程序放在1ms定时器中,1ms执行一次。
if(PWM_Low>0)
{
PWM_Low--;
LED_OFF(L4);//关灯
}
else if(PWM_High>0)
{
PWM_High--;
LED_ON(L4);//开灯
}
else
{
PWM_High = Light_Grade;
PWM_Low = 4-Light_Grade;
}
在第九届中对LED亮度的调节可以说是动态LED亮度调节。
刚开始写大约知道应该继续套用这个模板,可是这段程序具体的位置,没能记住。并且在PWM高电平时段内点亮的是LED_Disp(uc_led)
led显示函数。
//以下程序放在1ms定时器中,1ms执行一次。
if(PWM_Low>0)
{
PWM_Low--;
LED_Disp(0x00);
}
else if(PWM_High>0)
{
PWM_High--;
LED_Disp(uc_led);
}
else
{
PWM_High = Light_Grade;
PWM_Low = 4-Light_Grade;
}
关于亮度等级的具体划分:
Notes2:EEPROM第一次上电读取数据的处理
在第九届中,需要将 流转间隔 时间保存到AT24C02 EEPROM中,在下次上电时候自动读取。
可在没有对EEPROM写入任何数据(默认为0)或者写入其他不合理的数据时,读取到的 流转间隔 时间是不合理的(不在400~1200ms范围内或者led乱闪)。
**官方例程在上电还未进入死循环前,读取EEPROM信息后,先判断读取到的信息是否合理(是否在400~1200ms范围内)。若在则直接赋值给流转间隔时间变量
;若不在,则将流转间隔时间变量
初始化为400。
或者将这个操作称为应用前数据合理性的判断
Notes3:LED流水灯的实现方法
我使用的是intrins.h
头文件里的_crol_
,_cror_
循环移位函数实现,数据处理上比较简单,但逻辑上稍微复杂些。
官方例程使用二维数组提前将数据写好,逻辑上简单了太多。
比如在四个流水状态之间的循环切换:
既保证了循环切换的led初始状态又避免了led暂态导致的微亮。
Notes4:暂态与稳态
正确使用暂态与稳态避免led数码管微亮。
Notes5:数码管闪烁的问题再发现
按下按键后,数码管进入闪烁状态,最好是先点亮再熄灭。避免按下按键后短暂时间内看不到变化。