新建板级支持包bsp_key.c和bsp_key.h
GPIO输入配置过程:
- 定义初始化结构体;
- 开启RCC时钟,非常重要;
- 写入引脚和模式配置,不需要配置速度;
- 调用初始化函数,将初始化结构体写入对应的GPIO端口。
bsp_key.c包含两个函数,一个是初始化函数,另一个是按键扫描函数,会按键被按下时,返回按键的状态。
bsp_key.c
#include "bsp_key.h"
/**
* @brief 按键初始化函数
*/
void KEY_GPIO_Config(void)
{
// 定义GPIO初始化结构体
GPIO_InitTypeDef GPIO_InitStruct;
// 开启RCC时钟,非常关键
RCC_APB2PeriphClockCmd(KEY1_GPIO_CLK | KEY2_GPIO_CLK, ENABLE);
// 配置初始化结构体,传入具体参数
GPIO_InitStruct.GPIO_Pin = KEY1_GPIO_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(KEY1_GPIO_PORT, &GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = KEY2_GPIO_PIN;
GPIO_Init(KEY2_GPIO_PORT, &GPIO_InitStruct);
}
/**
* @brief 按键扫描函数
* @param GPIOx 扫描的GPIO口
* @param GPIO_Pin 扫描的GPIO引脚
*/
uint8_t key_scan(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
{
uint8_t key_status;
if (GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) == KEY_ON)
{
// 松手检测
while (GPIO_ReadInputDataBit(GPIOx, GPIO_Pin) == KEY_ON);
key_status = KEY_ON;
}
else
{
key_status = KEY_OFF;
}
return key_status;
}
bsp_key.h中对按键的硬件参数,按键的状态都进行了宏定义封装,提高程序的可移植性。
bsp_key.h
#ifndef __BSP_KEY_H
#define __BSP_KEY_H
#include "stm32f10x.h"
// 硬件封装宏
#define KEY1_GPIO_PIN GPIO_Pin_0
#define KEY1_GPIO_PORT GPIOA
#define KEY1_GPIO_CLK RCC_APB2Periph_GPIOA
#define KEY2_GPIO_PIN GPIO_Pin_13
#define KEY2_GPIO_PORT GPIOC
#define KEY2_GPIO_CLK RCC_APB2Periph_GPIOC
// 按键状态宏
#define KEY_ON 1
#define KEY_OFF 0
void KEY_GPIO_Config(void);
uint8_t key_scan(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin);
#endif /* __BSP_KEY_H */
在主函数中while循环中进行调用
main.c
#include "stm32f10x.h"
#include "bsp_led.h"
#include "bsp_key.h"
void delay(uint32_t count);
int main(void)
{
LED_GPIO_Config();
KEY_GPIO_Config();
while (1)
{
// 第一个按键按下(红灯反转)
if (key_scan(KEY1_GPIO_PORT, KEY1_GPIO_PIN) == KEY_ON)
{
LED_R_TOGGLE;
LED_B_OFF;
}
// 第二个按键按下(蓝灯反转)
if (key_scan(KEY2_GPIO_PORT, KEY2_GPIO_PIN) == KEY_ON)
{
LED_R_OFF;
LED_B_TOGGLE;
}
}
}
void delay(uint32_t count)
{
for (; count != 0; count--);
}