RGB彩灯驱动实现三种不同的显示效果

接口/总线/驱动

1125人已加入

描述

一 背景

最近接触到了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);
    }
}
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分