25 鸿蒙LiteOS GPIO轮询模式实战教程:电平读取与上升沿检测

鸿蒙LiteOS GPIO轮询模式实战教程:电平读取与上升沿检测

B站 配套视频【鸿蒙 LiteOS 实战 11】GPIO轮询模式实战教程

一、前言

在鸿蒙LiteOS嵌入式开发中,GPIO分为轮询模式中断模式 两种常用开发方式。

对于入门学习、低速按键检测、普通电平状态采集这类简单场景,GPIO轮询模式逻辑简单、上手无门槛、无需理解中断复杂机制,是新手必学的基础用法。

本文基于RK2206开发板+OpenHarmony LiteOS,手把手讲解GPIO轮询原理、完整源码、电平检测、上升沿识别,代码可直接编译烧录使用,适合嵌入式鸿蒙零基础入门学习。

二、什么是GPIO

GPIO 全称 General Purpose Input Output,即通用输入输出口,可以理解为单片机对外的引脚接口:

  • 配置为输入模式:读取外部高低电平,常用于按键、传感器信号采集;
  • 配置为输出模式:输出高低电平,常用于控制LED、继电器、蜂鸣器。

本文只讲解GPIO输入轮询模式,重点实现引脚电平循环读取与上升沿事件检测。

三、什么是GPIO轮询模式

轮询模式核心逻辑:

在任务死循环中,周期性不断读取GPIO引脚电平,通过前后电平对比,判断电平变化、识别上升沿/下降沿。

优点:

  • 逻辑简单,无需掌握中断机制;
  • 配置流程少,代码通俗易懂;
  • 适合低速、低实时性的普通场景。

缺点:

  • 需要任务持续循环运行,占用CPU资源;
  • 轮询间隔设置不合理时,容易漏掉快速电平跳变;
  • 不适合高频信号、高精度按键检测场景。

四、基础概念:上升沿与下降沿

  • 低电平:逻辑0,近似0V;
  • 高电平:逻辑1,近似3.3V。
  1. 上升沿:低电平0 → 高电平1 的瞬间跳变,对应按键按下、传感器信号生效;
  2. 下降沿:高电平1 → 低电平0 的瞬间跳变,对应按键松开、传感器信号失效。

轮询模式通过记录上一次电平 + 对比当前电平,即可软件模拟检测边沿跳变。

五、完整实战源码(GPIO轮询+上升沿检测)

c 复制代码
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <math.h>
#include "los_task.h"
#include "ohos_init.h"
#include "lz_hardware.h"

#define GPIO_TEST       GPIO0_PC5

/* 轮询上升沿触发计数 */
static unsigned int m_gpio_poll_count = 0;
/* 记录上一次引脚电平 */
static unsigned int last_level = 0;

/***************************************************************
* 函数名称: gpio_process
* 说    明: gpio轮询任务:循环读取电平、检测上升沿
* 参    数: 无
* 返 回 值: 无
***************************************************************/
void gpio_process()
{
    LzGpioValue cur_level;

    /* 初始化引脚为GPIO */
    LzGpioInit(GPIO_TEST);
    /* 引脚复用配置为GPIO功能 */
    PinctrlSet(GPIO_TEST, MUX_FUNC0, PULL_KEEP, DRIVE_LEVEL0);
    /* 引脚配置为输入模式 */
    LzGpioSetDir(GPIO_TEST, LZGPIO_DIR_IN);

    while (1)
    {
        printf("***************GPIO Polling Example*************\n");

        // 读取当前GPIO引脚电平
        LzGpioGetVal(GPIO_TEST, &cur_level);
        printf("gpio current level = %d\n", cur_level);

        // 软件检测上升沿:上一次低电平,当前高电平
        if (last_level == 0 && cur_level == 1)
        {
            m_gpio_poll_count++;
            printf("检测到上升沿事件,累计次数:%d\n", m_gpio_poll_count);
        }

        // 更新历史电平,用于下一次对比
        last_level = cur_level;
        printf("\n");

        // 轮询间隔200ms,降低CPU占用
        usleep(200000);
    }
}

/***************************************************************
* 函数名称: gpio_pool_example
* 说    明: 开机自启动创建GPIO轮询任务
* 参    数: 无
* 返 回 值: 无
***************************************************************/
void gpio_pool_example()
{
    unsigned int thread_id;
    TSK_INIT_PARAM_S task = {0};
    unsigned int ret = LOS_OK;

    task.pfnTaskEntry = (TSK_ENTRY_FUNC)gpio_process;
    task.uwStackSize = 2048;
    task.pcName = "gpio process";
    task.usTaskPrio = 24;
    ret = LOS_TaskCreate(&thread_id, &task);
    if (ret != LOS_OK)
    {
        printf("Falied to create task ret:0x%x\n", ret);
        return;
    }
}

APP_FEATURE_INIT(gpio_pool_example);

六、代码逻辑解析

1. GPIO初始化流程

  1. LzGpioInit:初始化指定GPIO引脚硬件时钟与基础配置;
  2. PinctrlSet:配置引脚复用功能为普通GPIO,设置上下拉、驱动能力;
  3. LzGpioSetDir:将引脚设置为输入模式,用于读取外部电平。

2. 轮询检测逻辑

  1. 在while(1)死循环中,周期性调用 LzGpioGetVal 读取引脚当前电平;
  2. 用变量 last_level 保存上一次循环的电平状态;
  3. 通过 last_level == 0 && cur_level == 1 软件判断上升沿跳变;
  4. 检测到上升沿后计数累加并打印提示;
  5. 加入 usleep(200000) 设置200ms轮询间隔,避免CPU空转占用资源。

七、串口运行打印效果

当外部引脚电平从低变高时,会自动识别上升沿并累加计数。

八、轮询模式适用场景与局限

适用场景

  • 新手入门学习GPIO基础配置;
  • 低速按键状态检测;
  • 普通传感器稳态电平采集;
  • 对实时性要求不高的简单IO检测。

局限性

  • 循环轮询占用CPU资源,不利于低功耗设计;
  • 轮询间隔过大时,会丢失快速的电平跳变;
  • 无法做到硬件级实时响应,高精度按键、高频信号不推荐使用。

九、总结

  1. GPIO轮询模式通过循环读取电平+软件对比,即可实现电平状态与上升沿检测;
  2. 配置流程简单、无中断复杂逻辑,非常适合鸿蒙LiteOS嵌入式新手入门;
  3. 轮询模式仅适合低速低实时性场景,高精度、高实时性需求建议使用GPIO中断模式;
  4. 本文源码可直接在RK2206开发板上编译运行,可自行修改引脚、轮询间隔适配项目需求。
相关推荐
秋越1 小时前
从工程角度理解嵌入式C语言关键字
c语言·开发语言·嵌入式·嵌入式软件开发·嵌入式c语言·c语言关键字
G_dou_1 小时前
Flutter+OpenHarmony实战:flashlight】手电筒项目
flutter·harmonyos
爱吃大芒果1 小时前
鸿蒙 ArkUI 架构蓝图:MoodLite 的 UI 渲染与数据逻辑解耦实践
ui·架构·harmonyos
nashane2 小时前
HarmonyOS 6学习:深入解析CustomDialog嵌套弹窗中的this指向陷阱与解决方案
学习·华为·harmonyos
痕忆丶2 小时前
openharmony北向开发基础之应用访问公共目录
harmonyos
ShallowLin2 小时前
【HarmonyOS闯关习题】——HarmonyOS介绍
华为·harmonyos
bbaydnog2 小时前
STM32调试三板斧:printf重定向、HardFault定位、逻辑分析仪抓波形,从此告别瞎改代码
stm32·嵌入式·调试
爱吃大芒果2 小时前
声明式 UI 进阶剖析:复杂长列表懒加载与视图模型 (ViewModel) 的内存优化策略
ui·华为·harmonyos
坚果的博客2 小时前
Flutter 开发鸿蒙 6 应用,祝贺六一儿童节 [特殊字符]
flutter·华为·harmonyos