[单片机框架] [app_led] [WS2812x] 利用软定时器实现WS2812x闪烁和呼吸等灯光模式

发布者:MysticGlow最新更新时间:2022-09-16 来源: csdn关键字:软定时器 手机看文章 扫描二维码
随时随地手机看文章

在这里插入图片描述

image.png

在这里插入图片描述

数据时序图

0,1码的高低电平时间:

image.png

在这里插入图片描述


[单片机框架] [onewire] 利用单线协议来点亮WS2812X 模拟IO 兼容带OS


/********************************************************************************

* @file    led_ws2812x.c

* @author  jianqiang.xue

* @version V1.0.0

* @date    2021-11-23

* @brief   LED灯光,OneWire控制

* @example

#include "business_function.h"

#include "app_led.h"

// 初始化APP_LED(创建软定时器)

app_led_init();

// 关闭灯光

app_led_indicate(LED_DRIVEN_WS2812, APP_LED_ID_0, LED_TYPE_OFF, 0, 0);

********************************************************************************/

/* Includes ------------------------------------------------------------------*/

#include

#include

#include


#include "app_led.h"

#include "onewire.h"

#include "os_api.h"

#include "rgb_hsv.h"

/* Private Includes ----------------------------------------------------------*/

#include "business_gpio.h"

#include "business_function.h"


/* Private Define ------------------------------------------------------------*/

#define BYTE_0(n)   ((uint8_t)((n) & (uint8_t)0xFF))        /*!< Returns the low byte of the 32-bit value */

#define BYTE_1(n)   ((uint8_t)(BYTE_0((n) >> (uint8_t)8)))  /*!< Returns the second byte of the 32-bit value */

#define BYTE_2(n)   ((uint8_t)(BYTE_0((n) >> (uint8_t)16))) /*!< Returns the third byte of the 32-bit value */

#define BYTE_3(n)   ((uint8_t)(BYTE_0((n) >> (uint8_t)24)))

/* Private Macro -------------------------------------------------------------*/

#if BS_APP_LED_WS2812_DRIVEN_MODE

#if BS_WS2812_CH0_EN

static void timer_ws2812_0_light_control(void const *arg);

#endif

#if BS_WS2812_CH1_EN

static void timer_ws2812_1_light_control(void const *arg);

#endif

#if BS_WS2812_CH2_EN

static void timer_ws2812_2_light_control(void const *arg);

#endif

#if BS_WS2812_CH3_EN

static void timer_ws2812_3_light_control(void const *arg);

#endif

#endif

/* Private Typedef -----------------------------------------------------------*/

static bool g_app_led_init = false;

// 定义led灯光结构体类型

typedef struct

{

    app_led_id_t     led_id;               // 组号

    app_led_type_t   type;                 // 0--灭灯  1--常亮  2--呼吸  3--快闪

    bool             level_logic;          // 0--低电平亮  1--高电平亮

    char            *timer_id;             // 软定时器id

    uint32_t         period_max;           // 重装载值(最大值)                   --> 对WS2812来说,则是挂载了多少个灯

    uint16_t         cycle_time;           // 定时器轮询时间(灭灯和常亮只执行一次)

    uint32_t         period;               // 重装载值(控制值)                   --> 对WS2812来说,则是RGB值

    // 下面不用填写,仅用于临时计算

    uint8_t          temp_dir;             // 用于方向 0--up 1--keep 2--down

    uint16_t         temp_times;           // 用于计次

} app_led_t;


// 定义软定时器,用于实现灯光效果

#if BS_APP_LED_WS2812_DRIVEN_MODE

#if BS_WS2812_CH0_EN

os_timer_def(ws2812_0, timer_ws2812_0_light_control);

app_led_t app_led_ws2812_0 = {APP_LED_ID_0, LED_TYPE_OFF, 0, NULL, BS_WS2812_CH0_NUM, 0, 0, 1, 0};

#endif

#if BS_WS2812_CH1_EN

os_timer_def(ws2812_1, timer_ws2812_1_light_control);

app_led_t app_led_ws2812_1 = {APP_LED_ID_1, LED_TYPE_OFF, 0, NULL, BS_WS2812_CH1_NUM, 0, 0, 1, 0};

#endif

#if BS_WS2812_CH2_EN

os_timer_def(ws2812_2, timer_ws2812_2_light_control);

app_led_t app_led_ws2812_2 = {APP_LED_ID_2, LED_TYPE_OFF, 0, NULL, BS_WS2812_CH2_NUM, 0, 0, 1, 0};

#endif

#if BS_WS2812_CH3_EN

os_timer_def(ws2812_3, timer_ws2812_3_light_control);

app_led_t app_led_ws2812_3 = {APP_LED_ID_3, LED_TYPE_OFF, 0, NULL, BS_WS2812_CH3_NUM, 0, 0, 1, 0};

#endif

#endif

/* Private Function Prototypes ----------------------------------------------*/

/********************[灯光类型]对内接口函数*************************************/

/**

 * @brief  关闭灯光

 * @param  *app_led: led灯光结构体指针

 */

static void led_type_off(app_led_t *app_led)

{

    uint8_t temp[3] = {0, 0 ,0};

    onewire_send_data(app_led->led_id, temp, 3);

}

/**

 * @brief  灯光常亮

 * @param  *app_led: led灯光结构体指针

 */

static void led_type_light(app_led_t *app_led)

{

    uint8_t temp[3] = {BYTE_1(app_led->period), BYTE_2(app_led->period), BYTE_0(app_led->period)}; // GRB

    onewire_send_data(app_led->led_id, temp, 3);

}


///**

// * @brief  灯光由暗变亮

// * @note   渐变效果由cycle_time决定

// * @param  *app_led: led灯光结构体指针

// */

//static void led_type_rise_slowly(app_led_t *app_led)

//{

//    if (app_led->type != LED_TYPE_RISE_SLOWLY)

//    {

//        return;

//    }

//    app_led->temp_times++;

//    if (app_led->temp_times == 257)

//    {

//        return;

//    }

//    uint8_t temp[3]; // GRB

//    float h, s, v;

//    rgb2hsv(BYTE_2(app_led->period), BYTE_1(app_led->period), BYTE_0(app_led->period), &h, &s, &v);

//    v = (float)(app_led->temp_times) / 256;

//    hsv2rgb(h, s, v, &temp[1], &temp[0], &temp[2]);


//    bsp_onewire_send_data(temp, 3);

//    os_timer_start((os_timer_id)(app_led->timer_id), app_led->cycle_time);

//}


///**

// * @brief  灯光由亮变暗

// * @note   渐变效果由cycle_time决定

// * @param  *app_led: led灯光结构体指针

// */

//static void led_type_fall_slowly(app_led_t *app_led)

//{

//    if (app_led->type != LED_TYPE_RISE_SLOWLY)

//    {

//        return;

//    }

//    app_led->temp_times++;

//    if (app_led->temp_times == 257)

//    {

//        return;

//    }

//    uint8_t temp[3]; // GRB

//    float h, s, v;

//    rgb2hsv(BYTE_2(app_led->period), BYTE_1(app_led->period), BYTE_0(app_led->period), &h, &s, &v);

//    v = (float)(256 - app_led->temp_times) / 256;

//    hsv2rgb(h, s, v, &temp[1], &temp[0], &temp[2]);


//    bsp_onewire_send_data(temp, 3);

//    os_timer_start((os_timer_id)(app_led->timer_id), app_led->cycle_time);

//}


/**

 * @brief  灯光呼吸效果

 * @note   呼吸频率由cycle_time决定

 * @param  *app_led: led灯光结构体指针

 */

static void led_type_breath(app_led_t *app_led)

{

    if (app_led->type != LED_TYPE_BREATH)

    {

        return;

    }


    uint16_t time = 0;

    uint8_t temp[3]; // GRB

    float h, s, v;


    if (app_led->temp_dir == 0)

    {

        app_led->temp_times++;

    }

    else if (app_led->temp_dir == 1)

    {

        app_led->temp_dir = 2;

        time = 255;

        goto end;

    }

    else if (app_led->temp_dir == 2)

    {

        app_led->temp_times--;

    }


    if (app_led->temp_times == 257)

    {

        app_led->temp_dir = 1;

    }

    else if (app_led->temp_times == 0)

    {

        app_led->temp_dir = 0;

        time = 255;

        goto end;

    }

    time = app_led->cycle_time;

end:

    rgb2hsv(BYTE_2(app_led->period), BYTE_1(app_led->period), BYTE_0(app_led->period), &h, &s, &v);

    v = (float)(app_led->temp_times) / 256;

    hsv2rgb(h, s, v, &temp[1], &temp[0], &temp[2]);


    onewire_send_data(app_led->led_id, temp, 3);

    os_timer_start((os_timer_id)(app_led->timer_id), time);

}


/**

 * @brief  灯光闪烁

 * @note   闪烁频率由cycle_time决定

 * @param  *app_led: led灯光结构体指针

 */

static void led_type_twinkle(app_led_t *app_led)

{

    if (app_led->type != LED_TYPE_TWINKLE)

    {

        return;

    }


    if (app_led->temp_dir == 0)

    {

        led_type_light(app_led);

        app_led->temp_dir = 1;

    }

    else

    {

        led_type_off(app_led);

        app_led->temp_dir = 0;

    }

    os_timer_start((os_timer_id)(app_led->timer_id), app_led->cycle_time);

}


/**

 * @brief  灯光SOS灯效

 * @param  *app_led: led灯光结构体指针

 */

static void led_type_sos(app_led_t *app_led)

{

    if (app_led->type != LED_TYPE_SOS)

    {

        return;

    }


    uint16_t time = 0;

    if (app_led->temp_dir == 0)

    {

        app_led->temp_dir = 1;

        led_type_light(app_led);

        time = 100;

        goto end;

    }

    else if (app_led->temp_dir == 1)

    {

        app_led->temp_times++;

        app_led->temp_dir = 0;

        if (app_led->temp_times > 2)

        {

[1] [2] [3]
关键字:软定时器 引用地址:[单片机框架] [app_led] [WS2812x] 利用软定时器实现WS2812x闪烁和呼吸等灯光模式

上一篇:C语言中使用 #pragma pack 和 __attribute(aligned(n)) 【非常有用的字节对齐用法说明】
下一篇:[单片机框架] [onewire] 利用单线协议来点亮WS2812X 模拟IO 兼容带OS

推荐阅读最新更新时间:2024-11-11 10:38

[单片机框架][bsp层][nrf51822][nrf51422][nrf51802][bsp_rng] rng随机数生成器配置和使用
Random Number Generator (RNG) The Random Number Generator (RNG) generates true non-deterministic random numbers derived from thermal noise that are suitable for cryptographic purposes. The RNG does not require a seed value. 随机数生成器(RNG)从热噪声中生成真实的非确定性随机数,适合于加密目的。 RNG不需要种子值。 /*****************************************
[单片机]
单片机---HLK-W801图形框架LVGL下开发(三)
2022.2.21日的效果如下 w801上移植lvgl,并增加APP模拟 中文支持 全世界都在学中国话 孔夫子的话 越来越国际化 全世界都在讲中国话 我们说的话 让世界都认真听话 by-S.H.E 所以汉化已经迫在眉睫了。 定制字体 首先,我们要生成一个小型的字库,因为我们用在单片机上,全部放进去没有任何意义,我们只用了几个汉字,所以定制一个小型字库,是最好的方法。 lvgl提供了在线生成字体文件的方式 ------在线地址------ 我这里只是把主页上的图标(button上的
[单片机]
<font color='red'>单片机</font>---HLK-W801图形<font color='red'>框架</font>LVGL下开发(三)
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved