Chapter 12 GPIO 输入--按键检测

Chapter 12 GPIO 输入--按键检测

硬件设计

软件设计

编程要点

  • 使用 GPIO 端口时钟
  • 初始化 GPIO 目标引脚为输入模式(浮空输入)
  • 编写简单测试程序,检测按键的状态:实现按键控制 LED

代码分析

1、按键引脚宏定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#ifndef	__BSP_KEY_H
#define __BSP_KEY_H

#include "stm32f10x.h"

/* Define the value of key pressed status */
#define KEY_ON 0
#define KEY_OFF 1

/* Keys I/O definitions */
#define KEY1_GIPO_CLK RCC_APB2Periph_GPIOC
#define KEY1_GPIO_PORT GPIOC
#define KEY1_GPIO_PIN GPIO_Pin_13

/* Keys I/O definitions */
#define KEY2_GIPO_CLK RCC_APB2Periph_GPIOC
#define KEY2_GPIO_PORT GPIOC
#define KEY2_GPIO_PIN GPIO_Pin_12

/* Function declarations */
void Key_GPIO_Config(void);
uint8_t Key_Scan(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

#endif

2、按键 GPIO 初始化函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* @brief Key Initialization function
* @param none
* @retval none
*/
void Key_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(KEY1_GIPO_CLK|KEY2_GIPO_CLK, ENABLE);

GPIO_InitStructure.GPIO_Pin = KEY1_GIPO_CLK;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(KEY1_GPIO_PORT, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = KEY2_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(KEY2_GPIO_PORT, &GPIO_InitStructure);
}

3、检测按键的状态

GPIO 引脚的输入电平可能过读取 IDR 寄存器对应的数据位来获取,而,

STM32 标准库提供了端口位获取状态函数:GPIO_ReadInputDataBit

开发板按键已提供硬件消除波纹,在 Key_Scan 函数中未做软件滤波。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* @brief Check if if specifiied key is pressed.
* @param GPIOx: Specified Port, x=(A..G)
* @param GPIO_Pin: Specified Pin, GPIO_Pin_x (x=0~15)
* @retval Status of key
* @arg KEY_ON: Key pressed
* @arg KEY_OFF: Key released
*/
uint8_t Key_Scan(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
/* Check if key pressed */
if(GPIO_ReadInputDataBit(KEY1_GPIO_PORT, KEY1_GPIO_PIN) == KEY_ON)
{
while(GPIO_ReadInputDataBit(KEY1_GPIO_PORT, KEY1_GPIO_PIN) == KEY_ON);
return KEY_ON;
} else
{
return KEY_OFF;
}
}

4、main 函数

初始化 LED 和按键后,在 while 函数里不断调用 Key_Scan 函数,并判断其返回值是否为表示按键按下的 LED_ON,若是反转 LED 的状态。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include "stm32f10x.h"

#include "bsp_led.h"
#include "bsp_key.h"

/**
* @brief main function
* @param none
* @retval none
*/
int main(void)
{
// System clock has been set to 72MHz

LED_GPIO_Config();
Key_GPIO_Config();

while(1)
{
if(Key_Scan(KEY1_GPIO_PORT, KEY1_GPIO_PIN) == KEY_ON)
{
LED_G_TOGGLE;
}
}
}

下载验证

编程、下载,复位开发板,按下按键可以控制 LED 亮、灭。