简介
GPIO(General Purpose Input and Output)是通用输入输出口。通俗地说,就是一些引脚,可以通过它们对外输出电平信号或者通过它们读取外部的电平信息。将I/O口用作普通输入/输出功能时,有两种常见的使用方式:一种是用作普通的输入/输出接口;一种是用作中断输入接口,即当指定的输入状态事件发生(比如:下降沿)时,触发用户自定义的回调函数。
接口介绍
函数列表:
函数原型 |
简要描述 |
aw_err_t aw_pin_cfg (int pin, uint32_t flags); |
配置引脚属性 |
aw_err_t aw_gpio_get (int pin); |
读取引脚的输入/输出值 |
aw_err_t aw_gpio_set (int pin, int value); |
设置引脚输出值 |
aw_err_t aw_gpio_toggle (int pin); |
翻转引脚的输出值,即高电平变低电平,低电平变高电平 |
aw_err_t aw_gpio_trigger_cfg (int pin, uint32_t flags); |
配置引脚“触发条件”,触发条件可位或 |
aw_err_t aw_gpio_trigger_connect (int pin, aw_pfuncvoid_t pfunc_callback, void *p_arg); |
连接一个回调函数到引脚 |
aw_err_t aw_gpio_trigger_disconnect (int pin, aw_pfuncvoid_t pfunc_callback, void *p_arg); |
断开引脚的回调函数 |
aw_err_t aw_gpio_trigger_on (int pin); |
开启引脚的触发功能 |
aw_err_t aw_gpio_trigger_off (int pin); |
关闭指定引脚的触发功能 |
使用aw_pin_cfg (int pin, uint32_t flags)接口配置pin为gpio功能时,flags参数详见下表。
GPIO属性配置表:
GPIO属性 |
宏定义 |
值 |
描述 |
GPIO模式 |
AW_PIN_CFG_GPIO_INPUT |
1<<0 |
输入模式 |
AW_PIN_CFG_GPIO_OUTPUT |
2<<0 |
输出模式 |
|
AW_PIN_CFG_GPIO_OUTPUT_LOW |
3<<0 |
输出模式且输出低 |
|
AW_PIN_CFG_GPIO_OUTPUT_HIGH |
4<<0 |
输出模式且输出高 |
|
上下拉功能 |
AW_PIN_CFG_FLOAT |
0<<3 |
浮空 |
AW_PIN_CFG_PULL_UP |
1<<3 |
上拉 |
|
AW_PIN_CFG_PULL_DOWN |
2<<3 |
下拉 |
|
AW_PIN_CFG_PULL_UP_DOWN |
3<<3 |
同时使能上下拉 |
|
输出模式 |
AW_PIN_CFG_OUTPUT_MODE_DRIVE |
0<<5 |
直接输出 |
AW_PIN_CFG_OUTPUT_MODE_OPEN_DRAIN |
1<<5 |
开漏输出 |
|
AW_PIN_CFG_OUTPUT_MODE_PUSH_PULL |
2<<5 |
推挽输出 |
配置时,flags参数可以是一个或者多个相关宏定义的组合,简单示例如下:
aw_pin_cfg(pin, AW_PIN_CFG_GPIO_INPUT);
/* 引脚配置为输出,浮空(无上下拉),直接输出 */
aw_pin_cfg(pin, AW_PIN_CFG_GPIO_OUTPUT);
aw_pin_cfg(pin, AW_PIN_CFG_GPIO_INPUT | AW_PIN_CFG_PULL_DOWN );
aw_pin_cfg(pin, AW_PIN_CFG_GPIO_OUTPUT| AW_PIN_CFG_OUTPUT_MODE_PUSH_PULL)
注意:- 调用配置时,若上表中GPIO属性值存在缺省时,则会使用未偏移前对应值为0的宏定义默认填充,如上述示例中line3;
- 配置时需一次性将flags进行传入,不能每次传递一个属性进行配置进行多次调用,否则可能和期望配置结果不匹配。
GPIO中断配置表:
宏定义 |
描述 |
AW_GPIO_TRIGGER_HIGH |
高电平触发 |
AW_GPIO_TRIGGER_LOW |
低电平触发 |
AW_GPIO_TRIGGER_RISE |
上升沿触发 |
AW_GPIO_TRIGGER_FALL |
下降沿触发 |
配置时,flags参数可以是一个或者多个上表宏定义的组合,简单示例如下:
aw_gpio_trigger_cfg (pin, AW_GPIO_TRIGGER_HIGH);
aw_pin_cfg(pin, AW_GPIO_TRIGGER_RISE);
aw_pin_cfg(pin, AW_GPIO_TRIGGER_RISE | AW_GPIO_TRIGGER_HIGH );
/* 双边沿触发 */
aw_pin_cfg(pin, AW_GPIO_TRIGGER_RISE | AW_GPIO_TRIGGER_FALL);
注意:- 当设置为不合理条件触发组合(如 AW_GPIO_TRIGGER_HIGH | AW_GPIO_TRIGGER_FALL)时,该函数会返回-AW_EINVAL。
使用样例
AWorksLP SDK相关使用请参考《AWorksLP SDK快速入门(MR6450)——开箱体验》一文,本文不再赘述。1.通用IO功能{SDK}demosperipheralgpio路径下为通用GPIO例程,例程具体代码如下:
/**
* rief GPIO demo 入口
*
eturn 无
*/
void demo_gpio_entry (int gpio)
{
int i = 0;
aw_kprintf("
GPIO demo testing...
");
/* LED以1s的周期闪烁5次 */
for (i = 0; i < 5; i++) {
aw_gpio_set(gpio, 0);
aw_mdelay(500);
aw_gpio_set(gpio, 1);
aw_mdelay(500);
}
/* LED以0.2s的周期持续闪烁 */
for (i = 0; i < 40; i++) {
aw_gpio_toggle(gpio);
aw_mdelay(100);
}
aw_kprintf("
GPIO demo exit...
");
}
上述代码中使用aw_gpio_set和aw_gpio_toggle接口分别实现了500ms时间间隔的引脚5次反转以及100ms时间间隔引脚40次反转。在HPM的SDK中,传入该例程函数的引脚为RUN灯,所以最终的实验现象是LED灯先以较慢的速度闪烁,后以较快的速度闪烁,RUN灯的位置如图1所示。
图1运行灯
2.中断功能{SDK}demosperipheralint路径下为通用中断例程,例程具体代码如下:
/**rief 记录是否产生中断 */
AW_SEMB_DECL_STATIC(__gpio_intr_semb);
static void __test_gpio_trig_isr (void* arg)
{
int interrupt_pin = (int)arg;
/* 关闭触发中断,避免电平触发时不停地进中断导致程序无法继续运行 */
aw_gpio_trigger_off(interrupt_pin);
AW_SEMB_GIVE(__gpio_intr_semb);
}
void demo_interrupt_entry (int output_pin, int interrupt_pin)
{
aw_err_t err;
int i;
aw_kprintf("
interrupt demo testing...
");
/* 信号量初始化 */
AW_SEMB_INIT(__gpio_intr_semb, AW_SEM_EMPTY, AW_SEM_Q_FIFO);
/* 连接中断回调函数 */
err = aw_gpio_trigger_connect(interrupt_pin,
__test_gpio_trig_isr,
(void *)interrupt_pin);
if (err != AW_OK) {
aw_kprintf("gpio trigger connect failed!
");
return;
}
/* 配置为 TRIGGER_FLAG 对应方式触发 */
err = aw_gpio_trigger_cfg(interrupt_pin, TRIGGER_FLAG);
if (err != AW_OK) {
aw_kprintf("gpio trigger cfg failed!
");
return;
}
/* 开启引脚的触发 */
err = aw_gpio_trigger_on(interrupt_pin);
if (err != AW_OK) {
aw_kprintf("gpio trigger on failed!
");
return;
}
for (i = 0; i < 50; i++) {
/* 设置输出管脚为低电平 */
aw_gpio_set(output_pin, 0);
/* 等待中断触发 */
err = AW_SEMB_TAKE(__gpio_intr_semb, 1000);
if (err == AW_OK) {
aw_kprintf("enter gpio interrupt!
");
}
/* 打开在回调函数中关闭的触发中断 */
err = aw_gpio_trigger_on(interrupt_pin);
if (err != AW_OK) {
aw_kprintf("gpio trigger on failed!
");
return;
}
/* 设置输出管脚为高电平 */
aw_gpio_set(output_pin, 1);
aw_mdelay(100);
}
/* 断开中断连接回调函数 */
aw_gpio_trigger_disconnect(interrupt_pin,
__test_gpio_trig_isr,
(void *)interrupt_pin);
/* 关闭引脚的触发 */
aw_gpio_trigger_off(interrupt_pin);
/* 终止信号量 */
AW_SEMB_TERMINATE(__gpio_intr_semb);
aw_kprintf("interrupt demo exit...
");
}
在例程代码中通过aw_gpio_trigger_connect、aw_gpio_trigger_cfg、aw_gpio_trigger_on三个接口配置interrupt_pin引脚中断触发模式为AW_GPIO_TRIGGER_RISE、中断回调函数为__test_gpio_trig_isr并对中断进行使能,同时配置output_pin持续翻转作为中断源的提供引脚,当output_pin 输出满足例程的中断条件时,会触发中断进入__test_gpio_trig_isr函数释放__gpio_intr_semb信号量,在例程中获取信号量成功后并打印"enter gpio interrupt!"。
例程中默认使用中断例程输出信号引脚为PIN_PF08、中断测试引脚为PF09,但由于本文测试所使用开发板并未引出该组引脚,故使用开发板上丝印URX1(PIN_PE24)做信号输出引脚与UTX1(PIN_PE25)做中断引脚进行测试,需修改main.c文件中TEST_OUTPUT_PIN与TEST_INTERRUPT_PIN宏定义,修改后如下所示:
修改完成后,重新编译工程并下载固件至开发板中,将开发板丝印URX1与UTX1引脚短接,并使用串口工具连接至DUART接口,则可看到在上位机中打印下图信息,表明中断触发成功。
图2串口打印信息注意事项:
- aw_gpio_trigger_connect函数所连接的回调函数是在中断中进行调用的,故该函数的实现需尽量的简短、高效,避免执行时间过长,否则可能会影响OS的实时性;
- 若中断触发条件为电平触发时,需在中断回调中关闭对应引脚中断,否则电平持续阶段会一直产生中断。
由于篇幅限制,样例中仅选取了部分特性进行讲解,在使用时需根据实际情况配置相应的触发条件以满足项目需求,更多引脚属性功能使用以及中断组合特性可自行调整测试。
本文对GPIO外设接口及样例做了详细介绍,当然其他外设也会陆续发布,请大家关注后续推文更新~
-
致远电子
+关注
关注
13文章
406浏览量
31304
原文标题:【产品应用】AWorksLP样例详解(MR6450)-- GPIO
文章出处:【微信号:ZLG_zhiyuan,微信公众号:ZLG致远电子】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
评论