GPIO
介绍
对于不同底层驱动的gpio操作实现,统一封装成本文所述hal接口。上层使用相关功能时,统一调用hal层接口,以保证app的通用性。 hal相关头文件位于目录:[include/aos/hal] hal相关实现位于具体的mcu目录下,如:[platform/mcu/stm32f1xx/hal/]
API列表
名称 | 描述 |
---|---|
hal_gpio_init | 初始化指定GPIO管脚 |
hal_gpio_output_high | 使指定GPIO输出高电平 |
hal_gpio_output_low | 使指定GPIO输出低电平 |
hal_gpio_output_toggle | 使指定GPIO输出翻转 |
hal_gpio_input_get | 获取指定GPIO管脚的输入值 |
hal_gpio_enable_irq | 使能指定GPIO的中断模式,挂载中断服务函数 |
hal_gpio_disable_irq | 关闭指定GPIO的中断 |
hal_gpio_clear_irq | 清除指定GPIO的中断状态 |
hal_gpio_finalize | 关闭指定GPIO |
API详情
请参考[include/aos/hal/gpio.h]
相关数据结构
gpio_dev_t
typedef struct {
uint8_t port; /* gpio逻辑端口号 */
gpio_config_t config; /* gpio配置信息 */
void *priv; /* 私有数据 */
} gpio_dev_t;
gpio_config_t
typedef enum {
ANALOG_MODE, /* 管脚用作功能引脚,如用于pwm输出,uart的输入引脚 */
IRQ_MODE, /* 中断模式,配置为中断源 */
INPUT_PULL_UP, /* 输入模式,内部包含一个上拉电阻 */
INPUT_PULL_DOWN, /* 输入模式,内部包含一个下拉电阻 */
INPUT_HIGH_IMPEDANCE, /* 输入模式,内部为高阻模式 */
OUTPUT_PUSH_PULL, /* 输出模式,普通模式 */
OUTPUT_OPEN_DRAIN_NO_PULL, /* 输出模式,输出高电平时,内部为高阻状态 */
OUTPUT_OPEN_DRAIN_PULL_up, /* 输出模式,输出高电平时,被内部电阻拉高 */
OUTPUT_OPEN_DRAIN_AF, /* 替换为高电平输出模式 */
OUTPUT_PUSH_PULL_AF, /* 替换为普通输出模式 */
} gpio_config_t;
gpio_irq_trigger_t
typedef enum {
IRQ_TRIGGER_RISING_EDGE = 0x1, /* 上升沿触发 */
IRQ_TRIGGER_FALLING_EDGE = 0x2, /* 下降沿触发 */
IRQ_TRIGGER_BOTH_EDGES = IRQ_TRIGGER_RISING_EDGE | IRQ_TRIGGER_FALLING_EDGE, /* 上升沿下降沿均触发 */
} gpio_irq_trigger_t;
gpio_irq_handler_t
typedef void (*gpio_irq_handler_t)(void *arg);
gpio_pinstate_t
typedef enum {
GPIO_PinState_Reset = 0, /*引脚状态为0 */
GPIO_PinState_Set = !GPIO_PinState_Reset, /*引脚状态为1 */
} gpio_pinstate_t;
hal_gpio_mode_t
typedef enum {
GPIO_INPUT = 0x0000U,
GPIO_OUTPUT_PP = 0x0001U,
GPIO_OUTPUT_OD = 0x0011U,
} hal_gpio_mode_t;
hal_gpio_init
Gpio 初始化
函数原型
int32_t hal_gpio_init(gpio_dev_t *gpio);
参数
参数名称 | 出入参 | 参数描述 | 参数示例 |
---|---|---|---|
gpio_dev_t *gpio | 入参 | GPIO设备描述,定义需要初始化的GPIO管脚的相关特性 | 用户自定义该结构体 |
返回值
类型:int 返回成功或失败, 返回0表示GPIO初始化成功,非0表示失败
调用示例
#define GPIO_LED_IO 18
gpio_dev_t led;
led.port = GPIO_LED_IO;
/* set as output mode */
led.config = OUTPUT_PUSH_PULL;
ret = hal_gpio_init(&led);
hal_gpio_output_high
某gpio输出高电平
函数原型
int32_t hal_gpio_output_high(gpio_dev_t *gpio)
参数
参数名称 | 出入参 | 参数描述 | 参数示例 |
---|---|---|---|
gpio_dev_t *gpio | 入参 | GPIO设备描述 | 使用hal_gpio_init初始化传入值 ,需要预设输出模式 |
返回值
类型:int 返回成功或失败, 返回0表示GPIO输出高电平成功,非0表示失败
调用示例
#define GPIO_IO_OUT 19
gpio_dev_t gpio_out;
gpio_out.port = GPIO_IO_OUT;
/* set as output mode */
gpio_out.config = OUTPUT_PUSH_PULL;
ret = hal_gpio_init(&gpio_out);
ret= hal_gpio_output_high(&gpio_out);
hal_gpio_output_low
某gpio输出低电平
函数原型
int32_t hal_gpio_output_low(gpio_dev_t *gpio)
参数
参数名称 | 出入参 | 参数描述 | 参数示例 |
---|---|---|---|
gpio_dev_t *gpio | 入参 | GPIO设备描述 | 使用hal_gpio_init初始化传入值 ,需要预设输出模式 |
返回值
类型:int 返回成功或失败, 返回0表示GPIO输出低电平成功,非0表示失败
调用示例
// gpio_out初始化同上
ret= hal_gpio_output_low(&gpio_out);
hal_gpio_output_toggle
某gpio输出翻转
函数原型
int32_t hal_gpio_output_toggle(gpio_dev_t* gpio)
参数
参数名称 | 出入参 | 参数描述 | 参数示例 |
---|---|---|---|
gpio_dev_t *gpio | 入参 | GPIO设备描述 | 使用hal_gpio_init初始化传入值 ,需要预设输出模式 |
返回值
类型:int 返回成功或失败, 返回0表示gpio翻转成功,非0表示失败。
调用示例
#define GPIO_IO_OUT 19
gpio_dev_t gpio_out;
gpio_out.port = GPIO_IO_OUT;
/* set as output mode */
gpio_out.config = OUTPUT_PUSH_PULL;
ret = hal_gpio_init(&gpio_out);
ret= hal_gpio_output_toggle(&gpio_out);
hal_gpio_input_get
获取某gpio管脚输入值
函数原型
int32_t hal_gpio_input_get(gpio_dev_t *gpio, uint32_t *value)
参数
参数名称 | 出入参 | 参数描述 | 参数示例 |
---|---|---|---|
gpio_dev_t *gpio | 入参 | GPIO设备描述 | 使用hal_gpio_init初始化传入值 ,需要预设输入模式 |
uint32_t *value | 出参 | 需要获取的管脚值存放地址 | 自定义uint32_t数据结构,传入地址 |
返回值
类型:int 返回成功或失败, 返回0表示gpio输入获取成功,非0表示失败。
调用示例
#define GPIO_IO_OUT 19
uint32_t pinval = 0;
gpio_dev_t gpio_out;
gpio_out.port = GPIO_IO_OUT;
/* set as input mode */
gpio_out.config = INPUT_PULL_UP;
ret = hal_gpio_init(&gpio_out);
ret= hal_gpio_input_get(&gpio_out,&pinval);
hal_gpio_enable_irq
使能指定GPIO的中断模式,挂载中断服务函数,需要预先调用hal_gpio_init,设置IRQ_MODE。
函数原型
int32_t hal_gpio_enable_irq(gpio_dev_t *gpio, gpio_irq_trigger_t trigger,gpio_irq_handler_t handler, void *arg)
参数
参数名称 | 出入参 | 参数描述 | 参数示例 |
---|---|---|---|
gpio_dev_t *gpio | 入参 | GPIO设备描述 | 使用hal_gpio_init初始化传入值 |
gpio_irq_trigger_t | 入参 | 中断的触发模式,上升沿、下降沿还是都触发 | 直接使用gpio_irq_trigger_t枚举 |
gpio_irq_handler_t handler | 入参 | 中断服务函数指针,中断触发后将执行指向的函数 | |
void *arg | 入参 | 中断服务函数的入参 |
返回值
类型:int 返回成功或失败, 返回0使能中断成功,非0表示失败。
调用示例
#define GPIO_IO_INT 19
void gpio_irq_fun(void *arg)
{
}
gpio_dev_t gpio_int;
gpio_int.port = GPIO_IO_INT;
/* set as int mode */
gpio_int.config = IRQ_MODE;
ret = hal_gpio_init(&gpio_int);
/* int triggered int rising edge */
ret= hal_gpio_enable_irq(&gpio_int, IRQ_TRIGGER_RISING_EDGE,gpio_irq_fun,NULL);
hal_gpio_disable_irq
关闭指定GPIO的中断。
函数原型
int32_t hal_gpio_disable_irq(gpio_dev_t *gpio)
参数
参数名称 | 出入参 | 参数描述 | 参数示例 |
---|---|---|---|
gpio_dev_t *gpio | 入参 | GPIO设备描述 | 使用hal_gpio_init初始化传入值 |
返回值
类型:int 返回成功或失败, 返回0表示中断去使能成功,非0表示失败。
调用示例
ret= hal_gpio_disable_irq(&gpio_int);
hal_gpio_clear_irq
清除指定GPIO的中断。
函数原型
int32_t hal_gpio_clear_irq(gpio_dev_t *gpio)
参数
参数名称 | 出入参 | 参数描述 | 参数示例 |
---|---|---|---|
gpio_dev_t *gpio | 入参 | GPIO设备描述 | 使用hal_gpio_init初始化传入值 |
返回值
类型:int 返回成功或失败, 返回0表示清中断成功,非0表示失败。
调用示例
ret= hal_gpio_clear_irq(&gpio_int);
hal_gpio_finalize
关闭指定GPIO,及其中断。
函数原型
int32_t hal_gpio_finalize(gpio_dev_t *gpio)
参数
参数名称 | 出入参 | 参数描述 | 参数示例 |
---|---|---|---|
gpio_dev_t *gpio | 入参 | GPIO设备描述 | 使用hal_gpio_init初始化传入值 |
返回值
类型:int 返回成功或失败, 返回0表示关闭成功,非0表示失败。
调用示例
ret= hal_gpio_finalize(&gpio_int);
使用
添加该组件
在相应的platform/mcu的mk内,添加对应hal文件的编译包含。
包含头文件
#include "aos/hal/gpio.h"
使用示例
GPIO作为输出
#include <aos/hal/gpio.h>
#define GPIO_LED_IO 18
/* define dev */
gpio_dev_t led;
int application_start(int argc, char *argv[])
{
int32_t ret = -1;
/* gpio port config */
led.port = GPIO_LED_IO;
/* set as output mode */
led.config = OUTPUT_PUSH_PULL;
/* configure GPIO with the given settings */
ret = hal_gpio_init(&led);
if (ret != 0) {
printf("gpio init error !\n");
}
/* output high */
hal_gpio_output_high(&led);
/* output low */
hal_gpio_output_low(&led);
/* toggle the LED every 1s */
while(1) {
/* toggle output */
hal_gpio_output_toggle(&led);
/* sleep 1000ms */
aos_msleep(1000);
};
}
注:port为逻辑端口号,其与物理端口号的对应关系见具体的对接实现
GPIO作为中断输入
#include <aos/hal/gpio.h>
#define GPIO_BUTTON_IO 5
/* define dev */
gpio_dev_t button1;
/* pressed flag */
int button1_pressed = 0;
void button1_handler(void *arg)
{
button1_pressed = 1;
}
int application_start(int argc, char *argv[])
{
int32_t ret = -1;
/* input pin config */
button1.port = GPIO_BUTTON_IO;
/* set as interrupt mode */
button1.config = IRQ_MODE;
/* configure GPIO with the given settings */
ret = hal_gpio_init(&button1);
if (ret != 0) {
printf("gpio init error !\n");
}
/* gpio interrupt config */
ret = hal_gpio_enable_irq(&button1, IRQ_TRIGGER_BOTH_EDGES,
button1_handler, NULL);
if (ret != 0) {
printf("gpio irq enable error !\n");
}
/* if button is pressed, print "button 1 is pressed !" */
while(1) {
if (button1_pressed == 1) {
button1_pressed = 0;
printf("button 1 is pressed !\n");
}
/* sleep 100ms */
aos_msleep(100);
};
}
当button被按下后,串口会打印"button 1 is pressed !"
移植说明
新建hal_gpio_xxmcu.c和hal_gpio_xxmcu.h的文件,并将这两个文件放到platform/mcu/xxmcu/hal目录下。在hal_gpio_xxmcu.c中实现所需要的hal函数,hal_gpio_xxmcu.h中放置相关宏定义。<br /> 参考platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_gpio_stm32l4.c