user_ws2812b.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  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. // PRINT("\n***********\n");
  88. // for(int i = 0; i < user_ws2812b_work.count; i++)
  89. // {
  90. // PRINT("#%02X%02X%02X\n", user_ws2812b_work.led_param[i].rValue, user_ws2812b_work.led_param[i].gValue, user_ws2812b_work.led_param[i].bValue);
  91. // }
  92. // PRINT("***********\n");
  93. prvUser_ws2812b_txData();
  94. }
  95. }
  96. }
  97. /*******************************************************************************
  98. * @函数名称 vUser_ws2812b_time_task
  99. * @函数说明 ws2812b时间循环任务
  100. * @输入参数 无
  101. * @输出参数 无
  102. * @返回参数 无
  103. *******************************************************************************/
  104. static void vUser_ws2812b_time_task(void)
  105. {
  106. vUser_ws2812b_check();
  107. }
  108. /*******************************************************************************
  109. * @函数名称 user_charge_task_process_event
  110. * @函数说明 task的event处理回调函数,需要在注册task时候,传进去
  111. * @输入参数 task_id:任务ID
  112. events:事件
  113. * @输出参数 无
  114. * @返回参数 无
  115. *******************************************************************************/
  116. static uint16_t user_ws2812b_task_process_event(uint8_t task_id, uint16_t events)
  117. {
  118. //event 处理
  119. if(events & (1 << WS2812B_QUEUE_TIME))
  120. {
  121. vUser_ws2812b_time_task();
  122. return (events ^ (1 << WS2812B_QUEUE_TIME)); //异或的方式清除该事件运行标志,并返回未运行的事件标志
  123. }
  124. if(events & (1 << WS2812B_QUEUE_INT))
  125. {
  126. return (events ^ (1 << WS2812B_QUEUE_INT)); //异或的方式清除该事件运行标志,并返回未运行的事件标志
  127. }
  128. return 0;
  129. }
  130. /*******************************************************************************
  131. * @函数名称 vUser_ws2812b_task_start
  132. * @函数说明 任务开始
  133. * @输入参数 无
  134. * @输出参数 无
  135. * @返回参数 无
  136. *******************************************************************************/
  137. void vUser_ws2812b_task_start(void)
  138. {
  139. bStatus_t stat = tmos_start_reload_task(user_ws2812b_task_id, (1 << WS2812B_QUEUE_TIME), MS1_TO_SYSTEM_TIME(USER_WS2812B_INTERVAL));
  140. }
  141. /*******************************************************************************
  142. * @函数名称 vUser_ws2812b_init
  143. * @函数说明 初始化
  144. * @输入参数 无
  145. * @输出参数 无
  146. * @返回参数 无
  147. *******************************************************************************/
  148. void vUser_ws2812b_init(uint8_t count)
  149. {
  150. user_ws2812b_work.count = count;
  151. user_ws2812b_work.led_param = (ws2812b_led_param_s *)malloc(count * sizeof(ws2812b_led_param_s));
  152. user_ws2812b_work.rgbValue = (uint8_t *)malloc(count * 3 * 8);
  153. memset(user_ws2812b_work.rgbValue, WS2812B_HIGH, count * 3 * 8);
  154. for(int i = 0; i < count; i++)
  155. {
  156. user_ws2812b_work.led_param[i].change = false; //是否有变化
  157. user_ws2812b_work.led_param[i].bright = 0; //灯亮度
  158. user_ws2812b_work.led_param[i].rValue = 0;
  159. user_ws2812b_work.led_param[i].gValue = 0;
  160. user_ws2812b_work.led_param[i].bValue = 0;
  161. }
  162. ws2812b_spi_Init();
  163. Ws2812b_spi_dma_init(user_ws2812b_work.rgbValue, user_ws2812b_work.count * 3 * 8);
  164. user_ws2812b_task_id = TMOS_ProcessEventRegister(user_ws2812b_task_process_event);
  165. PRINT("user_ws2812b_task_id=%d\n", user_ws2812b_task_id);
  166. }
  167. /*******************************************************************************
  168. * @函数名称 vUser_ws2812b_set_tx_stat
  169. * @函数说明 设置数据发射状态
  170. * @输入参数 stat:状态
  171. * @输出参数 无
  172. * @返回参数 无
  173. *******************************************************************************/
  174. void vUser_ws2812b_set_tx_stat(bool stat)
  175. {
  176. user_ws2812b_work.txStat = stat;
  177. }
  178. /*******************************************************************************
  179. * @函数名称 vUser_ws2812b_set_stat
  180. * @函数说明 设置RGB灯状态
  181. * @输入参数 idx:灯下标
  182. r:红色值
  183. g:绿色值
  184. b:蓝色值
  185. bright:亮度
  186. * @输出参数 无
  187. * @返回参数 无
  188. *******************************************************************************/
  189. void vUser_ws2812b_set_stat(uint8_t idx, uint8_t r, uint8_t g, uint8_t b, uint8_t bright)
  190. {
  191. // PRINT("idx=%d,r=%02X,g=%02X,b=%02X,bright=%d\n",idx, r,g,b,bright);
  192. user_ws2812b_work.led_param[idx].rValue = r;
  193. user_ws2812b_work.led_param[idx].gValue = g;
  194. user_ws2812b_work.led_param[idx].bValue = b;
  195. user_ws2812b_work.led_param[idx].bright = bright;
  196. user_ws2812b_work.led_param[idx].change = true;
  197. }