十二、按键点灯
首先我们先来一个前置步骤添加一下串口相关的文件,我们使用的是创建工程模板时使用的那个uart文件夹里的文件。
1. 配置流程
一般使用GPIO的端口输入功能,都需要有以下几个步骤。
- 关闭寄存器写保护
- 配置GPIO的模式 开发板的按键使用的是KEY,接到了单片机的PA0引脚上,因此需要配置PA0引脚的状态。
1.1 关闭急促请你写保护
我们要配置GPIO参数,所以需要打开寄存器的写保护。 可以写为:
// 关闭GPIO寄存器写保护
LL_PERIPH_WE(LL_PERIPH_GPIO);
2
函数原型:
void LL_PERIPH_WE(uint32_t u32Peripheral) 唯一的参数是用来选择解锁的外设。
1.2 配置GPIO模式
通过前面章节的按键检测原理知道需要检测按键引脚的电平状态来判断按键是否按下,要检测电平引脚的状态,就需要将按键配置为输入模式。开发板上的按键默认接的是低电平,也就按键松开的状态需要是低电平,在默认状态下需要将按键的状态保持为低电平。开发板上已经做了下拉处理,代码中可以配置为无上下拉也可以配置为下拉。
使能按键的引脚为输入模式,转换为代码为:
stc_gpio_init_t stcGpioInit; // 定义GPIO结构体
(void)GPIO_StructInit(&stcGpioInit); // 使用默认参数初始化
stcGpioInit.u16PinDir = PIN_DIR_IN; // 输入模式
(void)GPIO_Init(GPIO_PORT_A, GPIO_PIN_00, &stcGpioInit); // 初始化GPIO
2
3
4
5
2. 获取按键的状态
配置好GPIO之后,就可以检测按键引脚的状态了。
首先还是到hc32_ll_gpio.h中去查找对应的获取引脚状态的库函数。
en_pin_state_t GPIO_ReadInputPins(uint8_t u8Port, uint16_t u16Pin)
- u8Port:表示 GPIO 端口号,使用 GPIO_PORT_x,其中 x 可以是每个产品的 @ref GPIO_Port_Source 中的后缀。
- u16Pin:表示 GPIO 引脚号,使用 GPIO_PIN_x,其中 x 可以是每个产品的 @ref GPIO_Pins_Define 中的后缀。
- en_pin_state_t:表示返回值为枚举类型 en_pin_state_t,用于表示指定的 GPIO 端口引脚的输入值(0或1)。
2
3
4
这个函数可以获取引脚电平状态,有两个参数,第一个参数就是要获取引脚的端口,第二个参数就是要获取的引脚,还有一个返回值,返回值是获取到的引脚的状态,如果为高电平就为1,如果为低电平就为0。
获取PA0引脚的电平状态转换为代码就是:
/* 获取PA0引脚的高低电平状态 */
GPIO_ReadInputPins(GPIO_PORT_A, GPIO_PIN_00);
2
判断按键是否按下只需要判断检测的引脚电平是高电平即可。
转化为代码为:
/* 获取PA0引脚的高低电平状态 */
if( SET == GPIO_ReadInputPins(GPIO_PORT_A, GPIO_PIN_00) )
{
}
2
3
4
5
前面说过,机械按键按下之后会发生抖动,有硬件消抖和软件消抖两种,开发板上做了简单的硬件消抖处理,但硬件消抖只能改善,不能消除。所以在实际工程中需要使用软件消抖来实现,我们这里用软件消抖来实现。
可以在第一次检测到按键按下之后延迟一定的时间,等按键稳定之后再次检测按键按下,即可判断按键是按下状态。在按键按下之后就可以执行功能,比如点灯。在按键按下之后可以通过检测按键的引脚的状态变为低电平判断按键是否松开,这里用串口打印按键按下和松开的状态,最终编写代码为:
void key_scan(void)
{
if( SET == GPIO_ReadInputPins(GPIO_PORT_A, GPIO_PIN_00) )
{
/* 延迟消抖 */
delay_ms(20);
if( flag )
{
GPIO_ResetPins(GPIO_PORT_B, GPIO_PIN_02);
flag = 0;
}
else
{
GPIO_SetPins(GPIO_PORT_B, GPIO_PIN_02);
flag = 1;
}
printf("Key Press!!\r\n");
while( SET == GPIO_ReadInputPins(GPIO_PORT_A, GPIO_PIN_00) == SET ) // 等待按键松开
{
}
/* 延迟消抖 */
delay_ms(20);
printf("Key Release!!\r\n");
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
上面实现的效果就是按一次按键,led开启,再按一次按键,led关闭,每次按键按下和松开都会在串口打印key press和key release。
3. 实验现象
烧写我们的代码之后,按下一次按键,开启中间的led,再按下一次按键,关闭中间的led,以此类推。每次按下按键都会打印press!,松开按键会打印release!。如图3-1-1所示。