| 引脚编号 | 引脚名称 | 说明 |
|---|---|---|
| 1 | DO | 控制数据信号输出端 |
| 2 | DI | 控制数据信号输入端 |
| 3 | VCC | 控制电路电源正极 |
| 4 | NC | 空脚 |
| 5 | VDD | LED电源正极 |
| 6 | VSS | 电源负极 |
数据时序图
0,1码的高低电平时间:
| 电平 | 描述 | 时间 |
|---|---|---|
| T0H | 0 码, 高电平时间 | 0.35us ±150ns |
| T0L | 0 码, 低电平时间 | 0.8us ±150ns |
| T1H | 1 码, 高电平时间 | 0.7us ±150ns |
| T1L | 1 码, 低电平时间 | 0.6us ±150ns |
| RES | 低电平时间 | 约 >50us |
TH+TL=1.25μs±600ns
[单片机框架] [onewire] 利用单线协议来点亮WS2812X 模拟IO 兼容带OS
#include#include #include #include "app_led.h" #include "onewire.h" #include "os_api.h" #include "rgb_hsv.h" #include "business_gpio.h" #include "business_function.h" #define BYTE_0(n) ((uint8_t)((n) & (uint8_t)0xFF)) #define BYTE_1(n) ((uint8_t)(BYTE_0((n) >> (uint8_t)8))) #define BYTE_2(n) ((uint8_t)(BYTE_0((n) >> (uint8_t)16))) #define BYTE_3(n) ((uint8_t)(BYTE_0((n) >> (uint8_t)24))) #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 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 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); } 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); } // //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); //} // //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); //} 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); } 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); } 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) { app_led->temp_times = 0; app_led->temp_dir = 2; } led_type_off(app_led); time = 200; goto end; } else if (app_led->temp_dir == 2) { app_led->temp_dir = 3; led_type_light(app_led); time = 800; goto end; } else if (app_led->temp_dir == 3) { app_led->temp_times++; app_led->temp_dir = 2; if (app_led->temp_times > 2) { app_led->temp_times = 0; app_led->temp_dir = 0; } led_type_off(app_led); time = 200; goto end; } else { app_led->temp_dir = 0; } end: os_timer_start((os_timer_id)(app_led->timer_id), time); } static void led_type_red_blue_twinkle(app_led_t *app_led) { if (app_led->type != LED_TYPE_RED_BLUE_TWINKLE) { return; } uint16_t time = 0; if (app_led->temp_dir == 0) { app_led->temp_dir = 1; app_led->period = COLOR_RED; led_type_light(app_led); time = 150; goto end; } else if (app_led->temp_dir == 1) { app_led->temp_times++; app_led->temp_dir = 0; if (app_led->temp_times > 2) { app_led->temp_times = 0; app_led->temp_dir = 2; } app_led->period = COLOR_BLUE; led_type_light(app_led); time = 150; goto end; } else if (app_led->temp_dir == 2) { app_led->temp_dir = 3; app_led->period = COLOR_RED; led_type_light(app_led); time = 500; goto end; } else if (app_led->temp_dir == 3) { app_led->temp_times++; app_led->temp_dir = 2; if (app_led->temp_times > 2) { app_led->temp_times = 0; app_led->temp_dir = 0; } app_led->period = COLOR_BLUE; led_type_light(app_led); time = 500; goto end; } else { time = 1000; app_led->temp_dir = 0; app_led->temp_times = 0; led_type_off(app_led); } end: os_timer_start((os_timer_id)(app_led->timer_id), time); } #if BS_APP_LED_WS2812_DRIVEN_MODE #if BS_WS2812_CH0_EN static void timer_ws2812_0_light_control(void const *arg) { if (app_led_ws2812_0.type == LED_TYPE_OFF) { led_type_light(&app_led_ws2812_0); } else if (app_led_ws2812_0.type == LED_TYPE_LIGHT) { led_type_light(&app_led_ws2812_0); } else if (app_led_ws2812_0.type == LED_TYPE_BREATH) { led_type_breath(&app_led_ws2812_0); } else if (app_led_ws2812_0.type == LED_TYPE_TWINKLE) { led_type_twinkle(&app_led_ws2812_0); } else if (app_led_ws2812_0.type == LED_TYPE_SOS) { led_type_sos(&app_led_ws2812_0); } // else if (app_led_ws2812_0.type == LED_TYPE_RISE_SLOWLY) // { // led_type_rise_slowly(&app_led_ws2812_0); // } // else if (app_led_ws2812_0.type == LED_TYPE_FALL_SLOWLY) // { // led_type_fall_slowly(&app_led_ws2812_0); // } else if (app_led_ws2812_0.type == LED_TYPE_RED_BLUE_TWINKLE) { led_type_red_blue_twinkle(&app_led_ws2812_0); } } #endif #if BS_WS2812_CH1_EN static void timer_ws2812_1_light_control(void const *arg) { if (app_led_ws2812_1.type == LED_TYPE_OFF) { led_type_light(&app_led_ws2812_1); } else if (app_led_ws2812_1.type == LED_TYPE_LIGHT) { led_type_light(&app_led_ws2812_1); } else if (app_led_ws2812_1.type == LED_TYPE_BREATH) { led_type_breath(&app_led_ws2812_1); } else if (app_led_ws2812_1.type == LED_TYPE_TWINKLE) { led_type_twinkle(&app_led_ws2812_1); } else if (app_led_ws2812_1.type == LED_TYPE_SOS) { led_type_sos(&app_led_ws2812_1); } else if (app_led_ws2812_1.type == LED_TYPE_RISE_SLOWLY) { led_type_rise_slowly(&app_led_ws2812_1); } else if (app_led_ws2812_1.type == LED_TYPE_FALL_SLOWLY) { led_type_fall_slowly(&app_led_ws2812_1); } } #endif #if BS_WS2812_CH2_EN static void timer_ws2812_2_light_control(void const *arg) { if (app_led_ws2812_2.type == LED_TYPE_OFF) { led_type_light(&app_led_ws2812_2); } else if (app_led_ws2812_2.type == LED_TYPE_LIGHT) { led_type_light(&app_led_ws2812_2); } else if (app_led_ws2812_2.type == LED_TYPE_BREATH) { led_type_breath(&app_led_ws2812_2); } else if (app_led_ws2812_2.type == LED_TYPE_TWINKLE) { led_type_twinkle(&app_led_ws2812_2); } else if (app_led_ws2812_2.type == LED_TYPE_SOS) { led_type_sos(&app_led_ws2812_2); } else if (app_led_ws2812_2.type == LED_TYPE_RISE_SLOWLY) { led_type_rise_slowly(&app_led_ws2812_2); } else if (app_led_ws2812_2.type == LED_TYPE_FALL_SLOWLY) { led_type_fall_slowly(&app_led_ws2812_2); } } #endif #if BS_WS2812_CH3_EN static void timer_ws2812_3_light_control(void const *arg) { if (app_led_ws2812_3.type == LED_TYPE_OFF) { led_type_light(&app_led_ws2812_3); } else if (app_led_ws2812_3.type == LED_TYPE_LIGHT) { led_type_light(&app_led_ws2812_3); } else if (app_led_ws2812_3.type == LED_TYPE_BREATH) { led_type_breath(&app_led_ws2812_3); } else if (app_led_ws2812_3.type == LED_TYPE_TWINKLE) { led_type_twinkle(&app_led_ws2812_3); } else if (app_led_ws2812_3.type == LED_TYPE_SOS) { led_type_sos(&app_led_ws2812_3); } else if (app_led_ws2812_3.type == LED_TYPE_RISE_SLOWLY) { led_type_rise_slowly(&app_led_ws2812_3); } else if (app_led_ws2812_3.type == LED_TYPE_FALL_SLOWLY) { led_type_fall_slowly(&app_led_ws2812_3); } } #endif #endif static app_led_t *get_app_led(app_led_id_t led_id) { if (led_id == APP_LED_ID_0) { #if BS_APP_LED_WS2812_DRIVEN_MODE && BS_WS2812_CH0_EN return &app_led_ws2812_0; #else return NULL; #endif } #if BS_APP_LED_WS2812_DRIVEN_MODE && BS_WS2812_CH1_EN else if (led_id == APP_LED_ID_1) { return &app_led_ws2812_1; } #endif #if BS_APP_LED_WS2812_DRIVEN_MODE && BS_WS2812_CH2_EN else if (led_id == APP_LED_ID_2) { return &app_led_ws2812_2; } #endif #if BS_APP_LED_WS2812_DRIVEN_MODE && BS_WS2812_CH3_EN else if (led_id == APP_LED_ID_3) { return &app_led_ws2812_3; } #endif return NULL; } void led_ws2812_init(void) { if (g_app_led_init) { return; } g_app_led_init = true; uint32_t timer_err_ret = 0; #if BS_APP_LED_WS2812_DRIVEN_MODE #if BS_WS2812_CH0_EN app_led_ws2812_0.timer_id = (char *)os_timer_create(os_timer(ws2812_0), OS_TIMER_ONCE, &timer_err_ret); #endif #if BS_WS2812_CH1_EN app_led_ws2812_1.timer_id = (char *)os_timer_create(os_timer(ws2812_1), OS_TIMER_ONCE, &timer_err_ret); #endif #if BS_WS2812_CH2_EN app_led_ws2812_2.timer_id = (char *)os_timer_create(os_timer(ws2812_2), OS_TIMER_ONCE, &timer_err_ret); #endif #if BS_WS2812_CH3_EN app_led_ws2812_3.timer_id = (char *)os_timer_create(os_timer(ws2812_3), OS_TIMER_ONCE, &timer_err_ret); #endif #endif } uint16_t app_led_ws2812_get_current_period(app_led_id_t led_id) { app_led_t *app_led = get_app_led(led_id); return app_led->period; } app_led_type_t app_led_ws2812_get_current_type(app_led_id_t led_id) { app_led_t *app_led = get_app_led(led_id); return app_led->type; } bool app_led_ws2812_ioctl(app_led_id_t led_id, app_led_type_t type, uint16_t cycle_time, uint32_t period) { app_led_t *led_info = NULL; led_info = get_app_led(led_id); if (led_info == NULL) { return false; } led_info->temp_dir = 0; led_info->temp_times = 0; led_info->cycle_time = cycle_time; led_info->type = type; if (type == LED_TYPE_OFF) { led_info->period = 0; } else { led_info->period = period; } os_timer_start((os_timer_id)(led_info->timer_id), 1); return true; }


![[单片机框架] [app [单片机框架] [app](http://www.mshxw.com/aiimages/31/656912.png)
