1 软件设计
为了使程序更有条例,方便移植在"工程模板"之上新建"bsp_key.c"及"bsp_key.h"文件,这些文件也可根据您的喜好命名,这 些文件不属于STM32HAL库的内容,是由我们自己根据应用需要编写的
1.1 编程要点
1)使能GPIO端口时钟;
2) 初始化GPIO目标引脚为输入模式(浮空输入);
3.)编写简单测试程序,检测按键的状态,实现按键控制LED灯。
1.2 代码分析
1.2.1 按键引脚宏定义
为了方便移植,我们把按键引脚等资源宏定义到 "bsp_key.h"文件中,以下代码根据按键的硬件连接,把检测按键输入的GPIO端口、GPIO引脚号以及GPIO端口时钟 封装起来了。以下是我的开发板的定义,不同硬件根据自己资源更改。
#ifndef __KEY_H
#define __KEY_H
#include "stm32f1xx.h"
#include "main.h"
//引脚定义
/*******************************************************/
#define KEY1_PIN GPIO_PIN_0
#define KEY1_GPIO_PORT GPIOA
#define KEY1_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
#define KEY2_PIN GPIO_PIN_13
#define KEY2_GPIO_PORT GPIOC
#define KEY2_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
/*******************************************************/
/** 按键按下标置宏
* 按键按下为高电平,设置 KEY_ON=1, KEY_OFF=0
* 若按键按下为低电平,把宏设置成KEY_ON=0 ,KEY_OFF=1 即可
*/
#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 /* __KEY_H */
1.2.2 按键初始化函数
利用上面的宏,编写按键的初始化函数。代码如下:
void Key_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/*开启按键GPIO口的时钟*/
KEY1_GPIO_CLK_ENABLE();
KEY2_GPIO_CLK_ENABLE();
/*选择按键的引脚*/
GPIO_InitStructure.Pin = KEY1_PIN;
/*设置引脚为输入模式*/
GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
/*设置引脚不上拉也不下拉*/
GPIO_InitStructure.Pull = GPIO_NOPULL;
/*使用上面的结构体初始化按键*/
HAL_GPIO_Init(KEY1_GPIO_PORT, &GPIO_InitStructure);
/*选择按键的引脚*/
GPIO_InitStructure.Pin = KEY2_PIN;
/*使用上面的结构体初始化按键*/
HAL_GPIO_Init(KEY2_GPIO_PORT, &GPIO_InitStructure);
}
1.2.3 检测按键的状态
初始化按键后,就可以通过检测对应引脚的电平来判断按键状态,需注意的是我的按键是有硬件消抖的,若你的按键没有的话需要添加软件消抖,简单的软件消抖只需要加延时就可以了,代码如下:
uint8_t Key_Scan(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin)
{
/*检测是否有按键按下 */
if(HAL_GPIO_ReadPin(GPIOx,GPIO_Pin) == KEY_ON )
{
/*等待按键释放 */
while(HAL_GPIO_ReadPin(GPIOx,GPIO_Pin) == KEY_ON);
return KEY_ON;
}
else
return KEY_OFF;
}
1.2.4 主函数代码
在主函数进行初始化,然后调用Key_Scan函数,轮询检测按键的状态,按下一次LED灯翻转一次。代码如下:
int main(void)
{
/* 系统时钟初始化成72MHz */
SystemClock_Config();
/* LED 端口初始化 */
LED_GPIO_Config();
/*初始化按键*/
Key_GPIO_Config();
/* 轮询按键状态,若按键按下则反转LED */
while(1)
{
if( Key_Scan(KEY1_GPIO_PORT,KEY1_PIN) == KEY_ON )
{
/*LED1反转*/
LED1_TOGGLE;
}
if( Key_Scan(KEY2_GPIO_PORT,KEY2_PIN) == KEY_ON )
{
/*LED2反转*/
LED2_TOGGLE;
}
}
}