本帖最后由 zero949079783 于 2022-8-29 21:33 编辑
开发环境:RT-Thread Studio
芯片上的引脚一般分为 4 类:电源、时钟、控制与 I/O,I/O 口在使用模式上又分为 General Purpose Input Output(通用输入 / 输出),简称 GPIO,与功能复用 I/O(如 SPI/I2C/UART 等)。 大多数 MCU 的引脚都不止一个功能。不同引脚内部结构不一样,拥有的功能也不一样。可以通过不同的配置,切换引脚的实际功能。通用 I/O 口主要特性如下: - 可编程控制中断:中断触发模式可配置,一般有下图所示 5 种中断触发模式:
-
[color=var(--theme-color, #42b983)]设置引脚模式引脚在使用前需要先设置好输入或者输出模式,通过如下函数完成:
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 /* 开漏输出 */
[color=var(--theme-color, #42b983)]绑定引脚中断回调函数若要使用到引脚的中断功能,可以使用如下函数将某个引脚配置为某种中断触发模式并绑定一个中断回调函数到对应引脚,当引脚中断发生时,就会执行回调函数:
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 /* 低电平触发 */
[color=var(--theme-color, #42b983)]使能引脚中断
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 使能成功
错误码 使能失败
[color=var(--theme-color, #42b983)]脱离引脚中断回调函数
可以使用如下函数脱离引脚中断回调函数:
rt_err_t rt_pin_detach_irq(rt_int32_t pin);
参数 描述
pin 引脚编号
返回 ——
RT_EOK 脱离成功
错误码 脱离失败
示例:
#include <rtthread.h>
#include <board.h> // 添加头文件
#include <sys/reent.h>
#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
#define LED0_PIN GET_PIN(F,9) //获取引脚号为 PF9 的 LED0
#define LED1_PIN GET_PIN(F,10) //获取引脚号为 PF10 的 LED1
#define KEY0_PIN GET_PIN(A,0) //获取引脚号为 PA0 的 KEY0
#define KEY1_PIN GET_PIN(E,3) //获取引脚号为 PE3 的 KEY1
void EXTI1_Callback(void *args);
void EXTI0_Callback(void *args);
int main(void)
{
int count = 1;
rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT); //设为输出模式
rt_pin_mode(LED1_PIN, PIN_MODE_OUTPUT); //设为输出模式
rt_pin_write(LED0_PIN, PIN_HIGH );//输出高电平
rt_pin_write(LED1_PIN, PIN_HIGH );//输出高电平
rt_pin_mode(KEY0_PIN, PIN_MODE_INPUT_PULLDOWN);//设为下拉输入模式
rt_pin_mode(KEY1_PIN, PIN_MODE_INPUT_PULLUP);//设为上拉输入模式
/* 绑定中断,上升沿触发模式,回调函数名为EXTI0_Callback */
rt_pin_attach_irq(KEY0_PIN, PIN_IRQ_MODE_RISING, EXTI0_Callback, RT_NULL);
/* 绑定中断,下降沿触发模式,回调函数名为EXTI1_Callback */
rt_pin_attach_irq(KEY1_PIN, PIN_IRQ_MODE_FALLING, EXTI1_Callback, RT_NULL);
/* 使能中断 */
rt_pin_irq_enable(KEY0_PIN, PIN_IRQ_ENABLE);
while (count++)
{
LOG_D("Hello RT-Thread!");
rt_thread_mdelay(1000);
}
return RT_EOK;
}
/* EXTI0中断回调函数 */
void EXTI0_Callback(void *args)
{
rt_pin_write(LED1_PIN, PIN_LOW );//输出低电平
rt_pin_write(LED0_PIN, PIN_LOW );//输出低电平
rt_kprintf("LED_ON\n");
/*脱离中断回调函数 */
rt_pin_detach_irq(KEY0_PIN);
/* 绑定中断,下降沿触发模式,回调函数名为EXTI1_Callback */
rt_pin_attach_irq(KEY1_PIN, PIN_IRQ_MODE_FALLING, EXTI1_Callback, RT_NULL);
/* 使能中断 */
rt_pin_irq_enable(KEY1_PIN, PIN_IRQ_ENABLE);
}
/* EXTI1中断回调函数 */
void EXTI1_Callback(void *args)
{
rt_pin_write(LED0_PIN, PIN_HIGH );//输出高电平
rt_pin_write(LED1_PIN, PIN_HIGH );//输出高电平
rt_kprintf("LED_OFF\n");
/*脱离中断回调函数 */
rt_pin_detach_irq(KEY1_PIN);
/* 绑定中断,上升沿触发模式,回调函数名为EXTI0_Callback */
rt_pin_attach_irq(KEY0_PIN, PIN_IRQ_MODE_RISING, EXTI0_Callback, RT_NULL);
/* 使能中断 */
rt_pin_irq_enable(KEY0_PIN, PIN_IRQ_ENABLE);
}
|