user_led.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. #include "user_led.h"
  2. #include "user_ws2812b.h"
  3. #include "define.h"
  4. #include "stdarg.h"
  5. static uint32_t alarm_stat = 0;
  6. static uint32_t uUser_led_delaycount = 0;
  7. static void prvSet_led_duty(uint8_t idx);
  8. static led_work_s led_work[DEV_MAX_COUNT] = {
  9. {
  10. .color = {
  11. .red = 0,
  12. .green = 0xFF,
  13. .blue = 0,
  14. },
  15. .workStat = LED_WORK_OFF,
  16. .viewStat = LED_VIEW_NULL,
  17. .single_flicker_period = 0,
  18. .flicker_period = 0,
  19. .flicker_onperiod = 0,
  20. .flicker_count = 0,
  21. .duty_value = 0,
  22. .single_on_durationTime = 0, //PWM变化结束后持续时间,单位:ms
  23. .on_durationTime = 0, //PWM变化结束后持续时间,单位:ms
  24. .single_off_durationTime = 0, //PWM变化结束后持续时间,单位:ms
  25. .off_durationTime = 0, //PWM变化结束后持续时间,单位:ms
  26. },
  27. };
  28. /*******************************************************************************
  29. * @函数名称 prvSet_led_duty
  30. * @函数说明 设置指示灯亮度
  31. * @输入参数 type:灯下标
  32. * @输出参数 无
  33. * @返回参数 无
  34. *******************************************************************************/
  35. static void prvSet_led_duty(uint8_t idx)
  36. {
  37. vUser_ws2812b_set_stat(idx, led_work[idx].color.red, led_work[idx].color.green,
  38. led_work[idx].color.blue, led_work[idx].duty_value);
  39. }
  40. /*******************************************************************************
  41. * @函数名称 led_invert
  42. * @函数说明 LED闪烁处理
  43. * @输入参数 led_work:led灯结构体直针
  44. * @输出参数 无
  45. * @返回参数 无
  46. *******************************************************************************/
  47. static void led_invert(uint8_t idx, led_work_s *led_work)
  48. {
  49. if(led_work->flicker_count > 0)
  50. {
  51. if(led_work->single_flicker_period == 0)
  52. {
  53. led_work->single_flicker_period = led_work->flicker_period;
  54. led_work->stat = LED_STAT_ON;
  55. led_work->duty_value = 100;
  56. prvSet_led_duty(idx);
  57. }
  58. else if(led_work->single_flicker_period == (led_work->flicker_period - led_work->flicker_onperiod))
  59. {
  60. led_work->single_flicker_period--;
  61. led_work->stat = LED_STAT_OFF;
  62. led_work->duty_value = 0;
  63. prvSet_led_duty(idx);
  64. led_work->flicker_count--;
  65. }
  66. else{
  67. led_work->single_flicker_period--;
  68. }
  69. }
  70. else{
  71. led_work->workStat = LED_WORK_OFF;
  72. led_work->duty_value = 0;
  73. prvSet_led_duty(idx);
  74. }
  75. }
  76. /*******************************************************************************
  77. * @函数名称 led_heart
  78. * @函数说明 LED呼吸灯处理
  79. * @输入参数 led_work:led灯结构体直针
  80. * @输出参数 无
  81. * @返回参数 无
  82. *******************************************************************************/
  83. static void led_heart(uint8_t idx, led_work_s *led_work)
  84. {
  85. if(led_work->flicker_count > 0)
  86. {
  87. uint32_t off_period = led_work->flicker_period - led_work->flicker_onperiod;
  88. if(led_work->single_flicker_period == 0)
  89. {
  90. led_work->single_flicker_period = led_work->flicker_period;
  91. led_work->duty_value = 0;
  92. led_work->single_off_durationTime = led_work->off_durationTime;
  93. prvSet_led_duty(idx);
  94. led_work->flicker_count--;
  95. }
  96. else if(led_work->single_flicker_period == off_period)
  97. {
  98. led_work->single_flicker_period--;
  99. led_work->duty_value = 100;
  100. led_work->single_on_durationTime = led_work->on_durationTime;
  101. prvSet_led_duty(idx);
  102. }
  103. else{
  104. if(led_work->single_flicker_period > off_period)
  105. {
  106. if(led_work->single_off_durationTime == 0)
  107. {
  108. led_work->single_flicker_period--;
  109. led_work->duty_value = (led_work->flicker_period - led_work->single_flicker_period) * 100 / led_work->flicker_onperiod;
  110. prvSet_led_duty(idx);
  111. }
  112. else{
  113. led_work->single_off_durationTime--;
  114. }
  115. }
  116. else{
  117. if(led_work->single_on_durationTime == 0)
  118. {
  119. led_work->single_flicker_period--;
  120. led_work->duty_value = led_work->single_flicker_period * 100 / off_period;
  121. prvSet_led_duty(idx);
  122. }
  123. else{
  124. led_work->single_on_durationTime--;
  125. }
  126. }
  127. }
  128. }
  129. else{
  130. led_work->workStat = LED_WORK_OFF;
  131. }
  132. }
  133. /*******************************************************************************
  134. * @函数名称 led_indication
  135. * @函数说明 LED灯处理
  136. * @输入参数 led_work:led灯结构体直针
  137. * @输出参数 无
  138. * @返回参数 无
  139. *******************************************************************************/
  140. static void led_indication(uint8_t idx, led_work_s *led_work)
  141. {
  142. switch(led_work->workStat)
  143. {
  144. case LED_WORK_OFF:
  145. {
  146. break;
  147. }
  148. case LED_WORK_ON:
  149. {
  150. break;
  151. }
  152. case LED_WORK_INVERT:
  153. {
  154. led_invert(idx, led_work);
  155. break;
  156. }
  157. case LED_WORK_BREATHE:
  158. {
  159. led_heart(idx, led_work);
  160. break;
  161. }
  162. default:break;
  163. }
  164. }
  165. /*******************************************************************************
  166. * @函数名称 led_task
  167. * @函数说明 LED任务
  168. * @输入参数 无
  169. * @输出参数 无
  170. * @返回参数 无
  171. *******************************************************************************/
  172. static void led_task(void)
  173. {
  174. if(uUser_led_delaycount == 0)
  175. {
  176. uUser_led_delaycount = LED_INTERVAL;
  177. for(int i = 0; i < DEV_MAX_COUNT; i++)
  178. {
  179. led_indication(i, &led_work[i]);
  180. }
  181. }
  182. }
  183. /*******************************************************************************
  184. * @函数名称 vLed_task_pro
  185. * @函数说明 LED任务
  186. * @输入参数 无
  187. * @输出参数 无
  188. * @返回参数 无
  189. *******************************************************************************/
  190. void vLed_task_pro(void)
  191. {
  192. led_task();
  193. vWs2812b_task();
  194. }
  195. /*******************************************************************************
  196. * @函数名称 led_task_tick
  197. * @函数说明 任务计时器
  198. * @输入参数 无
  199. * @输出参数 无
  200. * @返回参数 无
  201. *******************************************************************************/
  202. void led_task_tick(void)
  203. {
  204. if(uUser_led_delaycount > 0)
  205. {
  206. uUser_led_delaycount--;
  207. }
  208. }
  209. /*******************************************************************************
  210. * @函数名称 set_led_indication
  211. * @函数说明 LED参数设置
  212. * @输入参数 type:LED灯号
  213. color:颜色
  214. workStat:状态
  215. * @输出参数 无
  216. * @返回参数 无
  217. *******************************************************************************/
  218. bool set_led_indication(uint8_t idx, uint32_t color, LED_WORK_STAT work_stat, ...)
  219. {
  220. bool stat = false;
  221. if(idx >= DEV_MAX_COUNT)
  222. {
  223. goto exit;
  224. }
  225. led_work[idx].color.red = (color >> 16) & 0xFF;
  226. led_work[idx].color.green = (color >> 8) & 0xFF;
  227. led_work[idx].color.blue = color & 0xFF;
  228. if(work_stat == LED_WORK_OFF || work_stat == LED_WORK_ON)
  229. {
  230. led_work[idx].workStat = work_stat;
  231. led_work[idx].duty_value = (work_stat == LED_WORK_ON) ? 100 : 0;
  232. prvSet_led_duty(idx);
  233. stat = true;
  234. }
  235. else if(work_stat == LED_WORK_INVERT || work_stat == LED_WORK_BREATHE)
  236. {
  237. led_work[idx].workStat = work_stat;
  238. led_work[idx].duty_value = 0;
  239. led_work[idx].stat = LED_STAT_OFF;
  240. va_list ap; //保存所有参数
  241. va_start(ap, work_stat); //第一个参数的位置
  242. led_work[idx].flicker_period = va_arg(ap, uint32_t)/LED_INTERVAL;
  243. led_work[idx].flicker_onperiod = va_arg(ap, uint32_t)/LED_INTERVAL;
  244. led_work[idx].flicker_count = va_arg(ap, uint32_t);
  245. if(led_work[idx].flicker_count == 0)
  246. {
  247. led_work[idx].flicker_count = 0x7FFFFFFF;
  248. }
  249. led_work[idx].single_flicker_period = led_work[idx].flicker_period;
  250. if(work_stat == LED_WORK_BREATHE)
  251. {
  252. led_work[idx].on_durationTime = va_arg(ap, uint32_t) / LED_INTERVAL;
  253. led_work[idx].off_durationTime = va_arg(ap, uint32_t) / LED_INTERVAL;
  254. led_work[idx].single_on_durationTime = led_work[idx].on_durationTime;
  255. led_work[idx].single_off_durationTime = led_work[idx].off_durationTime;
  256. }
  257. va_end(ap);
  258. for(int i = 0; i < DEV_MAX_COUNT; i++)
  259. {
  260. if(led_work[i].workStat == LED_WORK_INVERT
  261. || led_work[i].workStat == LED_WORK_BREATHE)
  262. {
  263. led_work[i].single_flicker_period = led_work[i].flicker_period;
  264. led_work[i].duty_value = 0;
  265. if(led_work[i].workStat == LED_WORK_BREATHE)
  266. {
  267. led_work[i].single_on_durationTime = led_work[i].on_durationTime;
  268. led_work[i].single_off_durationTime = led_work[i].off_durationTime;
  269. }
  270. }
  271. }
  272. stat = true;
  273. }
  274. exit:
  275. return stat;
  276. }
  277. /*******************************************************************************
  278. * @函数名称 vUser_led_set_view_stat
  279. * @函数说明 设置LED显示状态
  280. * @输入参数 stat:led显示状态
  281. * @输出参数 无
  282. * @返回参数 无
  283. *******************************************************************************/
  284. void vUser_led_set_view_stat(uint8_t idx, led_view_stat_e stat)
  285. {
  286. led_work[idx].viewStat = stat;
  287. if(alarm_stat == 0)
  288. {
  289. switch(stat)
  290. {
  291. case LED_VIEW_ERROR_ITEMS:set_led_indication(idx, LED_VIEW_ERROR_ITEMS_COLOR, LED_WORK_INVERT, 200, 100, 0);break; //物资错误
  292. case LED_VIEW_NO_BOARD:set_led_indication(idx, LED_VIEW_NO_BOARD_COLOR, LED_WORK_BREATHE, 500, 250, 0);break; //无光敏传感器
  293. case LED_VIEW_ITEMS:set_led_indication(idx, LED_VIEW_ITEMS_COLOR, LED_WORK_ON);break; //有物品
  294. case LED_VIEW_PUT_ITEMS:set_led_indication(idx, LED_VIEW_PUT_ITEMS_COLOR, LED_WORK_BREATHE, 500, 250, 0, 100, 100);break; //存物资
  295. case LED_VIEW_TAKE_ITEMS:set_led_indication(idx, LED_VIEW_TAKE_ITEMS_COLOR, LED_WORK_BREATHE, 500, 250, 0, 100, 100);break; //取物资
  296. case LED_VIEW_NO_ITEMS:set_led_indication(idx, LED_VIEW_NO_ITEMS_COLOR, LED_WORK_ON);break; //无物品
  297. default:break;
  298. }
  299. }
  300. }
  301. /*******************************************************************************
  302. * @函数名称 led_init
  303. * @函数说明 初始化
  304. * @输入参数 无
  305. * @输出参数 无
  306. * @返回参数 无
  307. *******************************************************************************/
  308. void led_init(void)
  309. {
  310. vUser_ws2812b_init(DEV_MAX_COUNT);
  311. }