STM学习- -库函数按键输入实验
主要内容:
- 按键输入驱动管脚确认;
- 软体处理;
- 对应GPIO时钟使能:RCC_APB2PeriphClockCmd()
- 初始化IO模式,上拉、下拉输入 CPIO_Init();
- 扫描IO口电平
- C语言关键字Static局部变量作用;
- Static申明局部变量 存储在静态储存区
- 函数调用后值会一直保持,具有记忆功能
int getValue(void)
{
static int flag=0; 局部变量该条指令使用了一次,后面不在执行
flag++;
return flag;
}
结果:1,2,3,4,5...
}
重点掌握内容:
-
管脚配置函数;
-
管脚输入状态读取函数;
-
头文件编写;
-
按键扫描函数;
流程图
按键GPIO IO输入管脚及外围电路:
- 输入模式:上拉输入、下拉输入、模拟输入、浮空输入
- KEY0~KEY2为上拉输入(按键按下低电触发)
- WKUP为下拉输入(按键按下高电平触发)
/
软体处理:
-
库函数加载
-
GPIO 源文件stm32f10x_gpio.c 头文件stm32f10x_gpio.h加载
-
stm32f10x_rcc.h
-
misc.h
- 编写步骤
按键初始化函数
按键初始化函数
void Key_Init(void) //IO初始化
{
GPIO_InitTypeDef GPIO_InitStructure; //Type 类型 Structure结构
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOA, ENABLE); //使能PB,PE端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4; //LED0-->PB.5 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; ///设置成上拉输入
GPIO_Init(GPIOE, &GPIO_InitStructure); //根据设定参数初始化GPIOB.5
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; ///初始化 WK_UP-->GPIOA.0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //初始化 WK_UP-->GPIOA.0 下拉输入
GPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIOB.5
}
GPIO按键输入函数
#define KEY0 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)//读取按键0
#define KEY1 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3)//读取按键1
#define KEY2 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)//读取按键2
#define WK_UP GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)//读取按键3(WK_UP)
GPIO按键判断函数
//mode:0,不支持连续按;1,支持连续按;
//0,没有任何按键按下
//1,KEY0按下
//2,KEY1按下
//3,KEY2按下
//4,KEY3按下 WK_UP
//注意此函数有响应优先级,KEY0>KEY1>KEY2>KEY3!!
u8 Key_Scan(u8 mode)
{
static u8 Key_up=1;//按键按松开标志
if(mode) Key_up=1; //支持连按
if(Key_up && (KEY0==0||KEY1==0||KEY2==0||WK_UP==1))
{
delay_ms(10);//去抖动
Key_up=0;
if(KEY0==0) return KEY0_PRES;
else if(KEY1==0) return KEY1_PRES;
else if(KEY2==0) return KEY2_PRES;
else if(WK_UP==1) return WKUP_PRES;
}
else if( KEY0==1 && KEY1==1 && KEY2==1 && WK_UP==0) Key_up=1;
return 0; // 无按键按下
}
管脚映射:
#ifndef __KEY_H
#define __KEY_H
#include "sys.h"
#define KEY0 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)//读取按键0
#define KEY1 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3)//读取按键1
#define KEY2 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)//读取按键2
#define WK_UP GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)//读取按键3(WK_UP)
#define KEY0_PRES 1 //KEY0按下 PRES->描述
#define KEY1_PRES 2 //KEY1按下
#define KEY2_PRES 3 //KEY2按下
#define WKUP_PRES 4 //KEY_UP按下(即WK_UP/KEY_UP)
void Key_Init(void);//IO初始化
u8 Key_Scan(u8); //按键扫描函数
#endif
软体代码:
--------------------------------------------------------------------------------------------------------
//主函数:
# int main(void)
{
u8 Key=0;
delay_init();
Led_Init();
Buzzer_Init();
Key_Init();
//Led0=Led1=1;//初始状态LED灭
//Buzzer=0; //初始状态蜂鸣器不响
while(1)
{
Key=Key_Scan(0);//不支持按键连续按下
if(Key) //扫描后读取键值
{
switch(Key)
{
case WKUP_PRES: //控制蜂鸣器
Buzzer=! Buzzer;
break;
case KEY2_PRES: //控制LED0翻转
Led0=!Led0;
break;
case KEY1_PRES: //控制LED1翻转
Led1=!Led1;
break;
case KEY0_PRES: //同时控制LED0,LED1翻转
Led0=!Led0;
Led1=!Led1;
break;
}
}
else delay_ms(10); ;
}
}
----------------------------------------------------------------------------------------------------------
//Key IO初始化
void Key_Init(void) //IO初始化
{
GPIO_InitTypeDef GPIO_InitStructure; //Type 类型 Structure结构
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOA, ENABLE); //使能PB,PE端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4; //LED0-->PB.5 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; ///设置成上拉输入
GPIO_Init(GPIOE, &GPIO_InitStructure); //根据设定参数初始化GPIOB.5
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; ///初始化 WK_UP-->GPIOA.0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //初始化 WK_UP-->GPIOA.0 下拉输入
GPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIOB.5
}
//按键处理函数
//返回按键值
//mode:0,不支持连续按;1,支持连续按;
//0,没有任何按键按下
//1,KEY0按下
//2,KEY1按下
//3,KEY2按下
//4,KEY3按下 WK_UP
//注意此函数有响应优先级,KEY0>KEY1>KEY2>KEY3!!
u8 Key_Scan(u8 mode)
{
static u8 Key_up=1;//按键按松开标志
if(mode) Key_up=1; //支持连按
if(Key_up && (KEY0==0||KEY1==0||KEY2==0||WK_UP==1))
{
delay_ms(10);//去抖动
Key_up=0;
if(KEY0==0) return KEY0_PRES;
else if(KEY1==0) return KEY1_PRES;
else if(KEY2==0) return KEY2_PRES;
else if(WK_UP==1) return WKUP_PRES;
}
else if( KEY0==1 && KEY1==1 && KEY2==1 && WK_UP==0) Key_up=1;
return 0; // 无按键按下
}
#ifndef __KEY_H
#define __KEY_H
#include "sys.h"
#define KEY0 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)//读取按键0
#define KEY1 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3)//读取按键1
#define KEY2 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)//读取按键2
#define WK_UP GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)//读取按键3(WK_UP)
#define KEY0_PRES 1 //KEY0按下 PRES->描述
#define KEY1_PRES 2 //KEY1按下
#define KEY2_PRES 3 //KEY2按下
#define WKUP_PRES 4 //KEY_UP按下(即WK_UP/KEY_UP)
void Key_Init(void);//IO初始化
u8 Key_Scan(u8); //按键扫描函数
#endif
----------------------------------------------------------------------------------------------