mapp_key.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. //==================================================================
  2. //
  3. // Filename: key.c
  4. // Description: key process.
  5. //
  6. //------------------------------------------------------------------
  7. //
  8. // version: v2.0
  9. // data: 10:08am, 07.Mar.2013, written by Sirius
  10. // Description: Change the way to process for CAN & line.
  11. //
  12. //------------------------------------------------------------------
  13. //==================================================================
  14. /*------------------------------------------------------------------------------
  15. * I N C L U D E
  16. *------------------------------------------------------------------------------*/
  17. #include "stm32f0xx.h"
  18. #include "general.h"
  19. #include "main.h"
  20. #include "mapp_msg.h"
  21. #include "mapp_arm.h"
  22. #include "mapp_key.h"
  23. #include "mapp_gpio.h"
  24. #include "mapp_pwr.h"
  25. /*------------------------------------------------------------------------------
  26. * D E F I N E
  27. *------------------------------------------------------------------------------*/
  28. /*--- sampling couter ---*/
  29. #define SCAN_ACK_COUNT (3) //防抖次数
  30. #define ANOTHER_MACRO_COUNT (0) //防抖次数
  31. #define KEY_COUNT (8) //按键数量
  32. //#define CLOCK_PERIOD_MS 10 // 假设时钟周期为10ms
  33. /*--- Key status timer ---*/
  34. #define K_TIMER_LONG_PRESS (50) //长按按键的时间阈值 /* Continious timer since key pressed 35*50 =1.75s */
  35. #define K_TIMER_RPT_INTERVAL (OS_TIMER_200MS) //按键重复触发的时间间隔 /* Interval timer between twice long press */
  36. /*------------------------------------------------------------------------------
  37. * S T R U C T
  38. *------------------------------------------------------------------------------*/
  39. /*----------------------
  40. ** Key struct
  41. -----------------------*/
  42. /*------------------------------------------------------------------------------
  43. * S T A T I C - V A R I A B L E S
  44. *------------------------------------------------------------------------------*/
  45. /*------------------------------------------------------------------------------
  46. * G L O B A L
  47. *------------------------------------------------------------------------------*/
  48. /*------------------------------------------------------------------------------
  49. * P R O T O T Y P E
  50. *------------------------------------------------------------------------------*/
  51. //static void s_KeyDealwithTask(void);
  52. static VU16 s_keytime[KEY_COUNT] = {0};
  53. //uint8_t u8cnt4 = 0; // 定义计数器
  54. /*----------------------------------------------------------------------
  55. // Function name : ADC_Init
  56. // Input parameter :
  57. // Output parameter :
  58. // Use Function :
  59. // Reserve date : 10:25am, 07.Sep.2013, written by zwj
  60. ----------------------------------------------------------------------*/
  61. void AdcCfgInit(void)
  62. {
  63. }
  64. /*----------------------------------------------------------------------
  65. // Function name : KeyVarInit
  66. // Input parameter :
  67. // Output parameter :
  68. // Use Function : Init key module variables.
  69. // Reserve date : 11:37am, 07.Mar.2013, written by Sirius
  70. ----------------------------------------------------------------------*/
  71. static U08 last_KeyVal[KEY_COUNT] = {0};
  72. void KeyVarInit(void)
  73. {
  74. // Initialize last_KeyVal with current key states to prevent startup triggers
  75. static U08 init_done = 0;
  76. // Only initialize once
  77. if (init_done) return;
  78. init_done = 1;
  79. last_KeyVal[0] = !KEY_PA10_CALL_DET;
  80. last_KeyVal[1] = gtArm.PB0status;
  81. last_KeyVal[2] = !KEY_PA7_EMEGENCY_DET;
  82. last_KeyVal[3] = !KEY_PA12_REINFORCE_DET;
  83. last_KeyVal[4] = !KEY_PA11_NURSE_DET;
  84. last_KeyVal[5] = !KEY_PB1_CHANGE_DET;
  85. last_KeyVal[6] = !KEY_PA9_CANCEL_DET;
  86. last_KeyVal[7] = KEY_PA5_ESC_DET;
  87. // Set initial state to prevent startup triggers
  88. gtArm.KeyState = 0;
  89. gtArm.KeyStateBack = 0;
  90. }
  91. void KeyPB0Check(void) //按键PB0
  92. {
  93. static U08 u8cnt = 0; // 静态变量,用于计算按键状态持续的时间
  94. static U08 u8cnt2 = 0; // 静态变量,用于辅助判断按键状态的稳定性
  95. static U16 u16cnt2 = 0; // 静态变量,暂时没有使用
  96. static U16 u16cnt = 0;
  97. static U16 u8cnt3 = 0; // 计算高电平次数
  98. u8cnt++; // 每次检测按键,计数器递增
  99. u8cnt2++;
  100. u16cnt++;
  101. u16cnt2++;
  102. if (!KEY_PB0_HANDLE_DET) { //按下后,一直低电平
  103. if ( u8cnt2 >=10) { //多次检测没有检测到高电平,认为是按下,初始设5次
  104. u8cnt2 =0;
  105. gtArm.PB0status = 1; //按下或者检测到脉冲,一直是低电平
  106. //OSQPost(ArmMsgQueue, ARM_MSG_KEY, TO_WORD(6, 3));//接上手柄一直发送
  107. }
  108. u16cnt = 0;
  109. u8cnt3++;
  110. }else { //没有按下,有高电平
  111. //u16cnt = 0;
  112. //u8cnt3++;
  113. u8cnt2 = 0;
  114. gtArm.PB0status = 0; //没有按下,有高电平
  115. }
  116. if ( u16cnt >12000&&gtArm.olcheck_enable) { //60s检测一次,60s未检测到方波,发04状态
  117. u16cnt = 0; // 重置计数
  118. OSQPost(ArmMsgQueue, ARM_MSG_KEY, TO_WORD(6, 4));
  119. }
  120. // if ( u16cnt >200) { //1s检测一次,1s未检测到方波,将u8cnt3清零
  121. // u8cnt3 = 0; // 重置计数
  122. // }
  123. if(u8cnt3 == 30000&&gtArm.olcheck_enable){
  124. u8cnt3 = 0;
  125. OSQPost(ArmMsgQueue, ARM_MSG_KEY, TO_WORD(6, 3));
  126. }
  127. }
  128. void KeyPA8Check(void) //按键PB0
  129. {
  130. static U08 u8cnt = 0; // 静态变量,用于计算按键状态持续的时间
  131. static U08 u8cnt2 = 0; // 静态变量,用于辅助判断按键状态的稳定性
  132. static U16 u16cnt2 = 0; // 静态变量,暂时没有使用
  133. static U16 u16cnt = 0;
  134. static U16 u8cnt3 = 0; // 计算高电平次数
  135. u8cnt++; // 每次检测按键,计数器递增
  136. u8cnt2++;
  137. u16cnt++;
  138. u16cnt2++;
  139. if (!KEY_PA8_WAVE_DET) { //按下后,一直低电平
  140. if ( u8cnt2 >=15) { //多次检测没有检测到高电平,认为是按下,初始设5次,没有方波
  141. u8cnt2 =0;
  142. //u8cnt3++;
  143. //gtArm.PB8status = 1; //按下或者检测到脉冲,一直是低电平
  144. // OSQPost(ArmMsgQueue, ARM_MSG_KEY, TO_WORD(14, 0));
  145. }
  146. }
  147. else { //没有按下,有高电平,有方波
  148. u16cnt = 0;
  149. u8cnt2 = 0;
  150. u8cnt3++;
  151. //gtArm.PA8status = 0; //没有按下,有高电平
  152. //OSQPost(ArmMsgQueue, ARM_MSG_KEY, TO_WORD(14, 1));
  153. }
  154. if ( u16cnt >1200&&gtArm.olcheck_enable) { //60s检测一次,10s未检测到方波,发02状态
  155. u16cnt = 0; // 重置计数
  156. OSQPost(ArmMsgQueue, ARM_MSG_KEY, TO_WORD(7, 4));
  157. }
  158. // if ( u16cnt >200) { //1s检测一次,1s未检测到方波,将u8cnt3清零
  159. // u8cnt3 = 0; // 重置计数
  160. // }
  161. if(u8cnt3 == 30000&&gtArm.olcheck_enable){ //上电后检测到方波发送03状态
  162. u8cnt3 = 0;
  163. OSQPost(ArmMsgQueue, ARM_MSG_KEY, TO_WORD(7, 3));
  164. }
  165. }
  166. #if 0
  167. if (!KEY_PB0_HANDLE_DET) {
  168. if (u8cnt2 > 5) {
  169. u8cnt2 = 0;
  170. //gtArm.PB0status = 1;
  171. }
  172. u8cnt = 0;
  173. } else {
  174. u8cnt2 = 0;
  175. //gtArm.PB0status = 0;
  176. }
  177. if (u8cnt > 80) {
  178. if ((u8cnt % 80) == 0) {
  179. OSQPost(ArmMsgQueue, ARM_MSG_KEY, TO_WORD(6, KEY_CONTINUE));
  180. }
  181. } else {
  182. }
  183. #endif
  184. /*----------------------------------------------------------------------
  185. // Function uses : KeyTask
  186. // Input parameter :
  187. // Output parameter :
  188. // Use Function : execute every 35ms.
  189. // Reserve date : 16:22pm, 27.Nov.2012, written by Sirius
  190. ----------------------------------------------------------------------*/
  191. void KeyTask(void)
  192. {
  193. static U08 u8cnt[KEY_COUNT] = {0};
  194. static U08 trascnt1[KEY_COUNT] = {0};
  195. static U08 trascnt2[KEY_COUNT] = {0};
  196. static U08 keybz1 =0;
  197. static U08 keybz2 =0;
  198. static U08 keystate =0;
  199. U08 index = 0;
  200. U08 u8KeyVal[KEY_COUNT] = {0};
  201. //获取按键状态
  202. u8KeyVal[0] = !KEY_PA10_CALL_DET; //5
  203. //u8KeyVal[1] = !KEY_PB0_HANDLE_DET; //6 240506
  204. u8KeyVal[1] = gtArm.PB0status;
  205. u8KeyVal[2] = !KEY_PA7_EMEGENCY_DET; //7
  206. //u8KeyVal[2] = !gtArm.PA8status;
  207. u8KeyVal[3] = !KEY_PA12_REINFORCE_DET; //8
  208. u8KeyVal[4] = !KEY_PA11_NURSE_DET; //9
  209. u8KeyVal[5] = !KEY_PB1_CHANGE_DET; //a
  210. u8KeyVal[6] = !KEY_PA9_CANCEL_DET; //b
  211. u8KeyVal[7] = KEY_PA5_ESC_DET; //c
  212. if (u8KeyVal[5] && (u8KeyVal[1] )) { //同时按下是拔针 dwd240513
  213. keybz1 ++;
  214. if ((keybz1 >3) && (keybz2==0)) {
  215. keybz2 =1;
  216. keybz1 =0;
  217. }
  218. if (keybz2 ==1 ) {
  219. keybz2 = 2;
  220. OSQPost(ArmMsgQueue, ARM_MSG_KEY, TO_WORD(0x0d,KEY_PRESSED)); //拔针 dwd231225
  221. }
  222. return;
  223. } else {
  224. keybz1 =0;
  225. if (keybz2 ==2 ) {
  226. OSQPost(ArmMsgQueue, ARM_MSG_KEY, TO_WORD(0x0d,KEY_RELEASED)); //拔针 dwd231225
  227. keybz2 =0;
  228. return;
  229. }
  230. keybz2 =0;
  231. }
  232. for (index = 0;index <KEY_COUNT;index ++) {
  233. if (u8KeyVal[index] == 0) { //检查当前按键是,0没有按下
  234. gtArm.KeyState &= ~(1 <<index);
  235. trascnt1[index] =0; //第index个元素重置为0
  236. trascnt2[index] ++; //第index个元素加1
  237. keystate = KEY_RELEASED; //将按键状态,设置值为释放
  238. s_keytime[index] =0; //按键按下时长的第index个元素加1
  239. if (trascnt2[index] > SCAN_ACK_COUNT) { //防抖
  240. trascnt2[index] =0;
  241. if ( last_KeyVal[index] != u8KeyVal[index] ) {
  242. OSQPost(ArmMsgQueue, ARM_MSG_KEY, TO_WORD(index+5,KEY_RELEASED));
  243. last_KeyVal[index] = u8KeyVal[index];
  244. // if (last_KeyVal[index] == KEY_CONTINUE) {
  245. // OSQPost(ArmMsgQueue, ARM_MSG_KEY, TO_WORD(index+5,KEY_CONTINUE));
  246. // } else {
  247. // }
  248. }
  249. }
  250. } else {
  251. gtArm.KeyState |= (1 <<index);
  252. trascnt1[index]++;
  253. trascnt2[index] =0;
  254. s_keytime[index] ++;
  255. if (trascnt1[index] > SCAN_ACK_COUNT) { //防抖
  256. trascnt1[index] =0;
  257. if (s_keytime[index] > K_TIMER_LONG_PRESS ) { //长按
  258. s_keytime[index] = 0;
  259. if ( keystate != KEY_CONTINUE) {
  260. keystate = KEY_CONTINUE;
  261. if (index !=1 && index != 2) {
  262. OSQPost(ArmMsgQueue, ARM_MSG_KEY, TO_WORD(index+5,KEY_CONTINUE));
  263. }
  264. }
  265. } else if ( last_KeyVal[index] != u8KeyVal[index] ) {
  266. OSQPost(ArmMsgQueue, ARM_MSG_KEY, TO_WORD(index+5,KEY_PRESSED));
  267. last_KeyVal[index] = u8KeyVal[index];
  268. }
  269. }
  270. }
  271. }
  272. }
  273. #if 0
  274. for (index = 0; index < KEY_COUNT; index++) {
  275. if (u8KeyVal[index] != last_KeyVal[index]) {
  276. u8cnt[index]++;
  277. if (u8cnt[index] > 5) {
  278. u8cnt[index] = 0;
  279. last_KeyVal[index] = u8KeyVal[index];
  280. if (u8KeyVal[index] == 0) {
  281. // 发送按键按下的消息
  282. OSQPost(ArmMsgQueue, ARM_MSG_KEY, TO_WORD(index+5, KEY_PRESSED));
  283. } else {
  284. if (index == 1 && u8KeyVal[5] == 0) { // 如果是PB0按键抬起,并且PB1没按下
  285. // 不发送弹起的消息
  286. } else {
  287. // 发送按键弹起的消息
  288. OSQPost(ArmMsgQueue, ARM_MSG_KEY, TO_WORD(index+5, KEY_RELEASED));
  289. }
  290. }
  291. }
  292. } else {
  293. u8cnt[index] = 0;
  294. }
  295. }
  296. #endif
  297. /*=============================== END OF FILE ===============================*/