数据时序图
0,1码的高低电平时间:
[单片机框架] [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) {
上一篇:C语言中使用 #pragma pack 和 __attribute(aligned(n)) 【非常有用的字节对齐用法说明】
下一篇:[单片机框架] [onewire] 利用单线协议来点亮WS2812X 模拟IO 兼容带OS
推荐阅读最新更新时间:2024-11-11 10:38
设计资源 培训 开发板 精华推荐
- 使用 Analog Devices 的 LTC3130IMSE-1 的参考设计
- 2021年C题-三端口DC-DC变换器+波形调不队
- DC2132A,使用 LTC3632 降压稳压器的演示板,24V,3A 恒压,恒流工作台电源
- 具有可调输出电压的 TS1117B 1A 低压差正电压稳压器的典型应用
- 基于ESP32的NES游戏掌机
- 具有 6V 输入 UVLO 的 LTC3633AEFE-1 3.3V/1.8V 顺序降压稳压器的典型应用电路
- LT6656ACS6-3、3V 精密电流和升压电压基准的典型应用
- CMCS002-2M-8,用于CMCS002控制器/FPGA模块的EP3C25模块
- 具有软启动功能的 LT124XCJ8 高速电流模式脉宽调制器的典型应用电路
- OP495GPZ单电源仪表放大器的典型应用