STM32按键初始化及扫描函数详解
这段代码实现了按键的初始化和按键扫描函数。
首先是KEY_Init函数,用于对按键的引脚和中断进行初始化。具体步骤如下:
- 使能AFIO外设时钟和GPIOA、GPIOB外设时钟。
- 配置GPIOA引脚8、GPIOB引脚15、GPIOB引脚5、GPIOB引脚6的工作模式为上拉输入。
- 配置GPIOA的引脚8、GPIOB的引脚15、GPIOB的引脚5、GPIOB的引脚6的中断线路。
- 初始化EXTI_InitStructure结构体变量,配置中断触发方式为下降沿触发,使能中断线路。
- 根据EXTI_InitStructure中的参数配置外设EXTI寄存器。
接下来是KEY_Scan函数,用于扫描按键的状态,并返回按键的值。具体步骤如下:
- 定义一个静态变量key_up,用于标识按键是否松开。
- 如果mode为1,则将key_up设置为1,即支持连续按键。
- 如果KEY1、KEY2、KEY3或KEY4中任意一个按键被按下,则执行以下操作:
- 延时10毫秒进行去抖动。
- 将key_up设置为0,表示按键按下。
- 根据按键的状态返回相应的按键值。
- 如果KEY1、KEY2、KEY3和KEY4都松开,则将key_up设置为1。
- 如果没有任何按键按下,则返回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;// 无按键按下
}
原文地址: https://www.cveoy.top/t/topic/lbT 著作权归作者所有。请勿转载和采集!