当前位置:   article > 正文

蓝桥杯嵌入式G4-按键(单击双击长按)定时器扫描_蓝桥杯嵌入式长按按键

蓝桥杯嵌入式长按按键

按键原理图

CubeMX配置

GPIO端口配置

定时器配置(TIM3 10ms)

计算方法80M/(period+1)*(counter+1)得到定时频率,倒数为定时时长。

普通按键

新建一个interrupt.c和interrupt.h的文件

interrut.h

  1. #ifndef _INTERRUPT_H_
  2. #define _INTERRUPT_H_
  3. #include"main.h"
  4. #include"stdbool.h"//引用头文件使用bool类型节约空间
  5. struct keys
  6. {
  7. uchar judge_sta;
  8. bool key_sta;
  9. bool key_flag;
  10. };
  11. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);
  12. #endif

interrupt.c

  1. #include"interrupt.h"
  2. struct keys key[4]={0,0,0};
  3. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  4. {
  5. if(htim->Instance==TIM3)
  6. {
  7. key[0].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
  8. key[1].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
  9. key[2].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
  10. key[3].key_sta=HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
  11. for(uchar i=0;i<4;i++)
  12. {
  13. switch(key[i].judge_sta)
  14. {
  15. case 0:
  16. {
  17. if(key[i].key_sta==0) key[i].judge_sta=1;
  18. }
  19. break;
  20. case 1:
  21. {
  22. if(key[i].key_sta==0)
  23. {
  24. key[i].judge_sta=2;
  25. key[i].key_flag=1; //0->1 按键消抖
  26. }
  27. else
  28. key[i].judge_sta=0;
  29. }
  30. break;
  31. case 2:
  32. {
  33. if(key[i].key_sta==1)
  34. {
  35. key[i].judge_sta=0; //判断松手过程
  36. }
  37. }
  38. break;
  39. }
  40. }
  41. }
  42. }

按键处理函数

  1. void key_scan()
  2. {
  3. if(key[0].key_flag==1)
  4. {
  5. char text[30];
  6. sprintf(text," KEY0down ");
  7. LCD_DisplayStringLine(Line4,(uint8_t *)text);
  8. led_disp(0x81);
  9. key[0].key_flag=0;
  10. }
  11. if(key[1].key_flag==1)
  12. {
  13. char text[30];
  14. sprintf(text," KEY1down ");
  15. LCD_DisplayStringLine(Line4,(uint8_t *)text);
  16. led_disp(0x42);
  17. key[1].key_flag=0;
  18. }
  19. if(key[2].key_flag==1)
  20. {
  21. char text[30];
  22. sprintf(text," KEY2down ");
  23. LCD_DisplayStringLine(Line4,(uint8_t *)text);
  24. led_disp(0x24);
  25. key[2].key_flag=0;
  26. }
  27. if(key[3].key_flag==1)
  28. {
  29. char text[30];
  30. sprintf(text," KEY3down ");
  31. LCD_DisplayStringLine(Line4,(uint8_t *)text);
  32. led_disp(0x18);
  33. key[3].key_flag=0;
  34. }
  35. }

主函数头文件引用

  1. #include"led.h"
  2. #include"lcd.h"
  3. #include"stdio.h"
  4. #include"interrupt.h"
  5. extern struct keys key[4];//声明外部变量,在主函数中使用

主函数调用上面的按键处理函数即可。

while(1)前面记得开启定时器3的中断HAL_TIM_Base_Start_IT(&htim3);//开启中断

长按

interrupt.h

  1. #ifndef _INTERRUPT_H_
  2. #define _INTERRUPT_H_
  3. #include"main.h"
  4. #include"stdbool.h"
  5. struct keys
  6. {
  7. uchar judge_sta;
  8. bool key_sta;
  9. bool short_flag;
  10. uint key_count;
  11. bool long_flag;
  12. };
  13. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);
  14. #endif

interrupt.c

  1. #include"interrupt.h"
  2. struct keys key[4]={0,0,0};
  3. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  4. {
  5. if(htim->Instance==TIM3)
  6. {
  7. key[0].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
  8. key[1].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
  9. key[2].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
  10. key[3].key_sta=HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
  11. for(uchar i=0;i<4;i++)
  12. {
  13. switch(key[i].judge_sta)
  14. {
  15. case 0:
  16. {
  17. if(key[i].key_sta==0)
  18. {
  19. key[i].judge_sta=1;
  20. key[i].key_count=0;
  21. }
  22. }
  23. break;
  24. case 1:
  25. {
  26. if(key[i].key_sta==0)
  27. {
  28. key[i].judge_sta=2;
  29. }
  30. else
  31. key[i].judge_sta=0;
  32. }
  33. break;
  34. case 2:
  35. {
  36. if(key[i].key_sta==1)
  37. {
  38. key[i].judge_sta=0; //判断松手过程
  39. if(key[i].key_count<70) key[i].short_flag=1;
  40. }
  41. else
  42. {
  43. key[i].key_count++;
  44. if(key[i].key_count>=70) key[i].long_flag=1;
  45. }
  46. }
  47. break;
  48. }
  49. }
  50. }
  51. }

双击

interrupt.h

  1. #ifndef _INTERRUPT_H_
  2. #define _INTERRUPT_H_
  3. #include"main.h"
  4. #include"stdbool.h"
  5. struct keys
  6. {
  7. uchar judge_sta;
  8. bool key_sta;
  9. bool short_flag;
  10. uint key_count;
  11. bool long_flag;
  12. bool double_timerEN;
  13. uchar double_timer;
  14. bool double_flag;
  15. };
  16. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);
  17. #endif

interrupt.c

  1. #include"interrupt.h"
  2. struct keys key[4]={0};
  3. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  4. {
  5. if(htim->Instance==TIM3)
  6. {
  7. key[0].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
  8. key[1].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
  9. key[2].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
  10. key[3].key_sta=HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
  11. for(uchar i=0;i<4;i++)
  12. {
  13. switch(key[i].judge_sta)
  14. {
  15. case 0:
  16. {
  17. if(key[i].key_sta==0)
  18. {
  19. key[i].judge_sta=1;
  20. key[i].key_count=0;
  21. }
  22. }
  23. break;
  24. case 1:
  25. {
  26. if(key[i].key_sta==0)
  27. {
  28. key[i].judge_sta=2;
  29. }
  30. else
  31. key[i].judge_sta=0;
  32. }
  33. break;
  34. case 2:
  35. {
  36. if(key[i].key_sta==1&&key[i].key_count<70)
  37. {
  38. if(key[i].double_timerEN==0)
  39. {
  40. key[i].double_timerEN=1;
  41. key[i].double_timer=0;
  42. }
  43. else
  44. {
  45. key[i].double_flag=1;
  46. key[i].double_timerEN=0;
  47. }
  48. key[i].judge_sta=0;
  49. }
  50. else if(key[i].key_sta==1&&key[i].key_count>=70) key[i].judge_sta=0;
  51. else
  52. {
  53. key[i].key_count++;
  54. if(key[i].key_count>=70) key[i].long_flag=1;
  55. }
  56. }
  57. break;
  58. }
  59. if(key[i].double_timerEN==1)
  60. {
  61. key[i].double_timer++;
  62. if(key[i].double_timer>35)
  63. {
  64. key[i].short_flag=1;
  65. key[i].double_timerEN=0;
  66. }
  67. }
  68. }
  69. }
  70. }

双击代码需要理解其中的逻辑就比较简单。

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号