当前位置: 首页 > news >正文

蓝桥杯—STM32G431RBT6按键的多方式使用(包含软件消抖方法精讲)从原理层面到实际应用(一)

新建工程教程见http://t.csdnimg.cn/JySLg

点亮LED教程见http://t.csdnimg.cn/Urlj5

末尾含所有代码

目录

按键原理图

一、按键使用需要解决的问题

1.抖动

     1.什么是抖动

     2.抖动类型

     3.如何去消除抖动

FIRST.延时函数消抖(缺点:浪费CPU资源)

SECOND.中断加定时器消抖(缺点:浪费定时器)

THIRD.状态机消抖

2.前期配置及效果展示

二、代码编写及功能实现

1.延时函数消抖(不推荐)

code.c(含代码解释)

code.h

main.c

2.定时器中断消抖(单击)

code.c(含代码解释)

code.h

main.c

3.状态机消抖(不推荐)

4.三行代码算法(最为推荐)(原理难理解,见下一篇文章)

code.c

code.h

main.c

三.按键拓展功能(使用三代码,长按和短按,双击和单击)

1.长按和短按

code.c

code.h

main.c

stm32g4xx-it.c(用定时器)

2.双击和单击

code.c

code.h

main.c

stm32g4xx-it.c(用定时器)

四:源代码(所有工程文件)


按键原理图

按键1,2,3,4分别对应PB0-PB1-PB2-PA0, 在默认情况下按键是由上拉电阻,上拉到高电平,当按键按下后,GND就会跟引脚导通,从而使引脚变为到低电平。

按键信号的识别:一般来说,按键的两个引脚的一端通过电阻上拉到高电平,另一端则接地。
在没有按键按下的时候,输入引脚为高电平,当有按键按下,输入引脚则为低电平。
通过反复读取按键输入引脚的信号,然后识别高低电平来判断是否有按键触发。

一、按键使用需要解决的问题

1.抖动

     1.什么是抖动

    在机械按键的触点闭合和断开时,都会产生抖动,为了保证系统能正确识别按键的开关,就必须对按键的抖动进行处理。
 按键的抖动对于人类来说是感觉不到的,但对单片机来说,则是完全可以感应到的,而且还是一个很“漫长”的过程,因为单片机处理的速度在“微秒”级,而按键抖动的时间至少在“毫秒”级。
片机如果在触点抖动期间检测按键的通断状态,则可能导致判断出错,即按键一次按下或释放被错误地认为是多次操作,从而引起误处理。因此,为了确保单片机对一次按键动作只作—次响应,就必须考虑如何消除按键抖动的影响。

     2.抖动类型

  1. 触点闭合抖动:在按键刚被按下时,触点会在极短时间内多次快速闭合和断开,这是由于机械弹性和电路瞬态响应导致的。
  2. 触点稳定闭合:经过抖动阶段后,触点稳定闭合,保持导通状态。
  3. 触点断开抖动:在释放按键时,同样会出现触点快速抖动的情况。

这种抖动现象可能会导致误触发或不准确的检测,对电路和系统的正常运行产生影响。为了避免按键抖动带来的问题,通常需要采取一些防抖措施,如软件延时滤波等。

     3.如何去消除抖动

常用的消抖方式有硬件消抖(通过RC低通滤波器来实现)和软件消抖(本文章主要探讨软件消抖)

FIRST.延时函数消抖(缺点:浪费CPU资源)
SECOND.中断加定时器消抖(缺点:浪费定时器)
THIRD.状态机消抖

2.前期配置及效果展示

点亮前AND按键之后点亮

二、代码编写及功能实现

1.延时函数消抖(不推荐)

code.c(含代码解释)
#include "headfile.h"void led_show(uint8_t led,uint8_t mode)
{
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);if(mode)
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8<<(led-1),GPIO_PIN_RESET);else
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8<<(led -1),GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);}void Delay(unsigned int t)//这是一个定义的延时函数,接收一个无符号整数 t 作为参数。
{while(t--);//这是一个循环语句。当 t 不为 0 时,循环会一直执行。在每次循环中,t 的值减 1。//通过这种方式,消耗一定的时间,从而实现延时的效果。当 t 减到 0 时,循环结束。
}void key_scan()//扫描按键函数
{if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==GPIO_PIN_RESET)//判断GPIOB端口的GPIO_PIN_0引脚是否被按下(低电平,即GPIO_PIN_RESET)。{Delay(1000);//延时 1000 毫秒,以消除按键抖动。if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==GPIO_PIN_RESET)//再次判断按键是否仍然处于按下状态。{HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_8);//如果按键仍然被按下,就切换GPIOC端口的GPIO_PIN_8引脚的状态(即进行一次翻转操作)。while(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==GPIO_PIN_RESET);//通过一个循环,等待按键被释放(即等待GPIOB端口的GPIO_PIN_0引脚变为高电平)。	}}
}
code.h
#ifndef _code_h
#define _code_h
#include "stm32g4xx.h"                  // Device headervoid led_show(uint8_t led,uint8_t mode);
void key_scan(void);
void Delay(unsigned int t);#endif
main.c
/* USER CODE BEGIN Header */
/********************************************************************************* @file           : main.c* @brief          : Main program body******************************************************************************* @attention** Copyright (c) 2024 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "gpio.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "headfile.h"
/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD *//* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV *//* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 *//* USER CODE END 0 *//*** @brief  The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();/* USER CODE BEGIN 2 *//* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){  key_scan();/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}/*** @brief System Clock Configuration* @retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Configure the main internal regulator output voltage*/HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV3;RCC_OscInitStruct.PLL.PLLN = 20;RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK){Error_Handler();}
}/* USER CODE BEGIN 4 *//* USER CODE END 4 *//*** @brief  This function is executed in case of error occurrence.* @retval None*/
void Error_Handler(void)
{/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */
}#ifdef  USE_FULL_ASSERT
/*** @brief  Reports the name of the source file and the source line number*         where the assert_param error has occurred.* @param  file: pointer to the source file name* @param  line: assert_param error line source number* @retval None*/
void assert_failed(uint8_t *file, uint32_t line)
{/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

2.定时器中断消抖(单击)

code.c(含代码解释)
#include "headfile.h"void led_show(uint8_t led,uint8_t mode)
{
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);if(mode)
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8<<(led-1),GPIO_PIN_RESET);else
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8<<(led -1),GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);}struct keys key[4]={0,0,0};//创建结构体数组,分别对应4个按键
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance==TIM4)//判断定时器4进入中断,在 C 语言中,->是结构体指针访问成员的操作符。{key[0].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);//读取当前按键状态key[1].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);//读取当前按键状态key[2].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);//读取当前按键状态key[3].key_sta=HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);//读取当前按键状态for(unsigned char i=0;i<4;i++)//对4个按键进行判断{switch(key[i].junk_sta)//按下按键后进入中断的次数并判断{case 0://当按键按下后,第一次不做任何操作,用于消抖10ms{if(key[i].key_sta==0)//当按键状态为按下的时候{key[i].junk_sta=1;//此时不进行任何操作,这相当于等待了一段时间,更新标志位为1}}break;case 1://第二次检测到按键按下后,将单击标志位single_flag设置为1{if(key[i].key_sta==0)//按键状态还是为按下时{key[i].junk_sta=2;//更新标志位为2key[i].single_flag=1;//中断次数记为1}}break;case 2://直到按键松开才将计算值设置为0,重新开始判断,这样单击不受长按影响{if(key[i].key_sta==1)//按键状态为松开时{key[i].junk_sta=0;//更新标志位为0}}break;			}}}
}
code.h
#ifndef _code_h
#define _code_h
#include "stdbool.h"
#include "stm32g4xx.h"                  // Device header
void led_show(uint8_t led,uint8_t mode);struct keys
{bool key_std;//用于存储按键状态unsigned char junk_std;//用于记录按键按下后进入中断次数bool single_flag;//单击按下标志位
};
extern struct keys key[4];//创建结构体数组,分别对应4个按键#endif
main.c
/* USER CODE BEGIN Header */
/********************************************************************************* @file           : main.c* @brief          : Main program body******************************************************************************* @attention** Copyright (c) 2024 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "tim.h"
#include "gpio.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "headfile.h"
/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD *//* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV *//* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 *//* USER CODE END 0 *//*** @brief  The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_TIM4_Init();/* USER CODE BEGIN 2 */HAL_TIM_Base_Start_IT(&htim4);//启动TIM4/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){  if(key[0].single_flag==1)//当单击标志位为1{led_show(1,1);//点亮key[0].single_flag=0;//再将单击标志位置为0}if(key[1].single_flag==1)//同上{led_show(2,1);key[1].single_flag=0;}/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}/*** @brief System Clock Configuration* @retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Configure the main internal regulator output voltage*/HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV3;RCC_OscInitStruct.PLL.PLLN = 20;RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK){Error_Handler();}
}/* USER CODE BEGIN 4 *//* USER CODE END 4 *//*** @brief  This function is executed in case of error occurrence.* @retval None*/
void Error_Handler(void)
{/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */
}#ifdef  USE_FULL_ASSERT
/*** @brief  Reports the name of the source file and the source line number*         where the assert_param error has occurred.* @param  file: pointer to the source file name* @param  line: assert_param error line source number* @retval None*/
void assert_failed(uint8_t *file, uint32_t line)
{/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

3.状态机消抖(不推荐)

代码冗长,不方便使用

4.三行代码算法(最为推荐)(原理难理解,见下一篇文章)

code.c
#include "headfile.h"void led_show(uint8_t led,uint8_t mode)
{
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);if(mode)
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8<<(led-1),GPIO_PIN_RESET);else
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8<<(led -1),GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);} 
uint8_t Key_Scan(void)
{uint8_t Key_val=0;if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==GPIO_PIN_RESET){Key_val=1;}if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==GPIO_PIN_RESET){Key_val=2;}if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)==GPIO_PIN_RESET){Key_val=3;}if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==GPIO_PIN_RESET){Key_val=4;}return Key_val;
}
extern uint8_t key_rval;
uint8_t Key_up,Key_down,key_old;void Key_Proc(void)	
{key_rval=Key_Scan();Key_down=key_rval&(key_rval^key_old);Key_up=~key_rval&(key_rval^key_old);key_old=key_rval;if(Key_down==1){HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_8);}}
code.h
#ifndef _code_h
#define _code_h
#include "stdbool.h"
#include "stm32g4xx.h"                  // Device header
#include "headfile.h"
void led_show(uint8_t led,uint8_t mode);
uint8_t Key_Scan(void);
void Key_Proc(void);#endif
main.c
/* USER CODE BEGIN Header */
/********************************************************************************* @file           : main.c* @brief          : Main program body******************************************************************************* @attention** Copyright (c) 2024 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "gpio.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "headfile.h"
/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD *//* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV */uint8_t key_rval;
/* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 *//* USER CODE END 0 *//*** @brief  The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();/* USER CODE BEGIN 2 *//* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){  Key_Proc();/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}/*** @brief System Clock Configuration* @retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Configure the main internal regulator output voltage*/HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV3;RCC_OscInitStruct.PLL.PLLN = 20;RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK){Error_Handler();}
}/* USER CODE BEGIN 4 *//* USER CODE END 4 *//*** @brief  This function is executed in case of error occurrence.* @retval None*/
void Error_Handler(void)
{/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */
}#ifdef  USE_FULL_ASSERT
/*** @brief  Reports the name of the source file and the source line number*         where the assert_param error has occurred.* @param  file: pointer to the source file name* @param  line: assert_param error line source number* @retval None*/
void assert_failed(uint8_t *file, uint32_t line)
{/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

三.按键拓展功能(使用三代码,长按和短按,双击和单击)

1.长按和短按

code.c
#include "headfile.h"void led_show(uint8_t led,uint8_t mode)
{
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);if(mode)
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8<<(led-1),GPIO_PIN_RESET);else
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8<<(led -1),GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);} 
uint8_t Key_Scan(void)
{uint8_t Key_val=0;if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==GPIO_PIN_RESET){Key_val=1;}if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==GPIO_PIN_RESET){Key_val=2;}if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)==GPIO_PIN_RESET){Key_val=3;}if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==GPIO_PIN_RESET){Key_val=4;}return Key_val;
}
extern uint8_t key_rval;
uint8_t Key_up,Key_down,key_old;
uint32_t keytime;
void Key_Proc(void)	
{key_rval=Key_Scan();Key_down=key_rval&(key_rval^key_old);Key_up=~key_rval&(key_rval^key_old);key_old=key_rval;if(Key_down==1){keytime=0;}if(keytime<800){if(Key_up==1)//短按亮LED1{led_show(1,1);}}else{if(key_rval==1)//长按亮LED2,熄灭LED1{led_show(2,1);led_show(1,0);}}
}
code.h
#ifndef _code_h
#define _code_h
#include "stdbool.h"
#include "stm32g4xx.h"                  // Device header
#include "headfile.h"
void led_show(uint8_t led,uint8_t mode);
uint8_t Key_Scan(void);
void Key_Proc(void);#endif
main.c
/* USER CODE BEGIN Header */
/********************************************************************************* @file           : main.c* @brief          : Main program body******************************************************************************* @attention** Copyright (c) 2024 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "gpio.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "headfile.h"
/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD *//* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV */uint8_t key_rval;
/* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 *//* USER CODE END 0 *//*** @brief  The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();/* USER CODE BEGIN 2 *//* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){  Key_Proc();/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}/*** @brief System Clock Configuration* @retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Configure the main internal regulator output voltage*/HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV3;RCC_OscInitStruct.PLL.PLLN = 20;RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK){Error_Handler();}
}/* USER CODE BEGIN 4 *//* USER CODE END 4 *//*** @brief  This function is executed in case of error occurrence.* @retval None*/
void Error_Handler(void)
{/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */
}#ifdef  USE_FULL_ASSERT
/*** @brief  Reports the name of the source file and the source line number*         where the assert_param error has occurred.* @param  file: pointer to the source file name* @param  line: assert_param error line source number* @retval None*/
void assert_failed(uint8_t *file, uint32_t line)
{/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
stm32g4xx-it.c(用定时器)
/* USER CODE BEGIN Header */
/********************************************************************************* @file    stm32g4xx_it.c* @brief   Interrupt Service Routines.******************************************************************************* @attention** Copyright (c) 2024 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/
/* USER CODE END Header *//* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32g4xx_it.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD *//* USER CODE END TD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD *//* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
extern uint32_t keytime;
/* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 *//* USER CODE END 0 *//* External variables --------------------------------------------------------*//* USER CODE BEGIN EV *//* USER CODE END EV *//******************************************************************************/
/*           Cortex-M4 Processor Interruption and Exception Handlers          */
/******************************************************************************/
/*** @brief This function handles Non maskable interrupt.*/
void NMI_Handler(void)
{/* USER CODE BEGIN NonMaskableInt_IRQn 0 *//* USER CODE END NonMaskableInt_IRQn 0 *//* USER CODE BEGIN NonMaskableInt_IRQn 1 */while (1){}/* USER CODE END NonMaskableInt_IRQn 1 */
}/*** @brief This function handles Hard fault interrupt.*/
void HardFault_Handler(void)
{/* USER CODE BEGIN HardFault_IRQn 0 *//* USER CODE END HardFault_IRQn 0 */while (1){/* USER CODE BEGIN W1_HardFault_IRQn 0 *//* USER CODE END W1_HardFault_IRQn 0 */}
}/*** @brief This function handles Memory management fault.*/
void MemManage_Handler(void)
{/* USER CODE BEGIN MemoryManagement_IRQn 0 *//* USER CODE END MemoryManagement_IRQn 0 */while (1){/* USER CODE BEGIN W1_MemoryManagement_IRQn 0 *//* USER CODE END W1_MemoryManagement_IRQn 0 */}
}/*** @brief This function handles Prefetch fault, memory access fault.*/
void BusFault_Handler(void)
{/* USER CODE BEGIN BusFault_IRQn 0 *//* USER CODE END BusFault_IRQn 0 */while (1){/* USER CODE BEGIN W1_BusFault_IRQn 0 *//* USER CODE END W1_BusFault_IRQn 0 */}
}/*** @brief This function handles Undefined instruction or illegal state.*/
void UsageFault_Handler(void)
{/* USER CODE BEGIN UsageFault_IRQn 0 *//* USER CODE END UsageFault_IRQn 0 */while (1){/* USER CODE BEGIN W1_UsageFault_IRQn 0 *//* USER CODE END W1_UsageFault_IRQn 0 */}
}/*** @brief This function handles System service call via SWI instruction.*/
void SVC_Handler(void)
{/* USER CODE BEGIN SVCall_IRQn 0 *//* USER CODE END SVCall_IRQn 0 *//* USER CODE BEGIN SVCall_IRQn 1 *//* USER CODE END SVCall_IRQn 1 */
}/*** @brief This function handles Debug monitor.*/
void DebugMon_Handler(void)
{/* USER CODE BEGIN DebugMonitor_IRQn 0 *//* USER CODE END DebugMonitor_IRQn 0 *//* USER CODE BEGIN DebugMonitor_IRQn 1 *//* USER CODE END DebugMonitor_IRQn 1 */
}/*** @brief This function handles Pendable request for system service.*/
void PendSV_Handler(void)
{/* USER CODE BEGIN PendSV_IRQn 0 *//* USER CODE END PendSV_IRQn 0 *//* USER CODE BEGIN PendSV_IRQn 1 *//* USER CODE END PendSV_IRQn 1 */
}/*** @brief This function handles System tick timer.*/
void SysTick_Handler(void)
{/* USER CODE BEGIN SysTick_IRQn 0 *//* USER CODE END SysTick_IRQn 0 */HAL_IncTick();/* USER CODE BEGIN SysTick_IRQn 1 */keytime++;/* USER CODE END SysTick_IRQn 1 */
}/******************************************************************************/
/* STM32G4xx Peripheral Interrupt Handlers                                    */
/* Add here the Interrupt Handlers for the used peripherals.                  */
/* For the available peripheral interrupt handler names,                      */
/* please refer to the startup file (startup_stm32g4xx.s).                    */
/******************************************************************************//* USER CODE BEGIN 1 *//* USER CODE END 1 */

2.双击和单击

code.c
#include "headfile.h"void led_show(uint8_t led,uint8_t mode)
{
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);if(mode)
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8<<(led-1),GPIO_PIN_RESET);else
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8<<(led -1),GPIO_PIN_SET);HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);} 
uint8_t Key_Scan(void)
{uint8_t Key_val=0;if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==GPIO_PIN_RESET){Key_val=1;}if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==GPIO_PIN_RESET){Key_val=2;}if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)==GPIO_PIN_RESET){Key_val=3;}if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==GPIO_PIN_RESET){Key_val=4;}return Key_val;
}
extern uint8_t key_rval;
uint8_t Key_up,Key_down,key_old;
uint32_t keytime;
uint8_t key_temp,key_flag;//temp保存第一次的按键值,flag用来判断是否可以计时
void Key_Proc(void)	
{key_rval=Key_Scan();Key_down=key_rval&(key_rval^key_old);Key_up=~key_rval&(key_rval^key_old);key_old=key_rval;if(Key_up){key_temp=Key_up;if(key_flag==0){keytime=0;key_flag=1;}elsekey_flag=0;//双击结束后的下一次可以开始计时}if(key_flag==1){if(keytime<300){if(Key_down==1&&key_temp==1)//双击,可修改按键{led_show(2,1);led_show(1,0);}	}else{if(key_temp==1)//单击{led_show(1,1);led_show(2,0);}key_flag=0;}}
}
code.h
#ifndef _code_h
#define _code_h
#include "stdbool.h"
#include "stm32g4xx.h"                  // Device header
#include "headfile.h"
void led_show(uint8_t led,uint8_t mode);
uint8_t Key_Scan(void);
void Key_Proc(void);#endif
main.c
/* USER CODE BEGIN Header */
/********************************************************************************* @file           : main.c* @brief          : Main program body******************************************************************************* @attention** Copyright (c) 2024 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "gpio.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "headfile.h"
/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD *//* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV */uint8_t key_rval;
/* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 *//* USER CODE END 0 *//*** @brief  The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();/* USER CODE BEGIN 2 *//* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){  Key_Proc();/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}/*** @brief System Clock Configuration* @retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Configure the main internal regulator output voltage*/HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV3;RCC_OscInitStruct.PLL.PLLN = 20;RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK){Error_Handler();}
}/* USER CODE BEGIN 4 *//* USER CODE END 4 *//*** @brief  This function is executed in case of error occurrence.* @retval None*/
void Error_Handler(void)
{/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */
}#ifdef  USE_FULL_ASSERT
/*** @brief  Reports the name of the source file and the source line number*         where the assert_param error has occurred.* @param  file: pointer to the source file name* @param  line: assert_param error line source number* @retval None*/
void assert_failed(uint8_t *file, uint32_t line)
{/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
stm32g4xx-it.c(用定时器)
/* USER CODE BEGIN Header */
/********************************************************************************* @file    stm32g4xx_it.c* @brief   Interrupt Service Routines.******************************************************************************* @attention** Copyright (c) 2024 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/
/* USER CODE END Header *//* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32g4xx_it.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD *//* USER CODE END TD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD *//* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
extern uint32_t keytime;
/* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 *//* USER CODE END 0 *//* External variables --------------------------------------------------------*//* USER CODE BEGIN EV *//* USER CODE END EV *//******************************************************************************/
/*           Cortex-M4 Processor Interruption and Exception Handlers          */
/******************************************************************************/
/*** @brief This function handles Non maskable interrupt.*/
void NMI_Handler(void)
{/* USER CODE BEGIN NonMaskableInt_IRQn 0 *//* USER CODE END NonMaskableInt_IRQn 0 *//* USER CODE BEGIN NonMaskableInt_IRQn 1 */while (1){}/* USER CODE END NonMaskableInt_IRQn 1 */
}/*** @brief This function handles Hard fault interrupt.*/
void HardFault_Handler(void)
{/* USER CODE BEGIN HardFault_IRQn 0 *//* USER CODE END HardFault_IRQn 0 */while (1){/* USER CODE BEGIN W1_HardFault_IRQn 0 *//* USER CODE END W1_HardFault_IRQn 0 */}
}/*** @brief This function handles Memory management fault.*/
void MemManage_Handler(void)
{/* USER CODE BEGIN MemoryManagement_IRQn 0 *//* USER CODE END MemoryManagement_IRQn 0 */while (1){/* USER CODE BEGIN W1_MemoryManagement_IRQn 0 *//* USER CODE END W1_MemoryManagement_IRQn 0 */}
}/*** @brief This function handles Prefetch fault, memory access fault.*/
void BusFault_Handler(void)
{/* USER CODE BEGIN BusFault_IRQn 0 *//* USER CODE END BusFault_IRQn 0 */while (1){/* USER CODE BEGIN W1_BusFault_IRQn 0 *//* USER CODE END W1_BusFault_IRQn 0 */}
}/*** @brief This function handles Undefined instruction or illegal state.*/
void UsageFault_Handler(void)
{/* USER CODE BEGIN UsageFault_IRQn 0 *//* USER CODE END UsageFault_IRQn 0 */while (1){/* USER CODE BEGIN W1_UsageFault_IRQn 0 *//* USER CODE END W1_UsageFault_IRQn 0 */}
}/*** @brief This function handles System service call via SWI instruction.*/
void SVC_Handler(void)
{/* USER CODE BEGIN SVCall_IRQn 0 *//* USER CODE END SVCall_IRQn 0 *//* USER CODE BEGIN SVCall_IRQn 1 *//* USER CODE END SVCall_IRQn 1 */
}/*** @brief This function handles Debug monitor.*/
void DebugMon_Handler(void)
{/* USER CODE BEGIN DebugMonitor_IRQn 0 *//* USER CODE END DebugMonitor_IRQn 0 *//* USER CODE BEGIN DebugMonitor_IRQn 1 *//* USER CODE END DebugMonitor_IRQn 1 */
}/*** @brief This function handles Pendable request for system service.*/
void PendSV_Handler(void)
{/* USER CODE BEGIN PendSV_IRQn 0 *//* USER CODE END PendSV_IRQn 0 *//* USER CODE BEGIN PendSV_IRQn 1 *//* USER CODE END PendSV_IRQn 1 */
}/*** @brief This function handles System tick timer.*/
void SysTick_Handler(void)
{/* USER CODE BEGIN SysTick_IRQn 0 *//* USER CODE END SysTick_IRQn 0 */HAL_IncTick();/* USER CODE BEGIN SysTick_IRQn 1 */keytime++;/* USER CODE END SysTick_IRQn 1 */
}/******************************************************************************/
/* STM32G4xx Peripheral Interrupt Handlers                                    */
/* Add here the Interrupt Handlers for the used peripherals.                  */
/* For the available peripheral interrupt handler names,                      */
/* please refer to the startup file (startup_stm32g4xx.s).                    */
/******************************************************************************//* USER CODE BEGIN 1 *//* USER CODE END 1 */

四:源代码(所有工程文件)

通过网盘分享的文件:消抖大礼包.zip
链接: https://pan.baidu.com/s/1BrKxstlCPuXrsmvk51JxfQ?pwd=0820 提取码: 0820

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • WPF DataGrid 列表中,DataGrid.Columns 列根据不同的值显示不同内容
  • 基于Netty实现TCP客户端:封装断线重连、连接保持
  • 僵尸网络开发了新的攻击技术和基础设施
  • 【C++指南】作用域限定符 :: 使用详解
  • Pandas Series对象创建,属性,索引及运算详解
  • 【系统架构设计师】软件架构的概念(经典习题)
  • 深度学习--------------序列模型
  • 17、Python如何读写文本文件
  • k8s-API 访问控制
  • AMD ThinkSystem服务器上的 Linux 和 C 状态设置 - Lenovo ThinkSystem
  • sqlgun靶场漏洞挖掘
  • 解码未来:H.265与H.266技术对比及EasyCVR视频汇聚平台编码技术优势
  • SpringBoot集成Thymeleaf模板引擎,为什么使用(详细介绍)
  • 【计算机网络】数据链路层深度解析
  • 初写MySQL四张表:(3/4)
  • 【个人向】《HTTP图解》阅后小结
  • 2018以太坊智能合约编程语言solidity的最佳IDEs
  • android高仿小视频、应用锁、3种存储库、QQ小红点动画、仿支付宝图表等源码...
  • Babel配置的不完全指南
  • Bytom交易说明(账户管理模式)
  • Fabric架构演变之路
  • FineReport中如何实现自动滚屏效果
  • oldjun 检测网站的经验
  • React-redux的原理以及使用
  • SQLServer插入数据
  • tweak 支持第三方库
  • Vue ES6 Jade Scss Webpack Gulp
  • Zsh 开发指南(第十四篇 文件读写)
  • 闭包--闭包之tab栏切换(四)
  • 搞机器学习要哪些技能
  • 融云开发漫谈:你是否了解Go语言并发编程的第一要义?
  • 使用SAX解析XML
  • 文本多行溢出显示...之最后一行不到行尾的解决
  • 学习笔记:对象,原型和继承(1)
  • 不要一棍子打翻所有黑盒模型,其实可以让它们发挥作用 ...
  • ######## golang各章节终篇索引 ########
  • ###C语言程序设计-----C语言学习(3)#
  • #define,static,const,三种常量的区别
  • #Js篇:单线程模式同步任务异步任务任务队列事件循环setTimeout() setInterval()
  • ()、[]、{}、(())、[[]]等各种括号的使用
  • (day6) 319. 灯泡开关
  • (delphi11最新学习资料) Object Pascal 学习笔记---第13章第1节 (全局数据、栈和堆)
  • (ZT)薛涌:谈贫说富
  • (阿里云在线播放)基于SpringBoot+Vue前后端分离的在线教育平台项目
  • (附源码)apringboot计算机专业大学生就业指南 毕业设计061355
  • (附源码)ssm考生评分系统 毕业设计 071114
  • (附源码)计算机毕业设计ssm基于Internet快递柜管理系统
  • (算法)硬币问题
  • (学习日记)2024.04.04:UCOSIII第三十二节:计数信号量实验
  • (转)GCC在C语言中内嵌汇编 asm __volatile__
  • .net core 依赖注入的基本用发
  • .NET MAUI Sqlite程序应用-数据库配置(一)
  • .NET/C#⾯试题汇总系列:⾯向对象
  • .NET使用HttpClient以multipart/form-data形式post上传文件及其相关参数
  • @Transactional类内部访问失效原因详解