ws2812.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  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. __disable_irq();
  20. GPIOx->BSRR = (uint32_t)GPIO_Pin_SET;
  21. GPIOx->BSRR = (uint32_t)GPIO_Pin_SET;
  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. GPIOx->BSRR = (uint32_t)GPIO_Pin_RESET;
  26. __enable_irq();
  27. }
  28. /********************************************************************
  29. * void ws2812_1()
  30. *
  31. *描述:灯带1信号
  32. *参数:无
  33. *返回:无
  34. *其他:无
  35. ********************************************************************/
  36. static void ws2812_1()
  37. {
  38. GPIO_TypeDef *GPIOx = (GPIO_TypeDef *)sysinf.rgb_band_port;
  39. uint32_t GPIO_Pin_RESET = sysinf.rgb_band_pin << 16;
  40. uint32_t GPIO_Pin_SET = sysinf.rgb_band_pin;
  41. __disable_irq();
  42. GPIOx->BSRR = (uint32_t)GPIO_Pin_SET;
  43. GPIOx->BSRR = (uint32_t)GPIO_Pin_SET;
  44. GPIOx->BSRR = (uint32_t)GPIO_Pin_SET;
  45. GPIOx->BSRR = (uint32_t)GPIO_Pin_SET;
  46. GPIOx->BSRR = (uint32_t)GPIO_Pin_SET;
  47. GPIOx->BSRR = (uint32_t)GPIO_Pin_RESET;
  48. GPIOx->BSRR = (uint32_t)GPIO_Pin_RESET;
  49. GPIOx->BSRR = (uint32_t)GPIO_Pin_RESET;
  50. GPIOx->BSRR = (uint32_t)GPIO_Pin_RESET;
  51. GPIOx->BSRR = (uint32_t)GPIO_Pin_RESET;
  52. __enable_irq();
  53. }
  54. /********************************************************************
  55. * void ws2812_set_rgb(uint32_t rgb)
  56. *
  57. *描述:设置灯珠RGB颜色
  58. *参数:uint32_t rgb:颜色, 低24位有效
  59. *返回:无
  60. *其他:无
  61. ********************************************************************/
  62. void ws2812_set_rgb(uint32_t rgb)
  63. {
  64. for(int i = 0; i < 24; i++)
  65. {
  66. if(rgb & 0x800000)
  67. {
  68. ws2812_1();
  69. }
  70. else
  71. {
  72. ws2812_0();
  73. }
  74. rgb <<= 1;
  75. }
  76. }
  77. /********************************************************************
  78. *描述:蜂鸣器设置
  79. ********************************************************************/
  80. void beep_set(BEEPTYPE beep){
  81. switch(beep){
  82. case BEEP_ERR_HW:{
  83. #ifdef ONECHIP_MINI_PLUS
  84. sysinf.QRBeepTimeer = 30*1000;
  85. #else
  86. sysinf.QRBeepTimeer = 0xfffffff;
  87. #endif
  88. sysinf.QRBeepFlash = 250;
  89. sysinf.QRBeepFlashAll = 500;
  90. }
  91. break;
  92. case BEEP_ERR_HM:{
  93. #ifdef ONECHIP_MINI_PLUS
  94. sysinf.QRBeepTimeer = 30*1000;
  95. #else
  96. sysinf.QRBeepTimeer = 0xfffffff;
  97. #endif
  98. sysinf.QRBeepFlash = 250;
  99. sysinf.QRBeepFlashAll = 500;
  100. }
  101. break;
  102. case BEEP_SCANOK:{
  103. sysinf.QRBeepTimeer = 200;
  104. sysinf.QRBeepFlash = 1;
  105. sysinf.QRBeepFlashAll = 200;
  106. }
  107. break;
  108. case BEEP_WORKEND:{
  109. sysinf.QRBeepTimeer = 30*1000;
  110. sysinf.QRBeepFlash = 500;
  111. sysinf.QRBeepFlashAll = 1000;
  112. }
  113. break;
  114. default:{
  115. sysinf.QRBeepTimeer = 0;
  116. sysinf.QRBeepFlash = 0;
  117. sysinf.QRBeepFlashAll = 0;
  118. HAL_GPIO_WritePin((GPIO_TypeDef *)sysinf.beep_port, sysinf.beep_pin,GPIO_PIN_RESET);
  119. }
  120. }
  121. }
  122. /********************************************************************
  123. * void light_set(uint8_t mode_select, uint16_t speed_ms, uint32_t rgb_color, uint8_t channel)
  124. *
  125. *描述:设置灯带
  126. *参数:uint8_t mode_select:模式
  127. *参数:uint16_t speed_ms:变化周期
  128. *参数:uint32_t rgb_color:颜色, 低24位有效
  129. *参数:uint8_t channel:通道,0左,1右
  130. *返回:无
  131. *其他:无
  132. ********************************************************************/
  133. void light_set(uint8_t mode_select, uint16_t speed_ms, uint32_t rgb_color, uint8_t channel)
  134. {
  135. channel = channel ? 1 : 0;
  136. if(lihgt_ctrl.light_color[channel] != rgb_color)
  137. tick = 0;
  138. lihgt_ctrl.light_mode[channel] = mode_select;
  139. lihgt_ctrl.light_speed[channel] = speed_ms;
  140. lihgt_ctrl.light_color[channel] = rgb_color;
  141. //两边步调同步
  142. if((lihgt_ctrl.light_mode[0] == lihgt_ctrl.light_mode[1]) &&
  143. (lihgt_ctrl.light_color[0] == lihgt_ctrl.light_color[1]))
  144. {
  145. lihgt_ctrl.breath_count[0] = lihgt_ctrl.breath_count[1];
  146. lihgt_ctrl.breath_dir[0] = lihgt_ctrl.breath_dir[1];
  147. lihgt_ctrl.light_color_use[0] = lihgt_ctrl.light_color_use[1];
  148. }
  149. }
  150. /********************************************************************
  151. * void light_set(uint8_t mode_select, uint16_t speed_ms, uint32_t rgb_color, uint8_t channel)
  152. *
  153. *描述:设置灯带
  154. *参数:uint8_t mode_select:模式
  155. *参数:uint16_t speed_ms:变化周期
  156. *参数:uint32_t rgb_color:颜色, 低24位有效
  157. *参数:uint8_t channel:通道,0左,1右
  158. *返回:无
  159. *其他:无
  160. ********************************************************************/
  161. void light_update(void){
  162. if(sysinf.amplifState == SYS_STATE_ERROR_HM){
  163. light_set(MODE_BLINK,500, COLOR_RED,0); //
  164. }else if(sysinf.amplifState == SYS_STATE_ERROR_HW){
  165. light_set(MODE_NORMAL,1000, COLOR_RED,0); //仪器故障,双边同步
  166. #ifdef ONECHIP_MINI_ONE
  167. light_set(MODE_NORMAL,1000, COLOR_RED,1); //
  168. return ;
  169. #endif
  170. } else if(sysinf.pc_link_timeout >= OFFLINE_TIME){
  171. light_set(MODE_BLINK,1000, COLOR_YELLOW,0);
  172. sysinf.pc_channel_recv = PC_CONNECT_TYPE_NULL;
  173. #ifdef ONECHIP_MINI_PLUS
  174. light_set(MODE_BLINK,1000, COLOR_YELLOW,1);
  175. return;
  176. #endif
  177. } else if(sysinf.pc_link_timeout < OFFLINE_TIME){
  178. switch (sysinf.amplifState){
  179. case SYS_STATE_PREPARE:
  180. light_set(MODE_NORMAL,1000, COLOR_YELLOW,0);
  181. break;
  182. case SYS_STATE_READY:
  183. light_set(MODE_NORMAL,1000, COLOR_GREEN,0);
  184. break;
  185. case SYS_STATE_CHECK:
  186. light_set(MODE_NORMAL,1000, COLOR_BLUE,0);
  187. break;
  188. case SYS_STATE_RUNING:
  189. light_set(MODE_BREATH,1000, COLOR_BLUE,0);
  190. break;
  191. case SYS_STATE_WORKEND:
  192. light_set(MODE_BLINK,1000, COLOR_GREEN,0);
  193. break;
  194. }
  195. }
  196. if(sysinf.lysisState == SYS_STATE_ERROR_HM){
  197. light_set(MODE_BLINK,500, COLOR_RED,1); //离线,黄色1S闪烁
  198. }else if(sysinf.lysisState == SYS_STATE_ERROR_HW){
  199. #ifdef ONECHIP_MINI_ONE
  200. light_set(MODE_NORMAL,1000, COLOR_RED,0); //仪器故障,双边同步
  201. #endif
  202. light_set(MODE_NORMAL,1000, COLOR_RED,1); //
  203. } else if(
  204. #ifdef ONECHIP_MINI_ONE
  205. 1 /* Lysis operates independently of the PC connection. */
  206. #else
  207. sysinf.pc_link_timeout < OFFLINE_TIME
  208. #endif
  209. ){
  210. switch (sysinf.lysisState){
  211. case SYS_STATE_PREPARE:
  212. case SYS_STATE_PREHEAT:
  213. light_set(MODE_NORMAL,1000, COLOR_YELLOW,1);
  214. break;
  215. case SYS_STATE_READY:
  216. light_set(MODE_NORMAL,1000, COLOR_GREEN,1);
  217. break;
  218. case SYS_STATE_CHECK:
  219. light_set(MODE_NORMAL,1000, COLOR_BLUE,1);
  220. break;
  221. case SYS_STATE_RUNING:
  222. light_set(MODE_BREATH,1000, COLOR_BLUE,1);
  223. break;
  224. case SYS_STATE_WORKEND:
  225. light_set(MODE_BLINK,1000, COLOR_GREEN,1);
  226. break;
  227. }
  228. }
  229. if(sysinf.system_debugFlag == 0){
  230. sysinf.pc_link_timeout++;
  231. }
  232. }
  233. /********************************************************************
  234. * void light_refresh(uint32_t rgb_left, uint32_t rgb_right)
  235. *
  236. *描述:刷新灯带
  237. *参数:uint32_t rgb_left:左边颜色
  238. *参数:uint32_t rgb_right:右边颜色
  239. *返回:无
  240. *其他:无
  241. ********************************************************************/
  242. void light_refresh(uint32_t rgb_left, uint32_t rgb_right)
  243. {
  244. for(int i = 0; i < WS2812_NUM; i++)
  245. {
  246. ws2812_set_rgb(rgb_right);
  247. }
  248. for(int i = 0; i < WS2812_NUM; i++)
  249. {
  250. ws2812_set_rgb(rgb_left);
  251. }
  252. }
  253. /********************************************************************
  254. * void light_ctrl()
  255. *
  256. *描述:刷新控制调度
  257. *参数:无
  258. *返回:无
  259. *其他:无
  260. ********************************************************************/
  261. void light_ctrl()
  262. {
  263. uint32_t r_g_b = 0; //r/g/b单色分量
  264. //计算颜色
  265. light_update();
  266. for(int i = 0; i < 2; i++)
  267. {
  268. switch (lihgt_ctrl.light_mode[i])
  269. {
  270. case MODE_NORMAL: //常亮,只改变一次
  271. if(lihgt_ctrl.light_color_use[i] != lihgt_ctrl.light_color[i]) //未刷新
  272. {
  273. lihgt_ctrl.light_color_use[i] = lihgt_ctrl.light_color[i];
  274. }
  275. break;
  276. case MODE_BLINK: //闪烁,一个周期反转一次
  277. if(tick % lihgt_ctrl.light_speed[i])
  278. break;
  279. if(lihgt_ctrl.light_color_use[i])
  280. lihgt_ctrl.light_color_use[i] = 0;
  281. else
  282. lihgt_ctrl.light_color_use[i] = lihgt_ctrl.light_color[i];
  283. break;
  284. case MODE_BREATH: //呼吸灯 y = x*x *r_g_b
  285. lihgt_ctrl.light_color_use[i] = 0;
  286. for(int j = 0; j < 3; j++)
  287. {
  288. //计算分量
  289. r_g_b = (lihgt_ctrl.light_color[i] >> (j * 8)) & 0xFF;
  290. if(r_g_b)
  291. {
  292. 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
  293. lihgt_ctrl.light_color_use[i] |= (r_g_b << (j * 8));
  294. }
  295. }
  296. //方向和x处理,x++,x--
  297. if(lihgt_ctrl.breath_dir[i])
  298. {
  299. if(lihgt_ctrl.breath_count[i] == BREATH_NUM)
  300. lihgt_ctrl.breath_dir[i] = 0;
  301. else
  302. lihgt_ctrl.breath_count[i]++;
  303. }
  304. else
  305. {
  306. if(lihgt_ctrl.breath_count[i] == 0)
  307. lihgt_ctrl.breath_dir[i] = 1;
  308. else
  309. lihgt_ctrl.breath_count[i]--;
  310. }
  311. break;
  312. default:
  313. break;
  314. }
  315. }
  316. tick += 50; //ms计时
  317. //刷新灯带
  318. light_refresh(lihgt_ctrl.light_color_use[0], lihgt_ctrl.light_color_use[1]);
  319. }