1.按键介绍:
按键WK_UP接在低电平,当按键按下检测到高电平;KEY0和KEY1接在高电平,当按键按下检测到低电平;
2.本次实验步骤:
(1)GPIO输入操作:
- 读取IO口输入电平的库函数:uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
- 读取IO口输入电平操作的寄存器:GPIOx_IDR(端口输入寄存器);
- 使用位带操作读取IO口输入电平:PBout(5) 读取GPIOB.5口电平,PEout(5)读取GPIOE.5口电平;
(2)按键输入步骤:
- 使能按键对应IO口时钟;
- 初始化IO口模式;
- 扫描IO口电平;
(3)按键扫描思路:
(4)static关键字介绍:
static关键字声明的局部变量,存储在静态存储区中;它在函数调用结束后不会被释放,会一直保留其值;因此对于static声明的变量具有记忆功能;
3.实验:
当KEY0按下LE0亮,当KEY1按下LED1亮,WK_UP按下LED0和LED1都亮:
(1)主函数:
#include "delay.h"
#include "key.h"
int main(){
u8 data=0;
delay_init(); //延时初始化
LED_Init(); //LED初始化
KEY_Init(); //按键初始化
while(1){
data=KEY_Scan(0); //扫描按键->不支持连续按下
if(data!=0){
switch(data)
{
case 1: //按键KEY0按下
LED0=!LED0;
break;
case 2: //按键KEY1按下
LED1=!LED1;
break;
case 3: //按键WK_UP按下
LED0=!LED0;
LED1=!LED1;
break;
}
}
}
}
(2)头文件
#ifndef __KEY_H
#define __KEY_H
#include "led.h"
#define LED0 PBout(5)
#define LED1 PEout(5)
//读取按键io的输入电平
#define KEY0 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)
#define KEY1 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3)
#define WK_UP GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)
//定义数值,便于阅读
#define KEY0_down 1
#define KEY1_down 2
#define WK_UP_down 3
typedef unsigned char u8;
void KEY_Init(void); //按键初始化
u8 KEY_Scan(u8 mode); //按键扫描
#endif
(3)按键输入功能函数:
#include "stm32f10x.h"
#include "key.h"
#include "delay.h"
/*
功能:按键初始化
变量:无
返回值:无
*/
void KEY_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
//1.使能时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE,ENABLE);
//2.配置io KEY0->PE4 输入模式不需要设置速度
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU; //输入上拉模式->由原理图可以看出,当接入高电平时按键工作
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_4; //PE4
GPIO_Init(GPIOE,&GPIO_InitStruct);
//配置io KEY1->PE3
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU; //输入上拉模式->由原理图可以看出,当接入高电平时按键工作
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_3; //PE3
GPIO_Init(GPIOE,&GPIO_InitStruct);
//配置io WK_UP->PA0
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPD; //输入下拉模式->由原理图可以看出,当接入低电平时按键工作
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0; //PA3
GPIO_Init(GPIOE,&GPIO_InitStruct);
}
/*
功能:按键扫描
变量:mode=0 -> 单次按下 ; mode=1 -> 连续按下
返回值:扫描的按键值
*/
u8 KEY_Scan(u8 mode)
{
static u8 key=1; //使用静态变量定义按下的标志(保持被修改后的值,不会被重置) ,key=1没按下,key=0按下
if(mode==1) //当支持连续按下时,将key设置为1,使之一直处于被扫描状态
key=1;
if((key==1)&&(KEY0==0||KEY1==0||WK_UP==1)) //判断是否具有按下的标志和检测哪一个按键被按下
{
delay_ms(10); //消抖
if(KEY0==0)
return KEY0_down; //KEY0按下则返回KEY0_down(KEY0_down在头文件中定义有特殊值)
else if(KEY1==0)
return KEY1_down;
else if(WK_UP==1)
return WK_UP_down;
}
else if(KEY0==1&&KEY1==1&&WK_UP==0) //当按键都没有被按下时,设置key=1
{
key=1; //没有按键按下的标志
}
return 0; //当无按键按下返回0
}