#include "user_ws2812b.h" #include "ws2812b_spi.h" tmosTaskID user_ws2812b_task_id = INVALID_TASK_ID; static uint16_t user_ws2812b_task_process_event(uint8_t task_id, uint16_t events); static void vUser_ws2812b_wrRGB(uint8_t r, uint8_t g, uint8_t b); static user_ws2812b_work_s user_ws2812b_work = { .txStat = false, .count = 0, //灯的数量 .rgbValue = NULL, }; /******************************************************************************* * @函数名称 vUser_ws2812b_set_wrByte * @函数说明 转换ws2812b颜色数据 * @输入参数 byte:字节 color:spi发送数据属猪 * @输出参数 无 * @返回参数 无 *******************************************************************************/ static void vUser_ws2812b_set_wrByte(uint8_t byte, uint8_t *color) { for(uint8_t i = 0; i < 8; i++) { if((byte & 0x80) == 0x80) { *color++ = WS2812B_HIGH; } else { *color++ = WS2812B_LOW; } byte <<= 1; } } /******************************************************************************* * @函数名称 prvUser_ws2812b_set_breath * @函数说明 设置ws2812b 呼吸灯效果 * @输入参数 idx:左边或者右边 * @输出参数 无 * @返回参数 无 *******************************************************************************/ static void prvUser_ws2812b_set_breath(uint8_t idx) { // 应用二次衰减算法(非线性),亮度更柔和自然 uint8_t bri = (user_ws2812b_work.led_param[idx].bright * user_ws2812b_work.led_param[idx].bright) >> 8; // 应用亮度到颜色 uint8_t out_r = ((uint16_t)user_ws2812b_work.led_param[idx].rValue * (uint16_t)bri) >> 8; uint8_t out_g = ((uint16_t)user_ws2812b_work.led_param[idx].gValue * (uint16_t)bri) >> 8; uint8_t out_b = ((uint16_t)user_ws2812b_work.led_param[idx].bValue * (uint16_t)bri) >> 8; vUser_ws2812b_set_wrByte(out_g, &user_ws2812b_work.rgbValue[idx * 24]); vUser_ws2812b_set_wrByte(out_r, &user_ws2812b_work.rgbValue[idx * 24 + 8]); vUser_ws2812b_set_wrByte(out_b, &user_ws2812b_work.rgbValue[idx * 24 + 16]); } /******************************************************************************* * @函数名称 prvUser_ws2812b_txData * @函数说明 发送ws2812b数据 * @输入参数 idx:左边或者右边 * @输出参数 无 * @返回参数 无 *******************************************************************************/ static void prvUser_ws2812b_txData(void) { bWs2812b_spi_WriteByte(user_ws2812b_work.rgbValue, user_ws2812b_work.count * 3 * 8); } /******************************************************************************* * @函数名称 vUser_ws2812b_left_time_task * @函数说明 ws2812b时间循环任务 * @输入参数 无 * @输出参数 无 * @返回参数 无 *******************************************************************************/ static void vUser_ws2812b_check(void) { if(user_ws2812b_work.txStat == false) { bool stat = false; for(uint8_t i = 0; i < user_ws2812b_work.count; i++) { if(user_ws2812b_work.led_param[i].change == true) { user_ws2812b_work.led_param[i].change = false; stat = true; prvUser_ws2812b_set_breath(i); } } if(stat == true) { prvUser_ws2812b_txData(); } } } /******************************************************************************* * @函数名称 vUser_ws2812b_time_task * @函数说明 ws2812b时间循环任务 * @输入参数 无 * @输出参数 无 * @返回参数 无 *******************************************************************************/ static void vUser_ws2812b_time_task(void) { vUser_ws2812b_check(); } /******************************************************************************* * @函数名称 user_charge_task_process_event * @函数说明 task的event处理回调函数,需要在注册task时候,传进去 * @输入参数 task_id:任务ID events:事件 * @输出参数 无 * @返回参数 无 *******************************************************************************/ static uint16_t user_ws2812b_task_process_event(uint8_t task_id, uint16_t events) { //event 处理 if(events & (1 << WS2812B_QUEUE_TIME)) { vUser_ws2812b_time_task(); return (events ^ (1 << WS2812B_QUEUE_TIME)); //异或的方式清除该事件运行标志,并返回未运行的事件标志 } if(events & (1 << WS2812B_QUEUE_INT)) { return (events ^ (1 << WS2812B_QUEUE_INT)); //异或的方式清除该事件运行标志,并返回未运行的事件标志 } return 0; } /******************************************************************************* * @函数名称 vUser_ws2812b_task_start * @函数说明 任务开始 * @输入参数 无 * @输出参数 无 * @返回参数 无 *******************************************************************************/ void vUser_ws2812b_task_start(void) { bStatus_t stat = tmos_start_reload_task(user_ws2812b_task_id, (1 << WS2812B_QUEUE_TIME), MS1_TO_SYSTEM_TIME(USER_WS2812B_INTERVAL)); } /******************************************************************************* * @函数名称 vUser_ws2812b_init * @函数说明 初始化 * @输入参数 无 * @输出参数 无 * @返回参数 无 *******************************************************************************/ void vUser_ws2812b_init(uint8_t count) { user_ws2812b_work.count = count; user_ws2812b_work.led_param = (ws2812b_led_param_s *)malloc(count * sizeof(ws2812b_led_param_s)); user_ws2812b_work.rgbValue = (uint8_t *)malloc(count * 3 * 8); for(int i = 0; i < count; i++) { user_ws2812b_work.led_param[i].change = false; //是否有变化 user_ws2812b_work.led_param[i].bright = 0; //灯亮度 user_ws2812b_work.led_param[i].rValue = 0; user_ws2812b_work.led_param[i].gValue = 0; user_ws2812b_work.led_param[i].bValue = 0; } ws2812b_spi_Init(); Ws2812b_spi_dma_init(user_ws2812b_work.rgbValue, user_ws2812b_work.count * 3 * 8); user_ws2812b_task_id = TMOS_ProcessEventRegister(user_ws2812b_task_process_event); PRINT("user_ws2812b_task_id=%d\n", user_ws2812b_task_id); } /******************************************************************************* * @函数名称 vUser_ws2812b_set_tx_stat * @函数说明 设置数据发射状态 * @输入参数 stat:状态 * @输出参数 无 * @返回参数 无 *******************************************************************************/ void vUser_ws2812b_set_tx_stat(bool stat) { user_ws2812b_work.txStat = stat; } /******************************************************************************* * @函数名称 vUser_ws2812b_set_stat * @函数说明 设置RGB灯状态 * @输入参数 idx:灯下标 r:红色值 g:绿色值 b:蓝色值 bright:亮度 * @输出参数 无 * @返回参数 无 *******************************************************************************/ void vUser_ws2812b_set_stat(uint8_t idx, uint8_t r, uint8_t g, uint8_t b, uint8_t bright) { PRINT("idx=%d,r=%02X,g=%02X,b=%02X,bright=%dms\n",idx, r,g,b,bright); user_ws2812b_work.led_param[idx].rValue = r; user_ws2812b_work.led_param[idx].gValue = g; user_ws2812b_work.led_param[idx].bValue = b; user_ws2812b_work.led_param[idx].bright = bright; user_ws2812b_work.led_param[idx].change = true; }