RT-Thread零基础快速入门第5讲——外部中断

一、前言

这一讲,我要讲的是外部中断,也不知道是太简单了还是没有人用,我没找到比较完整的关于RT-thread外部中断的教程,只发现RT-thread文档中心的PIN设备里面有提及中断相关的函数。不管怎样,我觉得外部中断平常用的还是很多的,至少我在使用RT-thread之前是经常会用到,好了,废话不多说,马上开始进入我们的教程。

源码链接

我发布的所有关于RT-thread的教程源代码都在下面这个链接里面,随着我教程的更新,新的代码也会加入进去。
教程源码下载链接:https://pan.baidu.com/s/1N2D8dM31deKIqNqaIQfPiA
提取码:7nsx

二、编程讲解

第一步:配置外部中断
在这里插入图片描述
从这个函数的描述我们可以很清楚的看到,只要调用上面这个函数就可以配置成外部中断脚,中断触发的方式,以及回调函数(等同于中断服务函数),而且回调函数的名称我们还可以自由定义,不像我们用裸机程序的时候,中断服务函数是已经固定了的。
第二步:使能中断
直接调用下面这个函数即可。
在这里插入图片描述
第三步:自己定义一个回调函数
因为RT-thread的外部中断没有固定的中断服务函数,所以我们需要自己定义一个,示例如下:

/* 自己定义一个回调函数,相当于中断服务函数 */
void IQR_HANDALE_KEY0(void *args)
{
    rt_pin_write(LED0_PIN, PIN_LOW);//点亮LED0
}

三、项目实战

因为这个两个函数原本在pin.c里面就有定义,所以我们也不需要自己去写,直接调用就行了。
我这里用两个按键,KEY0按下,触发外部中断,点亮LED0,KEY1按下,熄灭LED0,示例代码如下:

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

#define LED0_PIN    GET_PIN(F, 9)
#define LED1_PIN    GET_PIN(F, 10)
#define KEY0_PIN    GET_PIN(E, 4)
#define KEY1_PIN    GET_PIN(E, 3)

/* 自己定义KEY0的回调函数,相当于中断服务函数 */
void IQR_HANDALE_KEY0(void *args)
{
    rt_pin_write(LED0_PIN, PIN_LOW);//点亮LED0
}

/* 自己定义KEY1的回调函数,相当于中断服务函数 */
void IQR_HANDALE_KEY1(void *args)
{
    rt_pin_write(LED0_PIN, PIN_HIGH);//熄灭LED0
}

int main(void)
{
    int i = 0;

    /* 把LED引脚设置为输出 */
    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);

    /* 把KEY引脚设置为输入 */
    rt_pin_mode(KEY0_PIN, PIN_MODE_INPUT);
    rt_pin_mode(KEY1_PIN, PIN_MODE_INPUT);

    /* 绑定中断,下降沿模式,回调函数名为IQR_HANDALE_KEY0 */
    rt_pin_attach_irq(KEY0_PIN, PIN_IRQ_MODE_FALLING, IQR_HANDALE_KEY0, RT_NULL);
    /* 使能中断 */
    rt_pin_irq_enable(KEY0_PIN, PIN_IRQ_ENABLE);

    /* 绑定中断,下降沿模式,回调函数名为IQR_HANDALE_KEY1 */
    rt_pin_attach_irq(KEY1_PIN, PIN_IRQ_MODE_FALLING, IQR_HANDALE_KEY1, RT_NULL);
    /* 使能中断 */
    rt_pin_irq_enable(KEY1_PIN, PIN_IRQ_ENABLE);

    while (1)
    {
        rt_pin_write(LED1_PIN, PIN_LOW);//点亮LED1
        rt_thread_mdelay(1000);
        rt_pin_write(LED1_PIN, PIN_HIGH);//熄灭LED1
        rt_thread_mdelay(1000);
    }
}

四、结束语

好了,关于外部中断的编程讲解就到这里,如果还有什么问题可以私信给我。如果需要本文对应的源码的话可以在博文前言部分的链接下载。
如果觉得这篇文章对你有用,点赞+关注支持一下博主呗。
后续我会继续更新RT-thread入门教程系列,如果感兴趣的同学可以关注一下博主,谢谢!

RT-thread相关教程汇总:https://blog.csdn.net/ShenZhen_zixian/article/details/120563891

可以按照以下步骤实现STM32F103利用rt-thread外部中断接收nrf24l01的数据: 1. 首先,需要配置nrf24l01的SPI接口,并初始化nrf24l01的寄存器。 2. 配置外部中断,使其对应nrf24l01的IRQ引脚。在中断服务函数中,读取nrf24l01的状态寄存器,判断是否有数据接收完成。 3. 如果有数据接收完成,从nrf24l01的接收缓冲区中读取数据,并将数据传递给rt-thread的消息队列。 4. 在rt-thread的线程中,从消息队列中读取数据,并进行处理。 以下是一个简单的示例代码: ``` #include "rtthread.h" #include "drv_spi.h" #include "drv_nrf24l01.h" #define NRF24L01_IRQ_PIN GPIO_PIN_0 #define NRF24L01_IRQ_PORT GPIOA static rt_mq_t nrf24l01_mq; void nrf24l01_irq_handler(void) { if (nrf24l01_rx_data_ready()) { uint8_t data[32]; nrf24l01_read_rx_payload(data, sizeof(data)); rt_mq_send(&nrf24l01_mq, data, sizeof(data)); } } void nrf24l01_thread_entry(void* parameter) { rt_uint8_t data[32]; while (1) { rt_err_t result = rt_mq_recv(&nrf24l01_mq, data, sizeof(data), RT_WAITING_FOREVER); if (result == RT_EOK) { // 处理接收到的数据 } } } static void nrf24l01_init(void) { // 配置SPI接口 spi_init(); // 初始化nrf24l01寄存器 nrf24l01_init(); // 配置外部中断 GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = NRF24L01_IRQ_PIN; GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(NRF24L01_IRQ_PORT, &GPIO_InitStruct); // 配置中断服务函数 HAL_NVIC_SetPriority(EXTI0_IRQn, 5, 0); HAL_NVIC_EnableIRQ(EXTI0_IRQn); // 创建消息队列 rt_mq_init(&nrf24l01_mq, "nrf24l01_mq", data, sizeof(data), 32, RT_IPC_FLAG_FIFO); } int rt_application_init(void) { // 创建nrf24l01线程 rt_thread_t nrf24l01_thread = rt_thread_create("nrf24l01", nrf24l01_thread_entry, RT_NULL, 1024, 25, 10); if (nrf24l01_thread != RT_NULL) { rt_thread_startup(nrf24l01_thread); } // 初始化nrf24l01 nrf24l01_init(); return 0; } ``` 在上面的代码中,nrf24l01_irq_handler()函数是中断服务函数,会在nrf24l01的IRQ引脚触发外部中断时被调用。在该函数中,读取nrf24l01的状态寄存器,判断是否有数据接收完成,如果有,则从nrf24l01的接收缓冲区中读取数据,并将数据传递给rt-thread的消息队列。 nrf24l01_thread_entry()函数是rt-thread的线程函数,会从消息队列中读取数据,并进行处理。在该函数中,调用rt_mq_recv()函数从消息队列中读取数据。如果读取成功,则可以对接收到的数据进行处理。 在rt_application_init()函数中,创建nrf24l01线程,并初始化nrf24l01。在初始化nrf24l01时,会配置nrf24l01的SPI接口,并初始化nrf24l01的寄存器。同时,会配置外部中断,使其对应nrf24l01的IRQ引脚。创建消息队列时,需要指定消息队列的名称、消息缓冲区、消息长度和消息数量等参数。 如果需要发送数据,可以调用nrf24l01_write_tx_payload()函数将数据写入nrf24l01的发送缓冲区,然后调用nrf24l01_transmit()函数启动发送过程。发送完成后,会触发中断,可以在中断服务函数中处理发送完成的事件。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值