RT-Thread Pin设备驱动API应用介绍

概要

本文主要涉及Pin驱动相关的API接口的简要介绍及使用示例,有兴趣深入了解Pin驱动程序框架可参考:RT-Thread pin设备驱动代码结构剖析

PIN设备的操作方法

应用程序通过RT-Thred提供的pin设备管理接口来操作GPIO,函数接口如下表:

方法名称方法描述
rt_pin_mode()设置引脚模式
rt_pin_write()设置引脚电平
rt_pin_read()读取引脚电平
rt_pin_attach_irq()绑定引脚中断回调函数
rt_pin_detach_irq()脱离引脚中断回调函数
rt_pin_irq_enable()使能引脚中断

1. 设置引脚模式

在使用引脚之前需要先设定引脚的工作模式,通过下面函数完成:

void rt_pin_mode(rt_base_t pin, rt_base_t mode);

参数描述
pin引脚编号
mode引脚工作模式
返回描述

1.1 参数 pin

RT-Thread 提供的引脚编号需要和芯片的引脚号区分开来,它们并不是同一个概念,引脚编号由 PIN 设备驱动程序定义,和具体的芯片相关。有2种方式可以获取引脚编号:使用宏定义或者查看PIN 驱动文件。

如果使用 rt-thread/bsp/stm32 目录下的 BSP 则可以使用下面的宏获取引脚编号:

GET_PIN(port, pin)

获取引脚号为 PF9 的 LED0 对应的引脚编号的示例代码如下所示:

#define LED0_PIN GET_PIN(F, 9)

如果使用其他 BSP 则需要查看 PIN 驱动代码 drv_gpio.c 文件确认引脚编号。此文件里有一个数组存放了每个 PIN 脚对应的编号信息,如下所示:

static const rt_uint16_t pins[] =
{
    __STM32_PIN_DEFAULT,
    __STM32_PIN_DEFAULT,
    __STM32_PIN(2, A, 15),
    __STM32_PIN(3, B, 5),
    __STM32_PIN(4, B, 8),
    __STM32_PIN_DEFAULT,
    __STM32_PIN_DEFAULT,
    __STM32_PIN_DEFAULT,
    __STM32_PIN(8, A, 14),
    __STM32_PIN(9, B, 6),
    ... ...    
}

以__STM32_PIN(2, A, 15)为例,2 为 RT-Thread 使用的引脚编号,A 为端口号,15 为引脚号,所以 PA15 对应的引脚编号为 2。

1.2 参数 mode

RT-Thread目前支持的模式有下面5种:

#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    /*开漏输出*/

1.3 示例

使用示例如下所示:

#define BEEP_PIN_NUM            GET_PIN(B, 0)  /* PB0 */

/* 蜂鸣器引脚为输出模式 */
rt_pin_mode(BEEP_PIN_NUM, PIN_MODE_OUTPUT);

2. 设置引脚电平

设置引脚输出电平的函数如下所示:

void rt_pin_write(rt_base_t pin, rt_base_t value);

参数描述
pin引脚编号
value电平逻辑值,可取 2 种宏定义值之一:PIN_LOW 低电平,PIN_HIGH 高电平

使用示例如下所示:

#define BEEP_PIN_NUM            35  /* PB0 */

/* 蜂鸣器引脚为输出模式 */
rt_pin_mode(BEEP_PIN_NUM, PIN_MODE_OUTPUT);
/* 设置低电平 */
rt_pin_write(BEEP_PIN_NUM, PIN_LOW);

3. 读取引脚电平

读取引脚电平的函数如下所示:

int rt_pin_read(rt_base_t pin);

参数描述
pin引脚编号
返回——
PIN_LOW低电平
PIN_HIGH高电平

使用示例如下所示:

#define BEEP_PIN_NUM            35  /* PB0 */
int status;

/* 蜂鸣器引脚为输出模式 */
rt_pin_mode(BEEP_PIN_NUM, PIN_MODE_OUTPUT);
/* 设置低电平 */
rt_pin_write(BEEP_PIN_NUM, PIN_LOW);

status = rt_pin_read(BEEP_PIN_NUM);

4. 绑定引脚中断回调函数

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

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

参数描述
pin引脚编号
mode中断触发模式
hdr中断回调函数,用户需要自行定义这个函数
args中断回调函数的参数,不需要时设置为 RT_NULL
返回——
RT_EOK绑定成功
错误码绑定失败

中断触发模式 mode 可取如下 5 种宏定义值之一:

#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      /* 低电平触发 */

使用示例如下所示:

#define KEY0_PIN_NUM            55  /* PD8 */
/* 中断回调函数 */
void beep_on(void *args)
{
    rt_kprintf("turn on beep!\n");

    rt_pin_write(BEEP_PIN_NUM, PIN_HIGH);
}
static void pin_beep_sample(void)
{
    /* 按键0引脚为输入模式 */
    rt_pin_mode(KEY0_PIN_NUM, PIN_MODE_INPUT_PULLUP);
    /* 绑定中断,下降沿模式,回调函数名为beep_on */
    rt_pin_attach_irq(KEY0_PIN_NUM, PIN_IRQ_MODE_FALLING, beep_on, RT_NULL);
}

5. 使能引脚中断

绑定好引脚中断回调函数后使用下面的函数使能引脚中断:

rt_err_t rt_pin_irq_enable(rt_base_t pin, rt_uint32_t enabled);

参数描述
pin引脚编号
enabled状态,可取 2 种值之一:PIN_IRQ_ENABLE(开启),PIN_IRQ_DISABLE(关闭)
返回——
RT_EOK使能成功
错误码使能失败

使用示例如下所示:

#define KEY0_PIN_NUM            55  /* PD8 */
/* 中断回调函数 */
void beep_on(void *args)
{
    rt_kprintf("turn on beep!\n");

    rt_pin_write(BEEP_PIN_NUM, PIN_HIGH);
}
static void pin_beep_sample(void)
{
    /* 按键0引脚为输入模式 */
    rt_pin_mode(KEY0_PIN_NUM, PIN_MODE_INPUT_PULLUP);
    /* 绑定中断,下降沿模式,回调函数名为beep_on */
    rt_pin_attach_irq(KEY0_PIN_NUM, PIN_IRQ_MODE_FALLING, beep_on, RT_NULL);
    /* 使能中断 */
    rt_pin_irq_enable(KEY0_PIN_NUM, PIN_IRQ_ENABLE);
}

6. 脱离引脚中断回调函数

可以使用如下函数脱离引脚中断回调函数:

rt_err_t rt_pin_detach_irq(rt_int32_t pin);

参数描述
pin引脚编号
返回——
RT_EOK脱离成功
错误码脱离失败

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

#define KEY0_PIN_NUM            55  /* PD8 */
/* 中断回调函数 */
void beep_on(void *args)
{
    rt_kprintf("turn on beep!\n");

    rt_pin_write(BEEP_PIN_NUM, PIN_HIGH);
}
static void pin_beep_sample(void)
{
    /* 按键0引脚为输入模式 */
    rt_pin_mode(KEY0_PIN_NUM, PIN_MODE_INPUT_PULLUP);
    /* 绑定中断,下降沿模式,回调函数名为beep_on */
    rt_pin_attach_irq(KEY0_PIN_NUM, PIN_IRQ_MODE_FALLING, beep_on, RT_NULL);
    /* 使能中断 */
    rt_pin_irq_enable(KEY0_PIN_NUM, PIN_IRQ_ENABLE);
    /* 脱离中断回调函数 */
    rt_pin_detach_irq(KEY0_PIN_NUM);
}

注意:脱离中断回调函数后,中断并没有关掉,只是不再执行被脱离的回调函数

PIN 设备使用示例

PIN 设备的具体使用方式可以参考如下示例代码,示例代码的主要步骤如下:

设置蜂鸣器对应引脚为输出模式,并给一个默认的低电平状态。

设置按键 0 和 按键1 对应引脚为输入模式,然后绑定中断回调函数并使能中断。

按下按键 0 蜂鸣器开始响,按下按键 1 蜂鸣器停止响。

/*
 * 程序清单:这是一个 PIN 设备使用例程
 * 例程导出了 pin_beep_sample 命令到控制终端
 * 命令调用格式:pin_beep_sample
 * 程序功能:通过按键控制蜂鸣器对应引脚的电平状态控制蜂鸣器
*/

#include <rtthread.h>
#include <rtdevice.h>

/* 引脚编号,通过查看设备驱动文件drv_gpio.c确定 */
#ifndef BEEP_PIN_NUM
    #define BEEP_PIN_NUM            35  /* PB0 */
#endif
#ifndef KEY0_PIN_NUM
    #define KEY0_PIN_NUM            55  /* PD8 */
#endif
#ifndef KEY1_PIN_NUM
    #define KEY1_PIN_NUM            56  /* PD9 */
#endif

void beep_on(void *args)
{
    rt_kprintf("turn on beep!\n");

    rt_pin_write(BEEP_PIN_NUM, PIN_HIGH);
}

void beep_off(void *args)
{
    rt_kprintf("turn off beep!\n");

    rt_pin_write(BEEP_PIN_NUM, PIN_LOW);
}

static void pin_beep_sample(void)
{
    /* 蜂鸣器引脚为输出模式 */
    rt_pin_mode(BEEP_PIN_NUM, PIN_MODE_OUTPUT);
    /* 默认低电平 */
    rt_pin_write(BEEP_PIN_NUM, PIN_LOW);

    /* 按键0引脚为输入模式 */
    rt_pin_mode(KEY0_PIN_NUM, PIN_MODE_INPUT_PULLUP);
    /* 绑定中断,下降沿模式,回调函数名为beep_on */
    rt_pin_attach_irq(KEY0_PIN_NUM, PIN_IRQ_MODE_FALLING, beep_on, RT_NULL);
    /* 使能中断 */
    rt_pin_irq_enable(KEY0_PIN_NUM, PIN_IRQ_ENABLE);

    /* 按键1引脚为输入模式 */
    rt_pin_mode(KEY1_PIN_NUM, PIN_MODE_INPUT_PULLUP);
    /* 绑定中断,下降沿模式,回调函数名为beep_off */
    rt_pin_attach_irq(KEY1_PIN_NUM, PIN_IRQ_MODE_FALLING, beep_off, RT_NULL);
    /* 使能中断 */
    rt_pin_irq_enable(KEY1_PIN_NUM, PIN_IRQ_ENABLE);
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(pin_beep_sample, pin beep sample);
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
rt-thread是一个实时嵌入式操作系统,它提供了设备驱动开发的指南,帮助开发者更好地编写设备驱动程序。 首先,在rt-thread中进行设备驱动开发之前,需要了解rt-thread设备驱动框架,包括设备驱动的结构、设备驱动的注册和使用方法等。同时,开发者也需要了解rt-thread设备模型,包括设备设备驱动设备节点的概念,以便更好地理解设备驱动的开发流程。 其次,在编写设备驱动程序时,需要遵循rt-thread设备驱动编程规范,包括设备驱动的命名规范、接口函数的实现规范等。同时,还需要了解不同类型设备的特点和使用方法,以便更好地编写对应的设备驱动程序。 另外,rt-thread提供了丰富的设备驱动接口和函数,开发者可以根据需求选择合适的接口和函数进行设备驱动的开发。在编写设备驱动程序时,还需要注意设备驱动的稳定性和可靠性,及时处理错误和异常情况,以提高设备驱动程序的质量和可靠性。 最后,在设备驱动程序开发完成后,还需要进行设备驱动的测试和调试工作,确保设备驱动程序能够正常工作并符合需求。同时,还需要关注设备驱动程序的性能和优化工作,以提高设备驱动程序的效率和性能。 总之,rt-thread设备驱动开发指南提供了设备驱动开发的规范和方法,帮助开发者更好地编写设备驱动程序,并最终实现嵌入式系统的稳定和可靠运行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吾爱技术圈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值