渐变的原理和电影播放帧原理类似,变化的频率大于人眼刷新频率就可以实现不间断的渐变。人眼的刷新频率一般不超过30Hz,即变化间隔不大于33.3ms。要让灯光实现渐变效果,也只要实现频率大于人眼刷新频率的颜色变化即可。
软件上对实时性要求不高,可以使用软件定时器来实现,相对于使用线程更节省资源,也更容易移植到不跑操作系统的芯片上。
这里我使用Freertos的软件定时器来定时,定时周期30ms。代码基于上一次的工程,增加定时器的代码和渐变的代码。从红色开始,每30ms进入一次定时器回调,对H值进行自增,增加的量值会影响渐变的周期,也就是渐变的速度。
代码如下:
//全局hsb变量 hsb_t hsb = {0, 100, 100}; //软件定时器回调 void timer_callback(xTimerHandle timer_t) { rgb_t rgb; hsb.h += 0.5; //每次增加一定的值,增加此值会缩短渐变周期 if (hsb.h >= 360) { hsb.h -= 360; } hsb_to_rgb(&hsb, &rgb); set_rgb_color(&rgb); } void light_init(void) { //启用PWM通道 HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2); HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3); //创建Freertos软件定时器 xTimerHandle timer = xTimerCreate(NULL, 30 / portTICK_RATE_MS, pdTRUE, NULL, timer_callback); xTimerStart(timer, 0); }