GPIO使用指导

    图 1 GPIO使用流程图

    不同SOC芯片由于其GPIO控制器型号、参数、以及控制器驱动的不同,GPIO管脚号的换算方式不一样。

    • Hi3516DV300

      控制器管理12组GPIO管脚,每组8个。

      GPIO号 = GPIO组索引 (0~11) * 每组GPIO管脚数(8) + 组内偏移

      举例:GPIO10_3的GPIO号 = 10 * 8 + 3 = 83

    • Hi3518EV300

      控制器管理10组GPIO管脚,每组10个。

      GPIO号 = GPIO组索引 (0~9) * 每组GPIO管脚数(10) + 组内偏移

      举例:GPIO7_3的GPIO管脚号 = 7 * 10 + 3 = 73

    • 设置GPIO管脚方向

      在进行GPIO管脚读写前,需要先通过如下函数设置GPIO管脚方向:

      int32_t GpioSetDir(uint16_t gpio, uint16_t dir);

      表 1 GpioSetDir参数和返回值描述

    • 读写GPIO管脚

      如果要读取一个GPIO管脚电平,通过以下函数完成:

      int32_t GpioRead(uint16_t gpio, uint16_t *val);

      表 2 GpioRead参数和返回值描述

      参数

      参数描述

      gpio

      待读取的GPIO管脚号

      val

      接收读取电平值的指针

      返回值

      返回值描述

      0

      负数

      读取失败

      如果要向GPIO管脚写入电平值,通过以下函数完成:

      int32_t GpioWrite(uint16_t gpio, uint16_t val);

      表 3 GpioWrite参数和返回值描述

      示例代码:

    • 设置GPIO中断

      如果要为一个GPIO管脚设置中断响程序,使用如下函数:

      int32_t GpioSetIrq(uint16_t gpio, uint16_t mode, GpioIrqFunc func, void *arg);

      表 4 GpioSetIrq参数和返回值描述

      参数

      参数描述

      gpio

      GPIO管脚号

      mode

      中断触发模式

      func

      中断服务程序

      arg

      传递给中断服务程序的入参

      返回值

      返回值描述

      0

      设置成功

      负数

      设置失败

      int32_t GpioUnSetIrq(uint16_t gpio);

      表 5 GpioUnSetIrq参数和返回值描述

      在中断服务程序设置完成后,还需要先通过如下函数使能GPIO管脚的中断:

      int32_t GpioEnableIrq(uint16_t gpio);

      表 6 GpioEnableIrq参数和返回值描述

      参数

      参数描述

      gpio

      GPIO管脚号

      返回值

      返回值描述

      0

      使能成功

      负数

      使能失败

      GPIO使用指导 - 图1 注意: 必须通过此函数使能管脚中断,之前设置的中断服务函数才能被正确响应。

      如果要临时屏蔽此中断,可以通过如下函数禁止GPIO管脚中断:

      int32_t GpioDisableIrq(uint16_t gpio);

      表 7 GpioDisableIrq参数和返回值描述

      示例代码:

      1. */
      2. int32_t MyCallBackFunc(uint16_t gpio, void *data)
      3. {
      4. HDF_LOGI("%s: gpio:%u interrupt service in! data=%p\n", __func__, gpio, data);
      5. return 0;
      6. int32_t ret;
      7. /* 设置中断服务程序为MyCallBackFunc,入参为NULL,中断触发模式为上升沿触发 */
      8. ret = GpioSetIrq(3, OSAL_IRQF_TRIGGER_RISING, MyCallBackFunc, NULL);
      9. if (ret != 0) {
      10. return;
      11. }
      12. /* 使能3号GPIO管脚中断 */
      13. ret = GpioEnableIrq(3);
      14. if (ret != 0) {
      15. HDF_LOGE("GpioEnableIrq: failed, ret %d\n", ret);
      16. return;
      17. /* 禁止3号GPIO管脚中断 */
      18. if (ret != 0) {
      19. HDF_LOGE("GpioDisableIrq: failed, ret %d\n", ret);
      20. return;
      21. }
      22. /* 取消3号GPIO管脚中断服务程序 */
      23. ret = GpioUnSetIrq(3);
      24. if (ret != 0) {
      25. HDF_LOGE("GpioUnSetIrq: failed, ret %d\n", ret);
      26. return;
      27. }