user_ws2812b.c 7.1 KB

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