user_ws2812b.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. #include "user_ws2812b.h"
  2. #include "ws2812b_spi.h"
  3. tmosTaskID user_ws2812b_task_id = INVALID_TASK_ID;
  4. static uint16_t user_ws2812b_task_process_event(uint8_t task_id, uint16_t events);
  5. static void vUser_ws2812b_wrRGB(uint8_t r, uint8_t g, uint8_t b);
  6. static user_ws2812b_work_s user_ws2812b_work = {
  7. .txStat = false,
  8. .count = 0, //灯的数量
  9. .rgbValue = NULL,
  10. };
  11. /*******************************************************************************
  12. * @函数名称 vUser_ws2812b_set_wrByte
  13. * @函数说明 转换ws2812b颜色数据
  14. * @输入参数 byte:字节
  15. color:spi发送数据属猪
  16. * @输出参数 无
  17. * @返回参数 无
  18. *******************************************************************************/
  19. static void vUser_ws2812b_set_wrByte(uint8_t byte, uint8_t *color)
  20. {
  21. for(uint8_t i = 0; i < 8; i++)
  22. {
  23. if((byte & 0x80) == 0x80)
  24. {
  25. *color++ = WS2812B_HIGH;
  26. }
  27. else
  28. {
  29. *color++ = WS2812B_LOW;
  30. }
  31. byte <<= 1;
  32. }
  33. }
  34. /*******************************************************************************
  35. * @函数名称 prvUser_ws2812b_set_breath
  36. * @函数说明 设置ws2812b 呼吸灯效果
  37. * @输入参数 idx:左边或者右边
  38. * @输出参数 无
  39. * @返回参数 无
  40. *******************************************************************************/
  41. static void prvUser_ws2812b_set_breath(uint8_t idx)
  42. {
  43. // 应用二次衰减算法(非线性),亮度更柔和自然
  44. uint8_t bri = (user_ws2812b_work.led_param[idx].bright * user_ws2812b_work.led_param[idx].bright) >> 8;
  45. // 应用亮度到颜色
  46. uint8_t out_r = ((uint16_t)user_ws2812b_work.led_param[idx].rValue * (uint16_t)bri) >> 8;
  47. uint8_t out_g = ((uint16_t)user_ws2812b_work.led_param[idx].gValue * (uint16_t)bri) >> 8;
  48. uint8_t out_b = ((uint16_t)user_ws2812b_work.led_param[idx].bValue * (uint16_t)bri) >> 8;
  49. vUser_ws2812b_set_wrByte(out_g, &user_ws2812b_work.rgbValue[idx * 24]);
  50. vUser_ws2812b_set_wrByte(out_r, &user_ws2812b_work.rgbValue[idx * 24 + 8]);
  51. vUser_ws2812b_set_wrByte(out_b, &user_ws2812b_work.rgbValue[idx * 24 + 16]);
  52. }
  53. /*******************************************************************************
  54. * @函数名称 prvUser_ws2812b_txData
  55. * @函数说明 发送ws2812b数据
  56. * @输入参数 idx:左边或者右边
  57. * @输出参数 无
  58. * @返回参数 无
  59. *******************************************************************************/
  60. static void prvUser_ws2812b_txData(void)
  61. {
  62. bWs2812b_spi_WriteByte(user_ws2812b_work.rgbValue, user_ws2812b_work.count * 3 * 8);
  63. }
  64. /*******************************************************************************
  65. * @函数名称 vUser_ws2812b_left_time_task
  66. * @函数说明 ws2812b时间循环任务
  67. * @输入参数 无
  68. * @输出参数 无
  69. * @返回参数 无
  70. *******************************************************************************/
  71. static void vUser_ws2812b_check(void)
  72. {
  73. if(user_ws2812b_work.txStat == false)
  74. {
  75. bool stat = false;
  76. for(uint8_t i = 0; i < user_ws2812b_work.count; i++)
  77. {
  78. if(user_ws2812b_work.led_param[i].change == true)
  79. {
  80. user_ws2812b_work.led_param[i].change = false;
  81. stat = true;
  82. prvUser_ws2812b_set_breath(i);
  83. }
  84. }
  85. if(stat == true)
  86. {
  87. prvUser_ws2812b_txData();
  88. }
  89. }
  90. }
  91. /*******************************************************************************
  92. * @函数名称 vUser_ws2812b_time_task
  93. * @函数说明 ws2812b时间循环任务
  94. * @输入参数 无
  95. * @输出参数 无
  96. * @返回参数 无
  97. *******************************************************************************/
  98. static void vUser_ws2812b_time_task(void)
  99. {
  100. vUser_ws2812b_check();
  101. }
  102. /*******************************************************************************
  103. * @函数名称 user_charge_task_process_event
  104. * @函数说明 task的event处理回调函数,需要在注册task时候,传进去
  105. * @输入参数 task_id:任务ID
  106. events:事件
  107. * @输出参数 无
  108. * @返回参数 无
  109. *******************************************************************************/
  110. static uint16_t user_ws2812b_task_process_event(uint8_t task_id, uint16_t events)
  111. {
  112. //event 处理
  113. if(events & (1 << WS2812B_QUEUE_TIME))
  114. {
  115. vUser_ws2812b_time_task();
  116. return (events ^ (1 << WS2812B_QUEUE_TIME)); //异或的方式清除该事件运行标志,并返回未运行的事件标志
  117. }
  118. if(events & (1 << WS2812B_QUEUE_INT))
  119. {
  120. return (events ^ (1 << WS2812B_QUEUE_INT)); //异或的方式清除该事件运行标志,并返回未运行的事件标志
  121. }
  122. return 0;
  123. }
  124. /*******************************************************************************
  125. * @函数名称 vUser_ws2812b_task_start
  126. * @函数说明 任务开始
  127. * @输入参数 无
  128. * @输出参数 无
  129. * @返回参数 无
  130. *******************************************************************************/
  131. void vUser_ws2812b_task_start(void)
  132. {
  133. bStatus_t stat = tmos_start_reload_task(user_ws2812b_task_id, (1 << WS2812B_QUEUE_TIME), MS1_TO_SYSTEM_TIME(USER_WS2812B_INTERVAL));
  134. }
  135. /*******************************************************************************
  136. * @函数名称 vUser_ws2812b_init
  137. * @函数说明 初始化
  138. * @输入参数 无
  139. * @输出参数 无
  140. * @返回参数 无
  141. *******************************************************************************/
  142. void vUser_ws2812b_init(uint8_t count)
  143. {
  144. user_ws2812b_work.count = count;
  145. user_ws2812b_work.led_param = (ws2812b_led_param_s *)malloc(count * sizeof(ws2812b_led_param_s));
  146. user_ws2812b_work.rgbValue = (uint8_t *)malloc(count * 3 * 8);
  147. for(int i = 0; i < count; i++)
  148. {
  149. user_ws2812b_work.led_param[i].change = false; //是否有变化
  150. user_ws2812b_work.led_param[i].bright = 0; //灯亮度
  151. user_ws2812b_work.led_param[i].rValue = 0;
  152. user_ws2812b_work.led_param[i].gValue = 0;
  153. user_ws2812b_work.led_param[i].bValue = 0;
  154. }
  155. ws2812b_spi_Init();
  156. Ws2812b_spi_dma_init(user_ws2812b_work.rgbValue, user_ws2812b_work.count * 3 * 8);
  157. user_ws2812b_task_id = TMOS_ProcessEventRegister(user_ws2812b_task_process_event);
  158. PRINT("user_ws2812b_task_id=%d\n", user_ws2812b_task_id);
  159. }
  160. /*******************************************************************************
  161. * @函数名称 vUser_ws2812b_set_tx_stat
  162. * @函数说明 设置数据发射状态
  163. * @输入参数 stat:状态
  164. * @输出参数 无
  165. * @返回参数 无
  166. *******************************************************************************/
  167. void vUser_ws2812b_set_tx_stat(bool stat)
  168. {
  169. user_ws2812b_work.txStat = stat;
  170. }
  171. /*******************************************************************************
  172. * @函数名称 vUser_ws2812b_set_stat
  173. * @函数说明 设置RGB灯状态
  174. * @输入参数 idx:灯下标
  175. r:红色值
  176. g:绿色值
  177. b:蓝色值
  178. bright:亮度
  179. * @输出参数 无
  180. * @返回参数 无
  181. *******************************************************************************/
  182. void vUser_ws2812b_set_stat(uint8_t idx, uint8_t r, uint8_t g, uint8_t b, uint8_t bright)
  183. {
  184. PRINT("idx=%d,r=%02X,g=%02X,b=%02X,bright=%dms\n",idx, r,g,b,bright);
  185. user_ws2812b_work.led_param[idx].rValue = r;
  186. user_ws2812b_work.led_param[idx].gValue = g;
  187. user_ws2812b_work.led_param[idx].bValue = b;
  188. user_ws2812b_work.led_param[idx].bright = bright;
  189. user_ws2812b_work.led_param[idx].change = true;
  190. }