3. GPIO输入检测按键状态
任务说明
本案例在鸿蒙南向设备(以Hi3861为例)上完成GPIO输入功能:将GPIO05配置为输入模式,连接外部按键(按下接地,松开接高电平),循环读取引脚电平状态,并通过串口打印按键当前状态。核心目标是验证GPIO输入模式的配置流程与电平读取API的正确使用。
硬件连接
代码实现
在Hi3861 SDK的app/demo目录下创建gpio_key_demo.c,代码如下:
#include <stdio.h>
#include <unistd.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_gpio.h"
#include "iot_gpio_ex.h"
#define KEY_GPIO 5 // GPIO05
#define TASK_STACK_SIZE 4096
#define TASK_PRIORITY 25
static void *KeyTask(const char *arg)
{
(void)arg;
uint32_t lastState = 1; // 上一次状态,默认松开(高电平)
while (1) {
// 读取按键电平:按下为0(低电平),松开为1(高电平)
uint32_t level = 0;
IoTGpioGetInputVal(KEY_GPIO, &level);
// 检测状态变化(下降沿:从松开到按下)
if (level == 0 && lastState == 1) {
printf("Key Pressed!\n");
}
lastState = level;
usleep(20000); // 20ms轮询,消除抖动
}
return NULL;
}
static void GpioKeyDemoInit(void)
{
// 初始化GPIO05为输入模式
IoTGpioInit(KEY_GPIO);
// 配置GPIO05为输入,且内部上拉(确保松开时为高电平)
IoTGpioSetDir(KEY_GPIO, IOT_GPIO_DIR_IN);
IoSetPull(KEY_GPIO, IOT_IO_PULL_UP);
// 创建按键检测任务
osThreadAttr_t attr = {0};
attr.name = "KeyTask";
attr.stack_size = TASK_STACK_SIZE;
attr.priority = TASK_PRIORITY;
if (osThreadNew(KeyTask, NULL, &attr) == NULL) {
printf("Failed to create key task\n");
}
}
SYS_RUN(GpioKeyDemoInit);
代码说明
IoTGpioInit(5):初始化GPIO05外设时钟与寄存器。IoTGpioSetDir(KEY_GPIO, IOT_GPIO_DIR_IN):将GPIO05设置为输入方向。IoSetPull(KEY_GPIO, IOT_IO_PULL_UP):使能内部上拉电阻,确保按键松开时引脚读到高电平(1),按下接地时读到低电平(0)。IoTGpioGetInputVal():读取引脚当前电平值,存入level变量。- 任务中每20ms轮询一次,检测到电平从1跳变为0时打印
Key Pressed!,实现边沿触发效果。
编译与烧录
- 将
gpio_key_demo.c放入app/demo目录,并在app/BUILD.gn中添加该源文件引用。 - 在SDK根目录执行
python build.py wifiiot进行编译。 - 使用HiSuite或DevEco工具将生成的
Hi3861_wifiiot_app_allinone.bin烧录至开发板。
验证方法
- 开发板上电后,打开串口终端(波特率115200),观察启动日志。
- 用手按下按键(GPIO05对地短接),串口应打印
Key Pressed!。 - 松开按键,再次按下,每次按下都应打印一次该信息。
判定标准:每次按下按键,串口输出一行Key Pressed!,且松开时无输出,即表示GPIO输入模式配置正确、电平读取与按键检测逻辑工作正常。