Skip to content

GPIO/PIN

GPIO/PIN简介

芯片上的引脚一般分为 4 类:电源、时钟、控制与 I/O,I/O 口在使用模式上又分为 General Purpose Input Output(通用输入 / 输出),简称 GPIO。

GPIO控制器可以驱动或者获取信号/数据,定义I/O的功能、方向、状态以及中断,也称为PIN。

访问GPIO设备

访问GPIO设备,库中提供了以下接口:

函数 描述
rt_pin_mode() 设置GPIO工作模式
rt_pin_write() 设置GPIO输出高低电平
rt_pin_read() 读取GPIO电平
rt_pin_attach_irq() 绑定GPIO中断回调函数
rt_pin_irq_enable() 使能GPIO中断
rt_pin_detach_irq() 解绑GPIO中断回调函数

设置GPIO工作模式

设置指定的GPIO的工作模式,函数原型如下所示:

void rt_pin_mode(rt_base_t pin, rt_base_t mode);
  • 参数

    [IN]pin:GPIO引脚编号,AP板子支持的GPIO有五个,对应如下表所示:

    枚举定义 枚举值 引脚名称 连接LED灯
    GPIO_PIN_3 3 GPIO_3
    GPIO_PIN_4 4 GPIO_4
    GPIO_PIN_5 5 GPIO_5 D12
    GPIO_PIN_6 6 GPIO_6 D15
    GPIO_PIN_7 7 GPIO_7 D14
    GPIO_PIN_28 28 GPIO_28 D13

    [IN]mode:GPIO引脚工作模式,目前支持的引脚工作模式可取如所示的 5 种宏定义值之一:

    // 头文件相对路径:rt-thread/components/drivers/include/drivers/pin.h
    #define PIN_MODE_OUTPUT         0x00    // 输出 
    #define PIN_MODE_INPUT          0x01    // 输入 
    #define PIN_MODE_INPUT_PULLUP   0x02    // 上拉输入 
    #define PIN_MODE_INPUT_PULLDOWN 0x03    // 下拉输入 
    #define PIN_MODE_OUTPUT_OD      0x04    // 开漏输出 
    
  • 返回值

    无。

设置GPIO输出电平

设置指定GPIO引脚输出电平,函数原型如下所示:

void rt_pin_write(rt_base_t pin, rt_base_t value);
  • 参数

    [IN]pin:GPIO引脚编号,AP板子支持的GPIO有 5 个,请查看设置GPIO工作模式中的表格描述。

    [IN]value:电平逻辑值,可取如下2 种宏定义值之一:

    // 头文件相对路径:rt-thread/components/drivers/include/drivers/pin.h
    #define PIN_LOW     0x00    // 低电平
    #define PIN_HIGH    0x01    // 高电平
    
  • 返回值

读取GPIO电平

读取指定GPIO引脚输入电平,函数原型如下所示:

int rt_pin_read(rt_base_t pin);

绑定引脚中断回调函数

若要使用到GPIO引脚的中断功能,可以使用如下函数将某个引脚配置为某种中断触发模式并绑定一个中断回调函数到对应引脚,当引脚中断发生时,就会执行回调函数,函数原型如下所示:

rt_err_t rt_pin_attach_irq(rt_int32_t pin, 
                           rt_uint32_t mode, 
                           void (*hdr)(void* args), 
                           void* args);
  • 参数

    [IN]pin:GPIO引脚编号,AP板子支持的GPIO有五个,请查看设置GPIO工作模式中的表格描述。

    [IN]mode:中断触发模式,共定义了如下 5 种宏定义值:

    // 头文件相对路径:rt-thread/components/drivers/include/drivers/pin.h
    #define PIN_IRQ_MODE_RISING         0x00    // 上升沿触发
    #define PIN_IRQ_MODE_FALLING        0x01    // 下降沿触发
    #define PIN_IRQ_MODE_RISING_FALLING 0x02    // 边沿触发(上升沿和下降沿都触发)
    #define PIN_IRQ_MODE_HIGH_LEVEL     0x03    // 高电平触发
    #define PIN_IRQ_MODE_LOW_LEVEL      0x04    // 低电平触发
    

    [IN]hdr:中断回调函数,用户需要自行定义这个函数

    [INOUT]args:中断回调函数的参数,不需要时设置为 RT_NULL

  • 返回值

    0:成功。

    其他:错误,RT-Thread定义的错误类型。

使能GPIO脚中断

绑定好引脚中断回调函数后使用下面的函数使能引脚中断,函数原型如下所示:

rt_err_t rt_pin_irq_enable(rt_base_t pin, rt_uint32_t enable);
  • 参数

    [IN]pin:GPIO引脚编号,AP板子支持的GPIO有五个,请查看设置GPIO工作模式中的表格描述。

    [IN]enable:状态,可取以下 2 种值之一:

    #define PIN_IRQ_DISABLE     0x00    // 关闭
    #define PIN_IRQ_ENABLE      0x01    // 开启
    
  • 返回值

    0:成功。

    其他:错误,RT-Thread定义的错误类型。

解绑GPIO中断回调函数

可以使用如下函数解绑GPIO引脚中断回调函数:

rt_err_t rt_pin_detach_irq(rt_int32_t pin);
  • 参数

    [IN]pin:GPIO引脚编号,AP板子支持的GPIO有五个,请查看设置GPIO工作模式中的表格描述。

  • 返回值

    0:成功。

    其他:错误,RT-Thread定义的错误类型。

注:引脚解绑了中断回调函数后,中断并没有关闭,还可以调用绑定引脚中断回调函数再次绑定其他回调函数。

GPIO使用示例

使用示例需要配置menuconfig打开配置(默认关闭),路径如下:

wiota APP -> open pin, default close(_PIN_APP_)

以下提供GPIO测试实例,测试步骤如下:

  1. 设置GPIO输出模式。

  2. 输入模式下设置中断触发方式。

  3. 开启中断。

#include <rtthread.h>
#ifdef _GPIO_APP_
#include <rtdevice.h>
#include "uc_pin_app.h"

#define LED1_GPIO_NUM            5
#define LED2_GPIO_NUM            28
#define IRQ1_GPIO_NUM            3
#define IRQ2_GPIO_NUM            4

static void led2_on(void *args)
{
    rt_pin_write(LED2_GPIO_NUM, PIN_HIGH);
}

static void led2_off(void *args)
{
    rt_pin_write(LED2_GPIO_NUM, PIN_LOW);
}

int pin_app_init(void)
{
    rt_err_t ret = RT_EOK;
    rt_pin_mode(LED1_GPIO_NUM, PIN_MODE_OUTPUT);
    rt_pin_mode(LED2_GPIO_NUM, PIN_MODE_OUTPUT);

    rt_pin_write(LED1_GPIO_NUM, PIN_LOW);
    rt_pin_write(LED2_GPIO_NUM, PIN_LOW);

    rt_pin_mode(IRQ1_GPIO_NUM, PIN_MODE_INPUT_PULLDOWN);
    rt_pin_attach_irq(IRQ1_GPIO_NUM, PIN_IRQ_MODE_RISING, led2_on, RT_NULL);

    rt_pin_mode(IRQ2_GPIO_NUM, PIN_MODE_INPUT_PULLDOWN);
    rt_pin_attach_irq(IRQ2_GPIO_NUM, PIN_IRQ_MODE_RISING, led2_off, RT_NULL);

    return ret;
}

void pin_app_sample(void)
{
    rt_err_t ret = RT_EOK;

    rt_kprintf("pin test demo.\r\n");

    ret = pin_app_init();
    if(ret != RT_EOK)
    {
        printf("pin test error.\r\n");
    }

    rt_pin_write(LED1_GPIO_NUM, PIN_HIGH);
    rt_pin_write(LED2_GPIO_NUM, PIN_LOW);

    rt_pin_irq_enable(IRQ1_GPIO_NUM, PIN_IRQ_ENABLE);
    rt_pin_irq_enable(IRQ2_GPIO_NUM, PIN_IRQ_ENABLE);
}

#endif
Back to top