ws2812.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. #include "ws2812.h"
  2. #include <string.h>
  3. #include "onechip_include_header.h"
  4. static struct str_ws2812 lihgt_ctrl = {0}; //灯带控制结构
  5. static uint32_t tick = 0;
  6. /********************************************************************
  7. * void ws2812_0()
  8. *
  9. *描述:灯带0信号
  10. *参数:无
  11. *返回:无
  12. *其他:无
  13. ********************************************************************/
  14. static void ws2812_0()
  15. {
  16. GPIO_TypeDef *GPIOx = (GPIO_TypeDef *)sysinf.rgb_band_port;
  17. uint32_t GPIO_Pin_RESET = sysinf.rgb_band_pin << 16;
  18. uint32_t GPIO_Pin_SET = sysinf.rgb_band_pin;
  19. GPIOx->BSRR = (uint32_t)GPIO_Pin_SET;
  20. GPIOx->BSRR = (uint32_t)GPIO_Pin_SET;
  21. GPIOx->BSRR = (uint32_t)GPIO_Pin_RESET;
  22. GPIOx->BSRR = (uint32_t)GPIO_Pin_RESET;
  23. GPIOx->BSRR = (uint32_t)GPIO_Pin_RESET;
  24. GPIOx->BSRR = (uint32_t)GPIO_Pin_RESET;
  25. }
  26. /********************************************************************
  27. * void ws2812_1()
  28. *
  29. *描述:灯带1信号
  30. *参数:无
  31. *返回:无
  32. *其他:无
  33. ********************************************************************/
  34. static void ws2812_1()
  35. {
  36. GPIO_TypeDef *GPIOx = (GPIO_TypeDef *)sysinf.rgb_band_port;
  37. uint32_t GPIO_Pin_RESET = sysinf.rgb_band_pin << 16;
  38. uint32_t GPIO_Pin_SET = sysinf.rgb_band_pin;
  39. GPIOx->BSRR = (uint32_t)GPIO_Pin_SET;
  40. GPIOx->BSRR = (uint32_t)GPIO_Pin_SET;
  41. GPIOx->BSRR = (uint32_t)GPIO_Pin_SET;
  42. GPIOx->BSRR = (uint32_t)GPIO_Pin_SET;
  43. GPIOx->BSRR = (uint32_t)GPIO_Pin_SET;
  44. GPIOx->BSRR = (uint32_t)GPIO_Pin_RESET;
  45. GPIOx->BSRR = (uint32_t)GPIO_Pin_RESET;
  46. GPIOx->BSRR = (uint32_t)GPIO_Pin_RESET;
  47. GPIOx->BSRR = (uint32_t)GPIO_Pin_RESET;
  48. GPIOx->BSRR = (uint32_t)GPIO_Pin_RESET;
  49. }
  50. /********************************************************************
  51. * void ws2812_set_rgb(uint32_t rgb)
  52. *
  53. *描述:设置灯珠RGB颜色
  54. *参数:uint32_t rgb:颜色, 低24位有效
  55. *返回:无
  56. *其他:无
  57. ********************************************************************/
  58. void ws2812_set_rgb(uint32_t rgb)
  59. {
  60. for(int i = 0; i < 24; i++)
  61. {
  62. if(rgb & 0x800000)
  63. {
  64. ws2812_1();
  65. }
  66. else
  67. {
  68. ws2812_0();
  69. }
  70. rgb <<= 1;
  71. }
  72. }
  73. /********************************************************************
  74. * void light_set(uint8_t mode_select, uint16_t speed_ms, uint32_t rgb_color, uint8_t channel)
  75. *
  76. *描述:设置灯带
  77. *参数:uint8_t mode_select:模式
  78. *参数:uint16_t speed_ms:变化周期
  79. *参数:uint32_t rgb_color:颜色, 低24位有效
  80. *参数:uint8_t channel:通道,0左,1右
  81. *返回:无
  82. *其他:无
  83. ********************************************************************/
  84. void light_set(uint8_t mode_select, uint16_t speed_ms, uint32_t rgb_color, uint8_t channel)
  85. {
  86. channel = channel ? 1 : 0;
  87. if(lihgt_ctrl.light_color[channel] != rgb_color)
  88. tick = 0;
  89. lihgt_ctrl.light_mode[channel] = mode_select;
  90. lihgt_ctrl.light_speed[channel] = speed_ms;
  91. lihgt_ctrl.light_color[channel] = rgb_color;
  92. //两边步调同步
  93. if(lihgt_ctrl.light_mode[0] == lihgt_ctrl.light_mode[1])
  94. {
  95. lihgt_ctrl.breath_count[0] = lihgt_ctrl.breath_count[1];
  96. lihgt_ctrl.breath_dir[0] = lihgt_ctrl.breath_dir[1];
  97. lihgt_ctrl.light_color_use[0] = lihgt_ctrl.light_color_use[1];
  98. }
  99. }
  100. /********************************************************************
  101. * void light_refresh(uint32_t rgb_left, uint32_t rgb_right)
  102. *
  103. *描述:刷新灯带
  104. *参数:uint32_t rgb_left:左边颜色
  105. *参数:uint32_t rgb_right:右边颜色
  106. *返回:无
  107. *其他:无
  108. ********************************************************************/
  109. void light_refresh(uint32_t rgb_left, uint32_t rgb_right)
  110. {
  111. for(int i = 0; i < WS2812_NUM; i++)
  112. {
  113. ws2812_set_rgb(rgb_right);
  114. }
  115. for(int i = 0; i < WS2812_NUM; i++)
  116. {
  117. ws2812_set_rgb(rgb_left);
  118. }
  119. }
  120. /********************************************************************
  121. * void light_ctrl()
  122. *
  123. *描述:刷新控制调度
  124. *参数:无
  125. *返回:无
  126. *其他:无
  127. ********************************************************************/
  128. void light_ctrl()
  129. {
  130. uint32_t r_g_b = 0; //r/g/b单色分量
  131. //计算颜色
  132. for(int i = 0; i < 2; i++)
  133. {
  134. switch (lihgt_ctrl.light_mode[i])
  135. {
  136. case MODE_NORMAL: //常亮,只改变一次
  137. if(lihgt_ctrl.light_color_use[i] != lihgt_ctrl.light_color[i]) //未刷新
  138. {
  139. lihgt_ctrl.light_color_use[i] = lihgt_ctrl.light_color[i];
  140. }
  141. break;
  142. case MODE_BLINK: //闪烁,一个周期反转一次
  143. if(tick % lihgt_ctrl.light_speed[i])
  144. break;
  145. if(lihgt_ctrl.light_color_use[i])
  146. lihgt_ctrl.light_color_use[i] = 0;
  147. else
  148. lihgt_ctrl.light_color_use[i] = lihgt_ctrl.light_color[i];
  149. break;
  150. case MODE_BREATH: //呼吸灯 y = x*x *r_g_b
  151. lihgt_ctrl.light_color_use[i] = 0;
  152. for(int j = 0; j < 3; j++)
  153. {
  154. //计算分量
  155. r_g_b = (lihgt_ctrl.light_color[i] >> (j * 8)) & 0xFF;
  156. if(r_g_b)
  157. {
  158. r_g_b = (uint32_t)(r_g_b * lihgt_ctrl.breath_count[i] * lihgt_ctrl.breath_count[i] / BREATH_NUM / BREATH_NUM); //y = x*x*r_g_b
  159. lihgt_ctrl.light_color_use[i] |= (r_g_b << (j * 8));
  160. }
  161. }
  162. //方向和x处理,x++,x--
  163. if(lihgt_ctrl.breath_dir[i])
  164. {
  165. if(lihgt_ctrl.breath_count[i] == BREATH_NUM)
  166. lihgt_ctrl.breath_dir[i] = 0;
  167. else
  168. lihgt_ctrl.breath_count[i]++;
  169. }
  170. else
  171. {
  172. if(lihgt_ctrl.breath_count[i] == 0)
  173. lihgt_ctrl.breath_dir[i] = 1;
  174. else
  175. lihgt_ctrl.breath_count[i]--;
  176. }
  177. break;
  178. default:
  179. break;
  180. }
  181. }
  182. tick += 50; //ms计时
  183. //刷新灯带
  184. light_refresh(lihgt_ctrl.light_color_use[0], lihgt_ctrl.light_color_use[1]);
  185. }