前言:
STM32按键输入——GPIO做输入实验主要是根据正点原子视频及例程书写,主要作为个人学习笔记使用,如有错误,望不吝指出。主要分为两种按键逻辑:一种是持续按下只响应一次,一种是持续按下持续响应。
根据原理图对应调用引脚即可
具体步骤
使能按键对应IO口时钟,调用函数
初始化IO模式
扫描IO口电平
这里GPIO输入操作有三种:
1.调用库函数
uint8_t GPIO_ReadInputDataBit (GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin);
2.操作寄存器
GPIOx_IDR:端口输入寄存器
3.位带操作
PEin(n) 读取GPIOE.n口电平
IO口初始化和时钟使能
#include "stm32f10x.h"
#include "key.h"
#include "sys.h"
#include "delay.h"
void KEY_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;//调用结构体重命名
_HAL_RCC_GPIOA_CLK_ENABLE(); //开启GPIOA时钟
__HAL_RCC_GPIOC_CLK_ENABLE(); //开启GPIOC时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //PA0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //下拉输入
HAL_GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; //PA15
GPIO_InitStructure.GPIO_Mode=GPIO_IPU; //上拉输入
HAL_GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //PC5
GPIO_InitStructure.GPIO_Mode=GPIO_IPU; //上拉输入
HAL_GPIO_Init(GPIOC,&GPIO_InitStructure);
}
程序示例
持续按下只响应一次
像对于电源开关之类的按键,就要求只会响应一次开和关,即第一次按下了第二次没有按下无效,第一次没按下第二次按下了有效
u8 KEY_Scan(void)
{
static u8 key_up=1;//定义一个静态变量代表按键按松开标志,第一次触发后其直接return0
if(key_up&&key_flag == 1)
{
delay_ms(10); //消抖
key_up=0;
if(key_flag == 1)//再次确认按键按下
return KEY0_Result;
}
else if(key_flag == 0)
key_up=1;
return 0;// 无按键按下
}
持续按下持续响应
可以发现第二种写法在51中学习过,像电视机遥控板按钮,按下按钮之后它要一直响应(比如一直换台),直到你松开按钮之后它才停止响应,对于这种模式的程序,可以用这种
u8 KEY_Scan(void)
{
static u8 key_up=1;//定义一个静态变量代表按键按松开标志 ,第一次触发后其值为0则之后就不会在进行下面的第一个if语句直接return0
if(key_up&&key_flag==1)
{
delay_ms(10);//去抖动
key_up=0;
if(key_flag==1)
return KEY0_Result;
}
else if(key_flag==1)key_up=1;
return 0;// 无按键按下
}
可切换按键模式
u8 KEY_Scan(u8 mode)
{
static u8 key_up = 1; //按键按松开标志
if(mode) key_up = 1; //支持连按,如果Mode等于1则可以连按
if(key_up &&
(KEY0==0||KEY1==0||WK_UP==1)) //KEY0==0||KEY1==0||WK_UP==1分别代表三个按键按下
{
delay_ms(10);//去抖动
key_up=0;
if(KEY0==0)return KEY0_Result; //分别返回1,2,3。不同返回值不同功能
else if(KEY1==0)return KEY1_Result;
else if(WK_UP==1)return WKUP_Result;
}
else if(KEY0==1&&KEY1==1&&WK_UP==0)key_up=1; //都没有按下按钮
return 0; // 无按键按下
}
记得在key.h里定义返回值
#define KEY0_Result 1 //KEY0按下
#define KEY1_Result 2 //KEY1按下
#define WKUP_Result 3 //KEY_UP按下 控制蜂鸣器
按键可以与之前的蜂鸣器和点灯结合起来
记录
这里记录一下static的运用:
一般定义一个变量后,变量会被自动释放,下次跑程序会重新开始。但是用了static后会保留,具有记忆功能,且只初始化一次,只执行一次,第二次跳过初始化。
分为两种触发:边沿触发和电平触发
边沿触发:由高到低或由低到高这一瞬间触发
电平触发:在高或低电平保持的时间内触发
其主要区别是:如果是采用边沿触发,检测到电平变化会中断,但是如果中断检测口一直保持某一电平,则无法产生下次中断,需要等下次检测到电平变化才会中断。中断得到响应后由硬件自动清除。
如果是采用电平触发,检测到低/高电平会中断,但是如果中断检测口一直保持低电平,中断处理完成后,会继续产生下次中断,需要检测到高电平才会停止中断产生。中断得到响应后由硬件手动清除。