你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32G431RBTx 基本模块 KEY 长按(持续响应)以及双击

[复制链接]
STMCU小助手 发布时间:2023-3-1 22:54
前言
按键,一般有单击和长按两种考法,我们已经将单击的写法掌握之后就要开始学习长按的写法。

KEY(long)
原理图,配置元素,配置步骤,生成工程这四步与【STM32G431RBTx】备战蓝桥杯嵌入式→基本模块→KEY→单击一致,我们只需要对上篇文章中的interrupt.c,interrupt.h,main.c文件修改即可。

1.测试代码
interrupt.h:
  1. #ifndef __INTERRUPT_H__
  2. #define __INTERRUPT_H__

  3. #include "main.h"
  4. #include "stdbool.h" //如果需要添加bool形就要加入这个头文件

  5. struct keys
  6. {
  7.         unsigned char judge_sta;
  8.         bool key_sta;
  9.         bool single_flag;
  10.         unsigned key_time; //按键持续按下的时间
  11.         bool long_flag; //长按响应标志
  12. };


  13. #endif
复制代码

interrupt.c
  1. #include "interrupt.h"

  2. struct keys key[4] = {0, 0, 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(unsigned char 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_time = 0; //松开之后让按键持续按下时间归零
  21.                                         }
  22.                                         break;
  23.                                 }
  24.                                 case 1:
  25.                                 {
  26.                                         if(key[i].key_sta == 0)
  27.                                         {
  28.                                                 key[i].judge_sta = 2;
  29.                                         }
  30.                                         else
  31.                                         {
  32.                                                 key[i].judge_sta = 0;
  33.                                         }
  34.                                         break;
  35.                                 }
  36.                                 case 2:
  37.                                 {
  38.                                         if(key[i].key_sta == 1)
  39.                                         {
  40.                                                 key[i].judge_sta = 0; //松开按键后让其进入case0,防止长按松开之后仍在响应
  41.                                                 if(key[i].key_time <= 70) //只有按下小于700ms才算一次单击
  42.                                                 {
  43.                                                         key[i].single_flag = 1;
  44.                                                 }
  45.                                         }
  46.                                         else
  47.                                         {
  48.                                                 key[i].key_time++; //如果按下按键不松,按键时间开始增加
  49.                                                 if(key[i].key_time > 70) //一旦超过700ms,长按开始响应
  50.                                                 {
  51.                                                         key[i].long_flag = 1;
  52.                                                 }
  53.                                         }
  54.                                 }
  55.                                 break;
  56.                         }
  57.                 }
  58.         }
  59. }

复制代码

main.c中main函数部分:
  1. int main(void)
  2. {
  3.   /* USER CODE BEGIN 1 */

  4.   /* USER CODE END 1 */

  5.   /* MCU Configuration--------------------------------------------------------*/

  6.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  7.   HAL_Init();

  8.   /* USER CODE BEGIN Init */

  9.   /* USER CODE END Init */

  10.   /* Configure the system clock */
  11.   SystemClock_Config();

  12.   /* USER CODE BEGIN SysInit */

  13.   /* USER CODE END SysInit */

  14.   /* Initialize all configured peripherals */
  15.   MX_GPIO_Init();
  16.   MX_TIM3_Init();
  17.   /* USER CODE BEGIN 2 */
  18.         LCD_Init();
  19.         LCD_Clear(Black);
  20.         LCD_SetBackColor(Black);
  21.         LCD_SetTextColor(White);
  22.         HAL_TIM_Base_Start_IT(&htim3);
  23.   /* USER CODE END 2 */

  24.   /* Infinite loop */
  25.   /* USER CODE BEGIN WHILE */
  26.   while (1)
  27.   {
  28.     /* USER CODE END WHILE */

  29.     /* USER CODE BEGIN 3 */
  30.                 if(key[0].single_flag) //key0短按响应
  31.                 {
  32.                         LCD_DisplayStringLine(Line5, "      key0down      ");
  33.                         key[0].single_flag = 0;
  34.                 }
  35.                 if(key[0].long_flag) //key0长按响应(一直响应)
  36.                 {
  37.                         LCD_DisplayStringLine(Line5, "      key0long      ");
  38.                         key[0].long_flag = 0;                        
  39.                 }
  40.                 if(key[1].single_flag) //key1短按响应
  41.                 {
  42.                         j = 0;
  43.                         char text[30];
  44.                         sprintf(text, "      key1down%d     ", j);
  45.                         LCD_DisplayStringLine(Line6,(unsigned char *)text);
  46.                         key[1].single_flag = 0;               
  47.                 }
  48.                 if(key[1].long_flag) //key1长按响应(一直响应)
  49.                 {
  50.                         j++;
  51.                         char text[30];
  52.                         sprintf(text, "      key1long%d", j);
  53.                         LCD_DisplayStringLine(Line6,(unsigned char *)text);
  54.                         key[1].long_flag = 0;                        
  55.                 }
  56.   }
  57.   /* USER CODE END 3 */
  58. }
复制代码


2.测试效果

d9e7963294aa49ae9c1463f0a1154cb1.gif


KEY(double)
由于蓝桥杯至今没有考过双击,所以这里只把代码放到这里,下面的代码是将单,双,长合在一起的,如果要原始工程可以私信给我。
interrupt.h:
  1. #ifndef __INTERRUPT_H_
  2. #define __INTERRUPT_H_

  3. #include "main.h"
  4. #include "stdbool.h"

  5. struct keys
  6. {
  7.         unsigned char judge_sta;
  8.         bool key_sta;
  9.         bool single_key_flag;
  10.         bool long_flag;
  11.         unsigned int key_time;
  12.         bool double_click_timerEN;
  13.         unsigned int double_click_time;
  14.         bool double_key_flag;
  15.         bool long_key_flag;
  16. };

  17. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);

  18. #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.                
  12.                 for(int i = 0; i < 4; i++)
  13.                 {
  14.                         switch(key[i].judge_sta)
  15.                         {
  16.                                 case 0:
  17.                                 {
  18.                                         if(key[i].key_sta == 0)
  19.                                         {
  20.                                                 key[i].judge_sta = 1;
  21.                                                 key[i].key_time = 0;
  22.                                         }
  23.                                 }
  24.                                 break;
  25.                                 case 1:
  26.                                 {
  27.                                         if(key[i].key_sta == 0)
  28.                                         {
  29.                                                 key[i].judge_sta = 2;

  30.                                         }
  31.                                         else
  32.                                         {
  33.                                                 key[i].judge_sta = 0;
  34.                                         }
  35.                                 }
  36.                                 break;
  37.                                 case 2:
  38.                                 {
  39.                                         if(key[i].key_sta == 1 && key[i].key_time < 70)
  40.                                         {
  41.                                                 if(key[i].double_click_timerEN == 0)
  42.                                                 {
  43.                                                         key[i].double_click_timerEN = 1;
  44.                                                         key[i].double_click_time = 0;
  45.                                                 }
  46.                                                 else
  47.                                                 {
  48.                                                         key[i].double_key_flag = 1;
  49.                                                         key[i].double_click_timerEN = 0;
  50.                                                 }
  51.                                                 key[i].judge_sta = 0;
  52.                                         }
  53.                                         else if(key[i].key_sta == 1 && key[i].key_time >= 70) key[i].judge_sta = 0;
  54.                                         else
  55.                                         {
  56.                                                 if(key[i].key_time >= 70) key[i].long_key_flag = 1;
  57.                                                 key[i].key_time++;
  58.                                         }
  59.                                         break;
  60.                                 }
  61.                         }
  62.                         if(key[i].double_click_timerEN == 1)
  63.                         {
  64.                                 key[i].double_click_time++;
  65.                                 if(key[i].double_click_time >= 20)
  66.                                 {
  67.                                         key[i].single_key_flag = 1;
  68.                                         key[i].double_click_timerEN = 0;
  69.                                 }
  70.                         }
  71.                 }
  72.         }
  73. }

复制代码

main.c:
  1. /* USER CODE BEGIN Header */
  2. /**
  3.   ******************************************************************************
  4.   * @file           : main.c
  5.   * @brief          : Main program body
  6.   ******************************************************************************
  7.   * @attention
  8.   *
  9.   * <h2><center>© Copyright (c) 2023 STMicroelectronics.
  10.   * All rights reserved.</center></h2>
  11.   *
  12.   * This software component is licensed by ST under BSD 3-Clause license,
  13.   * the "License"; You may not use this file except in compliance with the
  14.   * License. You may obtain a copy of the License at:
  15.   *                        opensource.org/licenses/BSD-3-Clause
  16.   *
  17.   ******************************************************************************
  18.   */
  19. /* USER CODE END Header */
  20. /* Includes ------------------------------------------------------------------*/
  21. #include "main.h"
  22. #include "tim.h"
  23. #include "gpio.h"

  24. /* Private includes ----------------------------------------------------------*/
  25. /* USER CODE BEGIN Includes */
  26. #include "led.h"
  27. #include "lcd.h"
  28. #include "stdio.h"
  29. #include "interrupt.h"
  30. /* USER CODE END Includes */

  31. /* Private typedef -----------------------------------------------------------*/
  32. /* USER CODE BEGIN PTD */

  33. /* USER CODE END PTD */

  34. /* Private define ------------------------------------------------------------*/
  35. /* USER CODE BEGIN PD */
  36. /* USER CODE END PD */

  37. /* Private macro -------------------------------------------------------------*/
  38. /* USER CODE BEGIN PM */

  39. /* USER CODE END PM */

  40. /* Private variables ---------------------------------------------------------*/

  41. /* USER CODE BEGIN PV */
  42. extern struct keys key[];
  43. /* USER CODE END PV */

  44. /* Private function prototypes -----------------------------------------------*/
  45. void SystemClock_Config(void);
  46. /* USER CODE BEGIN PFP */
  47. /* USER CODE END PFP */

  48. /* Private user code ---------------------------------------------------------*/
  49. /* USER CODE BEGIN 0 */

  50. /* USER CODE END 0 */

  51. /**
  52.   * @brief  The application entry point.
  53.   * @retval int
  54.   */
  55. int main(void)
  56. {
  57.   /* USER CODE BEGIN 1 */
  58.   /* USER CODE END 1 */

  59.   /* MCU Configuration--------------------------------------------------------*/

  60.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  61.   HAL_Init();

  62.   /* USER CODE BEGIN Init */

  63.   /* USER CODE END Init */

  64.   /* Configure the system clock */
  65.   SystemClock_Config();

  66.   /* USER CODE BEGIN SysInit */

  67.   /* USER CODE END SysInit */

  68.   /* Initialize all configured peripherals */
  69.   MX_GPIO_Init();
  70.   MX_TIM3_Init();
  71.   /* USER CODE BEGIN 2 */

  72.   /* USER CODE END 2 */

  73.   /* Infinite loop */
  74.   /* USER CODE BEGIN WHILE */


  75.        
  76.         HAL_TIM_Base_Start_IT(&htim3);
  77.         LED_Disp(0x00); //这里是把灯全部灭掉

  78.   while (1)
  79.   {
  80.     /* USER CODE END WHILE */

  81.     /* USER CODE BEGIN 3 */
  82.                 if(key[0].single_key_flag == 1)
  83.                 {
  84.                         HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_8);
  85.                         key[0].single_key_flag = 0;
  86.                 }
  87.                 if(key[0].long_key_flag == 1)
  88.                 {
  89.                         LED_Disp(0xff);
  90.                         key[0].long_key_flag = 0;
  91.                 }
  92.                 if(key[0].double_key_flag == 1)
  93.                 {
  94.                         HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_15);
  95.                         key[0].double_key_flag = 0;
  96.                 }
  97.                 if(key[1].single_key_flag == 1)
  98.                 {
  99.                         HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_9);
  100.                         key[1].single_key_flag = 0;
  101.                 }
  102.                 if(key[1].long_key_flag == 1)
  103.                 {
  104.                         LED_Disp(0x00);
  105.                         key[1].long_key_flag = 0;
  106.                 }
  107.                 if(key[1].double_key_flag == 1)
  108.                 {
  109.                         HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_14);
  110.                         key[1].double_key_flag = 0;
  111.                 }

  112.                                                                                       
  113.   }
  114.   /* USER CODE END 3 */
  115. }

  116. /**
  117.   * @brief System Clock Configuration
  118.   * @retval None
  119.   */
  120. void SystemClock_Config(void)
  121. {
  122.   RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  123.   RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  124.   /** Configure the main internal regulator output voltage
  125.   */
  126.   HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);
  127.   /** Initializes the RCC Oscillators according to the specified parameters
  128.   * in the RCC_OscInitTypeDef structure.
  129.   */
  130.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  131.   RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  132.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  133.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  134.   RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV3;
  135.   RCC_OscInitStruct.PLL.PLLN = 20;
  136.   RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  137.   RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
  138.   RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  139.   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  140.   {
  141.     Error_Handler();
  142.   }
  143.   /** Initializes the CPU, AHB and APB buses clocks
  144.   */
  145.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  146.                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  147.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  148.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  149.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  150.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  151.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  152.   {
  153.     Error_Handler();
  154.   }
  155. }

  156. /* USER CODE BEGIN 4 */

  157. /* USER CODE END 4 */

  158. /**
  159.   * @brief  This function is executed in case of error occurrence.
  160.   * @retval None
  161.   */
  162. void Error_Handler(void)
  163. {
  164.   /* USER CODE BEGIN Error_Handler_Debug */
  165.   /* User can add his own implementation to report the HAL error return state */
  166.   __disable_irq();
  167.   while (1)
  168.   {
  169.   }
  170.   /* USER CODE END Error_Handler_Debug */
  171. }

  172. #ifdef  USE_FULL_ASSERT
  173. /**
  174.   * @brief  Reports the name of the source file and the source line number
  175.   *         where the assert_param error has occurred.
  176.   * @param  file: pointer to the source file name
  177.   * @param  line: assert_param error line source number
  178.   * @retval None
  179.   */
  180. void assert_failed(uint8_t *file, uint32_t line)
  181. {
  182.   /* USER CODE BEGIN 6 */
  183.   /* User can add his own implementation to report the file name and line number,
  184.      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  185.   /* USER CODE END 6 */
  186. }
  187. #endif /* USE_FULL_ASSERT */

  188. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

复制代码

led.h:
  1. #ifndef __LED_H__
  2. #define __LED_H__

  3. #include "main.h"

  4. void LED_Disp(unsigned char dsLED);

  5. #endif

复制代码

led.c
  1. #include "led.h"

  2. void LED_Disp(unsigned char dsLED)
  3. {
  4.         HAL_GPIO_WritePin(GPIOC, GPIO_PIN_All, GPIO_PIN_SET);
  5.         HAL_GPIO_WritePin(GPIOC, dsLED << 8, GPIO_PIN_RESET);
  6.         HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
  7.         HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
  8. }

复制代码

————————————————
版权声明:火花页.



收藏 评论0 发布时间:2023-3-1 22:54

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版