在实现呼吸灯效果时,我遇到了一个实际运行中的问题,比如在亮度变化的边界值(如`Compare=0`)处出现卡顿。本文将分享一些如何优化呼吸灯函数的经验,使其亮度变化更加平滑。
原始代码逻辑上看似正确,但在实际运行中会遇到卡顿问题:
for(Compare=0; Compare<=100; Compare++)
{
PWM_SetCompare1(Compare);
Delay_ms(10);
OLED_ShowNum(1,9,Compare,2);
}
for(Compare=100; Compare>=0; Compare--)
{
PWM_SetCompare1(Compare);
Delay_ms(10);
OLED_ShowNum(1,9,Compare,2);
}
这种写法可能会有一个问题,如果Compare
的类型是无符号类型(比如unsigned int
),当Compare
递减到0之后,再减一就会变成一个非常大的正数,而不是负数,从而导致循环条件一直成立,进而导致PWM占空比被设置为一个无效的值或者直接卡住在某个值上,导致灯常亮。另外,在亮度从0
变到100
时,可能会出现卡顿,影响视觉效果。
优化方案
方法一:添加过渡时间
在两个循环之间增加一个短暂的延迟,使亮度变化更加平滑。
for(Compare=0; Compare<=100; Compare++)
{
PWM_SetCompare1(Compare);
Delay_ms(10);
OLED_ShowNum(1, 9, Compare, 2);
}
// 添加过渡时间
Delay_ms(100);
for(Compare=0; Compare<=100; Compare++)
{
PWM_SetCompare1(100 - Compare);
Delay_ms(10);
OLED_ShowNum(1, 9, 100 - Compare, 2);
}
方法二:使用单个循环
将增亮和变暗的过程合并到一个循环中,避免中间的停顿。
for(Compare=0; Compare<=200; Compare++)
{
if (Compare <= 100) {
PWM_SetCompare1(Compare);
OLED_ShowNum(1, 9, Compare, 2);
} else {
PWM_SetCompare1(200 - Compare);
OLED_ShowNum(1, 9, 200 - Compare, 2);
}
Delay_ms(10);
}
在这个方法中,`Compare`从0到200,当`Compare`小于等于100时是增亮过程,当`Compare`大于100时是变暗过程。
解决思路
1. 变量类型 :可以让`Compare`是有符号类型(如`int`),避免在递减操作时出现意外问题。
2. 延迟时间一致性 :增亮和变暗过程的延迟时间应一致,保证亮度变化平滑。
3. 过渡处理 :在循环之间添加过渡时间或无缝衔接,避免亮度在边界值处卡顿。
结论
通过调整延迟时间、改变变量类型以及无缝衔接亮度变化过程,可以有效避免呼吸灯控制中的卡顿问题,使亮度变化更加平滑。希望本文的优化方法和总结能对你实现呼吸灯效果有所帮助。