这段代码实现了按键的初始化和按键扫描函数。

首先是KEY_Init函数,用于对按键的引脚和中断进行初始化。具体步骤如下:

  1. 使能AFIO外设时钟和GPIOA、GPIOB外设时钟。
  2. 配置GPIOA引脚8、GPIOB引脚15、GPIOB引脚5、GPIOB引脚6的工作模式为上拉输入。
  3. 配置GPIOA的引脚8、GPIOB的引脚15、GPIOB的引脚5、GPIOB的引脚6的中断线路。
  4. 初始化EXTI_InitStructure结构体变量,配置中断触发方式为下降沿触发,使能中断线路。
  5. 根据EXTI_InitStructure中的参数配置外设EXTI寄存器。

接下来是KEY_Scan函数,用于扫描按键的状态,并返回按键的值。具体步骤如下:

  1. 定义一个静态变量key_up,用于标识按键是否松开。
  2. 如果mode为1,则将key_up设置为1,即支持连续按键。
  3. 如果KEY1、KEY2、KEY3或KEY4中任意一个按键被按下,则执行以下操作:
    • 延时10毫秒进行去抖动。
    • 将key_up设置为0,表示按键按下。
    • 根据按键的状态返回相应的按键值。
  4. 如果KEY1、KEY2、KEY3和KEY4都松开,则将key_up设置为1。
  5. 如果没有任何按键按下,则返回5,表示无按键按下。

总体上,这段代码实现了对按键的初始化和按键状态的扫描,可以根据实际需求进行修改和扩展。

void KEY_Init(void) //IO初始化
{
	GPIO_InitTypeDef GPIO_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	EXTI_InitTypeDef EXTI_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);	//使能复用功能时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB,ENABLE);//使能PORTA,PORTE时钟

	
	GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_15|GPIO_Pin_5|GPIO_Pin_6;//mode KEY2
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入
	GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB1,3,
	//初始化 Key1-->GPIOA.8	  上拉输入
	GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_8;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置上拉输入	  
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.8

	NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;			//使能按键WK_UP所在的外部中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;	//抢占优先级2, 
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;					//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;								//使能外部中断通道
	NVIC_Init(&NVIC_InitStructure);
	
	NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;			//使能按键WK_UP所在的外部中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;	//抢占优先级2, 
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;					//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;								//使能外部中断通道
	NVIC_Init(&NVIC_InitStructure);


	//GPIOB.15 中断线以及中断初始化配置   下降沿触发
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource15);
	 //GPIOA.8 中断线以及中断初始化配置   下降沿触发
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource8);
	 //GPIOB.5 中断线以及中断初始化配置   下降沿触发
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource5);
	 //GPIOB.6 中断线以及中断初始化配置   下降沿触发
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource6);

	EXTI_InitStructure.EXTI_Line=EXTI_Line15;	//KEY3
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);	 	//根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器


	EXTI_InitStructure.EXTI_Line=EXTI_Line8;	//KEY3
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);	 	//根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器

	EXTI_InitStructure.EXTI_Line=EXTI_Line5;	//KEY3
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);	 	//根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器

	EXTI_InitStructure.EXTI_Line=EXTI_Line6;	//KEY4
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);	 	//根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器

}
//按键处理函数
//返回按键值
//mode:0,不支持连续按;1,支持连续按;
//0,m0de按下
//1,KEY0按下
//2,KEY1按下
//注意此函数有响应优先级,KEY0>KEY1>KEY2
u8 KEY_Scan(u8 mode)
{	 
	static u8 key_up=1;//按键按松开标志
	if(mode)key_up=1;  //支持连按		
	if(KEY1==0||KEY2==0||KEY3==0||KEY4==0)
	{
		delay_ms(10);//去抖动 
		key_up=0;
		if(KEY1==0)return KEY1_PRES;
		else if(KEY2==0)return KEY2_PRES;
		else if(KEY3==0)return KEY3_PRES;
		else if(KEY4==0)return KEY4_PRES;
	}
	else if(KEY1==1&&KEY2==1&&KEY3==1&&KEY4==1)key_up=1;
	return 5;// 无按键按下
}
STM32按键初始化及扫描函数详解

原文地址: https://www.cveoy.top/t/topic/lbT 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录