目录
概述
本文介绍Renesa Version Board开发之RT-Thread 下IO驱动开发的详细方法,比这边介绍了RT-Thread的Pin接口函数,还使用FSP配置Version Board上RGB类型LED的IO,并实现其驱动程序,然后在mesh终端,通过命令测试该驱动程序的功能。
1 硬件接口介绍
Renesa Version Board板卡上有3个LED,该LED支持3个RGB模式的显示,其电路如下:
其对应的IO接口如下:
2 RT-Thread的Pin接口
2.1 PIN接口介绍
芯片上的引脚一般分为 4 类:电源、时钟、控制与 I/O,I/O 口在使用模式上又分为 General Purpose Input Output(通用输入 / 输出),简称 GPIO,与功能复用 I/O(如 SPI/I2C/UART 等)。
大多数MCU 的引脚支持复用功能。不同引脚内部结构不一样,拥有的功能也不一样。可以通过不同的配置,切换引脚的实际功能。
通用 I/O 口主要特性如下:
- 可编程控制中断:中断触发模式可配置,一般有下图所示 5 种中断触发模式:
输入输出模式可控制。
输出模式一般包括:推挽、开漏、上拉、下拉。引脚为输出模式时,可以通过配置引脚输出的电平状态为高电平或低电平来控制连接的外围设备。
输入模式一般包括:浮空、上拉、下拉、模拟。引脚为输入模式时,可以读取引脚的电平状态,即高电平或低电平。
2.2 访问PIN接口
应用程序通过 RT-Thread 提供的 PIN 设备管理接口来访问 GPIO,相关接口如下所示:
函数 | 描述 |
---|---|
rt_pin_get() | 获取引脚编号 |
rt_pin_mode() | 设置引脚模式 |
rt_pin_write() | 设置引脚电平 |
rt_pin_read() | 读取引脚电平 |
rt_pin_attach_irq() | 绑定引脚中断回调函数 |
rt_pin_irq_enable() | 使能引脚中断 |
rt_pin_detach_irq() | 脱离引脚中断回调函数 |
2.2.1 设置引脚模式
引脚在使用前需要先设置好输入或者输出模式,通过如下函数完成:
void rt_pin_mode(rt_base_t pin, rt_base_t mode);
参数 | 描述 |
---|---|
pin | 引脚编号 |
mode | 引脚工作模式 |
目前 RT-Thread 支持的引脚工作模式可取如所示的 5 种宏定义值之一,每种模式对应的芯片实际支持的模式需参考 PIN 设备驱动程序的具体实现:
#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 /* 开漏输出 */
2.2.2 设置引脚电平
设置引脚输出电平的函数如下所示:
void rt_pin_write(rt_base_t pin, rt_base_t value);
参数 | 描述 |
---|---|
pin | 引脚编号 |
value | 电平逻辑值,可取 2 种宏定义值之一:PIN_LOW 低电平,PIN_HIGH 高电平 |
2.2.3 读取引脚电平
读取引脚电平的函数如下所示:
int rt_pin_read(rt_base_t pin);
参数 | 描述 |
---|---|
pin | 引脚编号 |
返回 | —— |
PIN_LOW | 低电平 |
PIN_HIGH | 高电平 |
2.2.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 | 绑定成功 |
错误码 | 绑定失败 |
2.2.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 | 使能成功 |
错误码 | 使能失败 |
2.2.6 脱离引脚中断回调函数
可以使用如下函数脱离引脚中断回调函数:
rt_err_t rt_pin_detach_irq(rt_int32_t pin);
参数 | 描述 |
---|---|
pin | 引脚编号 |
返回 | —— |
RT_EOK | 脱离成功 |
错误码 | 脱离失败 |
引脚脱离了中断回调函数以后,中断并没有关闭,还可以调用绑定中断回调函数再次绑定其他回调函数。
3 软件功能实现
3.1 FSP配置参数
1)配置参数:LED0
2) 配置LED1接口
3) 配置LED2接口
3.2 使用FSP生成项目
在bsp_pin_cfg.h中查看配置的参数
4 RT-Thread下的驱动程序实现
4.1 代码实现
实现功能:
在mesh终端,通过输入相关的命令,就能控制LED的状态,命令如下:
Usage: you can slect led0,led1 or led2
userled led0 0: off led
userled led0 1: on led
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2024-07-28 mingfei.tang the first version
*/
#include <rtthread.h>
#include <rtdevice.h>
#include "hal_data.h"
void userled(int argc, char *argv[])
{
if (argc > 1)
{
if (!strcmp(argv[1], "led0"))
{
if (!strcmp(argv[2], "0"))
{
rt_pin_write(ULED0, PIN_HIGH);
}
else {
rt_pin_write(ULED0, PIN_LOW);
}
}
else if (!strcmp(argv[1], "led1"))
{
if (!strcmp(argv[2], "0"))
{
rt_pin_write(ULED1, PIN_HIGH);
}
else {
rt_pin_write(ULED1, PIN_LOW);
}
}
else if (!strcmp(argv[1], "led2"))
{
if (!strcmp(argv[2], "0"))
{
rt_pin_write(ULED2, PIN_HIGH);
}
else {
rt_pin_write(ULED2, PIN_LOW);
}
}
else
{
rt_kprintf("Unknown command. Please enter 'led' for help\n");
}
}
else
{
rt_kprintf("Usage: you can slect led0,led1 or led2 \n");
rt_kprintf("example: \n");
rt_kprintf("userled led0 0: off led \n");
rt_kprintf("userled led0 1: on led \n");
}
}
MSH_CMD_EXPORT(userled, led driver function);
4.2 功能测试
1)编译和下载代码至板卡中
下载完成后,终端上显示如下信息
2) 通过命令控制LED的状态
板卡上LED0的状态
控制LED1的状态:
板卡上的状态:
控制LED2的状态
板卡上LED2的状态