二元一次方程在呼吸灯上的应用

2019-04-15 13:38发布

我一直想用一个简单的表达式把呼吸灯效果表达出来。搜索了一下,大家都是千篇一律。我看稍微有点想法的也是说用sin(x)函数实现,还有人说有matlab。我只是想说,对于一个2MHz的单片机,你们的要求太高了。
我只是追求用最简单,而且运算量不大的C代码实现。抛物线函数足够了,开口向下的,还要过原点(0,0),因为起始灯是熄灭的。
二元一次方程最适合。参数a,b,c的c=0,因为过了原点。又由于开口向下,a<0。这些是利用二元一次方程的特性可以看出来。
呼吸灯的亮度无非是控制占空比,通常是在timer控制器设置PWM输出方波信号占空比的分子和分母来实现不同的亮度。分母为最亮值,如果分子y为极限值分母,那么输出信号就为常高。所以是最亮。
说了点最基础的知识。再回到方程。方程有两个根x1,x2,一个是0,一个需要计算一下。 上面方框中的公式就是我们要写成代码的东东。可以看到我们只剩下一个参数需要调节,就是b,因为单片机一般是整数运算,所以我们的抛物线,并不是一个曲线,而是曲线上,一些不连续的点,这个参数b,就是用来调节这些不连续的点的美丽程度的。 在我的 STM8L开发板上,我利用内置的RTC定时触发亮度的变化,参考代码如下: void RTC_callback() {     static int16_t x=0; #define b (int16_t) 3     uint16_t y;     y = (b*x)-((b*b*x*x)/(4*TIM2_PERIOD));     x++;     x=x%((4*TIM2_PERIOD)/b);     TIM2_SetCompare1(y); }

视频http://www.tudou.com/programs/view/0frjMheZDMw/

另外可以看出b越大,你的X的取值范围就越小。这样你的不连续点就太少,导致LED亮度变化可能不那么平滑。