一 背景
最近接觸到了RGB彩燈,這種燈的驅動方式一般有兩種,一種是使用專門的驅動IC,可能是I2C接口也可能是SPI接口,發送一些指令來實現驅動的目的,另外一種是直接使用PWM方式驅動,根據三路PWM設置的DUTY比例來實現顯示不同的顏色,我們可以設置最大DUTY為255,顏色可以參考標準的24位RGB定義。
二 實現三種不同的顯示效果
2.1 顯示指定顏色長亮
在三個PWM值都為0時燈是滅的狀態
我們可以寫一個接口函數,輸入參數是顏色值
void drv_rgbled_setcolor(uint32_t set_val)
{
rgbled_r_pwmset((uint8_t)(set_val >?>16));
rgbled_g_pwmset((uint8_t)(set_val >?>8));
rgbled_b_pwmset((uint8_t)(set_val));
}
2.2 實現閃爍效果
在pwm關閉的時候燈也是滅的狀態,我們可以通過使能PWM的方式來完成閃爍功能,我們也可以記錄下當前燈的顏色,在關閉時設置為0,在非0時保存顏色值,打開時使用之前的顏色值即可,做一個接口來實現開關RGB燈條
static uint32_t s_current_rgbled_color = 0;
void drv_rgbled_setcolor(uint32_t set_val)
{
rgbled_r_pwmset((uint8_t)(set_val >?>16));
rgbled_g_pwmset((uint8_t)(set_val >?>8));
rgbled_b_pwmset((uint8_t)(set_val));
if (set_val)
{
s_current_rgbled_color = set_val;
}
}
void drv_rgbled_enbale(uint8_t set_en)
{
if (!set_en)
{
drv_rgbled_setcolor(0);
}
else
{
drv_rgbled_setcolor(s_current_rgbled_color);
}
2.3 實現呼吸效果
如果要實現一個藍色呼吸燈的效果,我們首先知道的是藍色燈100%亮度的值是0x0000FF,如果要實現50%藍色燈的效果就需要對三個顏色分量乘以等比例系數0.5,我們可以實現一個設置亮度的接口函數
void drv_rgbled_brightness(uint8_t set_val,uint8_t max_val)
{
uint32_t get_color = s_current_rgbled_color;
uint8_t get_r = (uint8_t)(get_color >?>16);
uint8_t get_g = (uint8_t)(get_color >?>8);
uint8_t get_b = (uint8_t)(get_color);
uint8_t set_val_r = get_r*set_val/max_val;
uint8_t set_val_g = get_g*set_val/max_val;
uint8_t set_val_b = get_b*set_val/max_val;
rgbled_r_pwmset(set_val_r);
rgbled_g_pwmset(set_val_g);
rgbled_b_pwmset(set_val_b);
}
2.4 應用層
在任務中需要對閃爍時間進行計數,控制呼吸燈的狀態
#define CONFIG_RGBLED_FLASH_IVT_MS 500
#define CONFIG_RGBLED_BREATH_BRIGHTNESS_MAX 100
#define CONFIG_RGBLED_BREATH_CHANGE_MS 1500
#define CONFIG_RGBLED_BREATH_IVT_MS (CONFIG_RGBLED_BREATH_CHANGE_MS/CONFIG_RGBLED_BREATH_BRIGHTNESS_MAX)
#define CONFIG_TASK_IVT_MS 15
typedef enum
{
S_RGBLED_OFF,
S_RGBLED_ON,
S_RGBLED_FLASH,
S_RGBLED_BREATH
}rgbled_workstatus_t;
typedef enum
{
BRS_RGBLED_REDUCE,
BRS_RGBLED_INCREASE,
}rgbled_breathstatus_t;
uint32_t rgbled_workstatus = S_RGBLED_OFF;
uint32_t rgbled_flash_ivt_count_ms = 0;
uint32_t rgbled_flash_status = 0;
uint32_t rgbled_breath_ivt_count_ms = 0;
uint32_t rgbled_breath_status = 0;
uint32_t rgbled_breath_brightness = CONFIG_RGBLED_BREATH_BRIGHTNESS_MAX;
void task_entry_main(void *parameter)
{
while(1)
{
if (S_RGBLED_FLASH == rgbled_workstatus)
{
rgbled_flash_ivt_count_ms++;
if (rgbled_flash_ivt_count_ms >= CONFIG_RGBLED_FLASH_IVT_MS)
{
rgbled_flash_ivt_count_ms = 0;
rgbled_flash_status = !rgbled_flash_status;
drv_rgbled_enbale(rgbled_flash_status);
}
}
else if (S_RGBLED_BREATH == rgbled_workstatus)
{
rgbled_breath_ivt_count_ms++;
if (rgbled_breath_ivt_count_ms >= (CONFIG_RGBLED_BREATH_IVT_MS/CONFIG_TASK_IVT_MS))
{
rgbled_breath_ivt_count_ms = 0;
if (BRS_RGBLED_REDUCE == rgbled_breath_status)
{
if (rgbled_breath_brightness > 0)
{
rgbled_breath_brightness--;
}
else
{
rgbled_breath_brightness = 0;
rgbled_breath_status = BRSBRS_RGBLED_INCREASE;
}
}
else if (BRSBRS_RGBLED_INCREASE == rgbled_breath_status)
{
if (rgbled_breath_brightness < CONFIG_RGBLED_BREATH_BRIGHTNESS_MAX)
{
rgbled_breath_brightness++;
}
else
{
rgbled_breath_brightness = CONFIG_RGBLED_BREATH_BRIGHTNESS_MAX;
rgbled_breath_status = BRS_RGBLED_REDUCE;
}
}
drv_rgbled_brightness(rgbled_breath_brightness,CONFIG_RGBLED_BREATH_BRIGHTNESS_MAX);
}
}
task_mdelay(CONFIG_TASK_IVT_MS);
}
}
評論
查看更多