关于文章《NRF24L01使用外部中断读取数据的问题》中的错误。

原文:NRF24L01读取数据不能使用中断的方式,原因如下:首先NRF24L01中断触发时,IRQ引脚会一直保持低电平直到状态寄存器中的中断标志被重新清零。stm32的外部中断触发方式只有上升沿或者下降沿触发,若配置成外部中断模式,当RX_DR中断触发时IRQ引脚会产生一个下降沿,stm32进入中断函数执行数据读取函数,读取完之后清除状态寄存器标志,IRQ引脚重新变为高电平。但,若在在清除中断标志之后刚好又来了一帧数据,而此时还没有出中断函数,IRQ引脚就会被置为低电平,然后退出中断函数,但IRQ引脚再也产生不了下降沿信号(因为中断标志位不会再被清除),也即再也进不了中断了。总而言之尽量用查询的方式,不要用中断就好。

解决办法:清除IRQ中断的语句,前面加CE拉低,后面加CE拉高,就可以正常使用中断接收了,不会再出现进不去中断的问题了。原因,手册说了,写寄存器必须在待机或掉电模式下进行,代码如下:

void NRF24L01_IRQ_Clear(void)
{
	uint8_t sta;
	sta = NRF24L01_Read_Reg(STATUS);  //读取状态寄存器的值
	NRF24L01_CE_LOW();//此处拉低<———————————————————————————————————————————————————————————!!!
	NRF24L01_Write_Reg(NRF_WRITE_REG + STATUS, sta); //清除TX_DS或MAX_RT中断标志
	NRF24L01_Write_Reg(FLUSH_RX, 0xff); //清除RX FIFO寄存器
	NRF24L01_Write_Reg(FLUSH_TX, 0xff); //清除TX FIFO寄存器
	NRF24L01_CE_HIGH();//此处拉高<———————————————————————————————————————————————————————————!!!
}

如果对你有帮助,并解决了问题帮忙点下赞,我好做下统计,谢谢!

--------------------------------------------------北雁南飞 ----------------------------------------------

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以按照以下步骤实现STM32F103利用rt-thread外部中断接收nrf24l01的数据: 1. 首先,需要配置nrf24l01的SPI接口,并初始化nrf24l01的寄存器。 2. 配置外部中断,使其对应nrf24l01IRQ引脚。在断服务函数,读取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()函数是断服务函数,会在nrf24l01IRQ引脚触发外部中断时被调用。在该函数,读取nrf24l01的状态寄存器,判断是否有数据接收完成,如果有,则从nrf24l01的接收缓冲区读取数据,并将数据传递给rt-thread的消息队列。 nrf24l01_thread_entry()函数是rt-thread的线程函数,会从消息队列读取数据,并进行处理。在该函数,调用rt_mq_recv()函数从消息队列读取数据。如果读取成功,则可以对接收到的数据进行处理。 在rt_application_init()函数,创建nrf24l01线程,并初始化nrf24l01。在初始化nrf24l01时,会配置nrf24l01的SPI接口,并初始化nrf24l01的寄存器。同时,会配置外部中断,使其对应nrf24l01IRQ引脚。创建消息队列时,需要指定消息队列的名称、消息缓冲区、消息长度和消息数量等参数。 如果需要发送数据,可以调用nrf24l01_write_tx_payload()函数将数据写入nrf24l01的发送缓冲区,然后调用nrf24l01_transmit()函数启动发送过程。发送完成后,会触发断,可以在断服务函数处理发送完成的事件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值