之前的点亮小灯实验用到了GPIO的输出模式,但是对于输入模式没有用到,这次小R给小伙伴们介绍GPIO的其中一种输入模式——上拉输入。按键出现在很多的应用场景,按键处理更是一门学问。因此,小R给小伙伴们介绍GPIO的上拉输入模式并简单应用于按键实验中,通过判断按键的状态来控制LED灯的亮灭情况。
首先,需要了解的是:当IO做输入使用时,通过调用函数GPIO_ReadInputDataBit()来读取IO口的电平状态。其次,按键是需要消抖滴。最后,既然是按键实验,就会有按键电路。按键电路如下:
电路很简单,将按键接在I/O和GND两端,
I/O配置时设置成内部的上拉输入,
这样按下按键接通GND,输入低电平;
也可以将按键接在I/O和VCC两端,
I/O配置时设置成内部的下拉输入,
按下按键I/O接通VCC,输入高电平。
#设计时一般接GND#
设计思路:采用轮询方式扫描I/O口电平状态,若按键被按下,I/O口为低电平,则LED亮,否则LED不亮。
1. 新建两个文件,key.c 和 key.h
2. 在头文件 key.h 添加下面代码:
#ifndef _KEY_H
#define _KEY_H
#include "stm32f10x.h"
#define KEY0 GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_12)
void key_init(void);
#endif;
3. 把 key.c 添加到工程中
4. 在 key.c 中添加以下代码:
#include "key.h"
void key_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //定义GPIO结构体
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能GPIOA时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; //配置引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIOA
}
5. 实现按键轮询控制LED灯亮灭
#include "stm32f10x.h"
#include "delay.h"
#include "led.h"
#include "tim.h"
#include "key.h"
int mian(void)
{
delay_init();
led_init();
key_init();
while(1)
{
if(KEY0 == 0) {
delay_ms(20); //按键消抖,时间一般为10-20ms
if(KEY0 == 0) LED_ON;
}
else LED_OFF;
}
}
库函数相关代码:
/**
* @brief Reads the specified input port pin.
* @param GPIOx: where x can be (A..G) to select the GPIO peripheral.
* @param GPIO_Pin: specifies the port bit to read.
* This parameter can be GPIO_Pin_x where x can be (0..15).
* @retval The input port pin value.
*/
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
uint8_t bitstatus = 0x00;
/* Check the parameters */
assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
assert_param(IS_GET_GPIO_PIN(GPIO_Pin));
if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)Bit_RESET)
{
bitstatus = (uint8_t)Bit_SET;
}
else
{
bitstatus = (uint8_t)Bit_RESET;
}
return bitstatus;
}
手机可以左右滑查看代码
stm32f10x_gpio.c中可以找到上述代码,实际上就是读取GPIOx_IDR寄存器。
小提示:如果身边没有按键面包板搭电路,可以使用一条杜邦线完成实验,杜邦线的一端接PA12,当另一端接GND时代表“按键”被按下。
欢迎关注微信公众号『OpenSSR』