之前写过了对于NRF24L01的单向通信,即一个作为固定发送端,另一个作为固定接收端的程序。这次在之前的基础上更进一步,让两个NRF24L01芯片互相通信,两个芯片在发送和接收模式之间来回切换。这样就可以做到双向通信。
NRF24L01芯片中有一个应答机制,就是在接收到信息后,接收端延时一段时间后会给发送端一个应答信号,但是这个应答信号我在实际使用过程中会出现错误,我也找不到错误在哪里,所以干脆就不使用它的应答,直接将应答关掉。

NRF_WriteRegister(NRF_REG_EN_AA, ENAA_ALL_DISABLE);     //使能自动应答(不使用自动应答)

大概思路有两种如下:
想要双向通信的话,就需要先找某一端作为发送端A,另一端作为接收端B,然后依次进入发送和接收模式。
1.一种是两个芯片A先进入发送端,3ms后如果发送完成就进入接收模式(这个时间与需要发送的数据量的大小有关,这里以发送19个字节的数据为例,大约需要1ms左右,等待3ms是为了使其将所有数据发送出去),另一端B也先进入接收模式,只不过2ms后发送完成进入接收模式,将两个芯片的运行时间错开。
2.在A发送作为发送端发送数据时,B需要在RX_MODE下等待,直到接收到A端发送的消息为止。A端发送完一个字节的数据后将发送中断标志位和FIFO全部清零并进入RX_MODE开始等待,B端接收到数据后将接收到的数据从FIFO中读出后把接收中断标志位和FIFO全部清零并进入TX_MODE开始发送消息。
以上两种方法都是可行的,只不过各有优缺点。

接下来贴上第一种方法的代码:

while(1){static NRF_TR_e modestatus;if(millis()>=(RC_WRITE_HANDLE_PERIOD+RC_WRITE_HANDLE_TIME)){RC_WRITE_HANDLE_TIME=millis();if(!modestatus){modestatus=TX;}switch(modestatus){case TX:rc_txdata_handle();NRF_TX_mode();NRF_FIFO_WRITE(nrf_tx_buffer,NRF_BUFFER_SIZE);modestatus=TX_DONE;break;case TX_DONE:NRF_WriteRegister(NRF_REG_STATUS, CLEAR_TX_IRQ);modestatus=RX;break;case RX:while(IRQ){static uint16_t wait;if(++wait>1000){wait=0;break;}  }if(!IRQ){uint8_t status = NRF_ReadRegister(NRF_REG_STATUS);if(status & CLEAR_RX_IRQ){NRF_WriteRegister(NRF_REG_STATUS, CLEAR_RX_IRQ);NRF_RX_mode();NRF_FIFO_READ(nrf_rx_buffer,NRF_BUFFER_SIZE);rc_rxdata_handle();NRF_FIFO_FLUSH(FLUSH_RX);}}break;default:break; }}}

这是第一种方法的程序,只需要改变RC_WRITE_HANDLE_PERIOD的值就可以了,一个为2,一个为3。优点是两个芯片可以共用一套程序,缺点是可能会影响收发数据的精准度和速度。

第二种方法的代码与第一种大同小异,只不过接收端有另外一套程序,我还没有做具体的测试能不能使用,仅供参考吧:

//发送端
while(1){static NRF_TR_e modestatus;if(millis()>=(RC_WRITE_HANDLE_PERIOD+RC_WRITE_HANDLE_TIME)){RC_WRITE_HANDLE_TIME=millis();if(!modestatus){modestatus=TX;}switch(modestatus){case TX:rc_txdata_handle();NRF_TX_mode();NRF_FIFO_WRITE(nrf_tx_buffer,NRF_BUFFER_SIZE);modestatus=TX_DONE;break;case TX_DONE:NRF_WriteRegister(NRF_REG_STATUS, CLEAR_TX_IRQ);modestatus=RX;break;case RX:while(IRQ){static uint16_t wait;if(++wait>1000){wait=0;break;}  }if(!IRQ){uint8_t status = NRF_ReadRegister(NRF_REG_STATUS);if(status & CLEAR_RX_IRQ){NRF_WriteRegister(NRF_REG_STATUS, CLEAR_RX_IRQ);NRF_RX_mode();NRF_FIFO_READ(nrf_rx_buffer,NRF_BUFFER_SIZE);rc_rxdata_handle();NRF_FIFO_FLUSH(FLUSH_RX);}}break;default:break; }}}//接收端
while(1){static NRF_TR_e modestatus;if(millis()>=(RC_WRITE_HANDLE_PERIOD+RC_WRITE_HANDLE_TIME)){RC_WRITE_HANDLE_TIME=millis();if(!modestatus){modestatus=RX;}switch(modestatus){case RX:while(IRQ){static uint16_t wait;if(++wait>1000){wait=0;break;}}if(!IRQ){uint8_t status = NRF_ReadRegister(NRF_REG_STATUS);if(status & CLEAR_RX_IRQ){NRF_WriteRegister(NRF_REG_STATUS, CLEAR_RX_IRQ);NRF_RX_mode();rc_rxdata_handle();NRF_FIFO_WRITE(nrf_rx_buffer,NRF_BUFFER_SIZE);}}modestatus=RX_DONE;case RX_DONE:NRF_WriteRegister(NRF_REG_STATUS, CLEAR_RX_IRQ);modestatus=TX;case TX:rc_txdata_handle();NRF_TX_mode();NRF_FIFO_WRITE(nrf_rx_buffer,NRF_BUFFER_SIZE);modestatus=TX_DONE;case TX_DONE:NRF_WriteRegister(NRF_REG_STATUS, CLEAR_TX_IRQ);modestatus=RX;}}}

第二个方法的优点是相较于第一种提高了数据接收和发送的精准度,速度有一定的提升,缺点是需要两套程序。

NRF24L01+双向通信相关推荐

  1. NRF24L01+模块实现双向通信(带ACK payload)

    本文主要关于NRF24L01+ 2.4GHz无线模块的应用. 目录 说明 模块开发的大致步骤 使用方式 一.单向通信 二.双向通信(有应答包(ACK payload)) 寄存器配置 三.星状组网 注意 ...

  2. Portapack应用开发教程(七)nrf24l01解调

    前段时间我在做低功耗蓝牙的时候看到了这个网页 https://wiki.bitcraze.io/misc:hacks:hackrf 但是我当时没有成功解调nrf24l01,反而成功搞定蓝牙了. 后来我 ...

  3. NRF24L01+实现一对一数据双向传输

    NRF24L01+实现一对一数据双向传输 目录 说明 带负载数据ACK的双向通信 配置NRF24L01+的收发程序 收发双方数据的处理 测试代码和结果 目录 说明 最近在diy四轴飞行器的时候,需要实 ...

  4. 2.2 Arduino各类模块-3(NRF24L01 2.4G无线模块单向双向传输)

    6.2.4G无线模块(NRF24L01) 说明: 使用1.9-3.6v供电,典型供电3.3v NRF24L01 2.4G无线模块我们分为两个部分,使用两个不同的库进行实现. NRF24L01硬件上具有 ...

  5. arduino笔记33:nRF24l01模块使用 FSK 波特率 通信方式 PTX PRX

    最近再arduino中文社区看到了一篇介绍nrf24l01基本原理的帖子,内容感觉蛮不错的,学习一下,记录一下学习笔记. 大部分内容都是Arduino中文社区的帖子,附上自己的一点点体会. 目录 一. ...

  6. Arduino无线通信– NRF24L01教程

    在本Arduino教程中,我们将学习如何使用NRF24L01收发器模块在两个Arduino板之间进行无线通信.您可以观看以下视频或阅读下面的书面教程. Arduino无线通信– NRF24L01教程 ...

  7. linux进程间通信:FIFO实现进程间的双向通信

    fifo的双向通信的方式如下图: 两个进程间的通信需要两个命名管道,分别处理一个进程的读和写 导致这种通信方式出现的根因还是由于fifo的阻塞读和阻塞写,所以这里需要使用两个管道对读写进行分别处理. ...

  8. Android应用开发提高篇(4)-----Socket编程(多线程、双向通信)(转载)

    转自:http://www.cnblogs.com/lknlfy/archive/2012/03/04/2379628.html 一.概述 关于Socket编程的基本方法在基础篇里已经讲过,今天把它给 ...

  9. AIDL 客户端与服务端的双向通信

    时隔一年半了,终于写下了这个续篇,我发现我的很多博客有头无尾,都是有前面一点点,后面就没写去了,也正在想办法都补上 初涉IPC,了解AIDL的工作原理及使用方法 今天聊聊的是客户端和服务端的相互通信, ...

最新文章

  1. 《女性的选择》--[日]今野由梨
  2. AC-Tek Sidewinder v7.2.2 输送机设计+IDEA StatiCa v9.1.31.50722 钢结构混凝土结构件设计...
  3. 蓝桥杯-算法训练 2的次幂表示
  4. boost::process::posix相关的测试程序
  5. 退货表mysql_openant电商-退货 - 数据库设计 - 数据库表结构 - 果创云
  6. 设计模式--常用8个设计模式 单例-策略-责任链-装饰者-迭代器模式-观察者模式-常用设计模式
  7. linux 自动挂载usb设备,Raspberry Pi 自动挂载USB存储设备
  8. mysql使用存储过程循环修改数据
  9. 翻译:iOS上的MVVM + RxSwift架构对比 MVC,MVVM,MVP和VIPER
  10. LightOj 1336(Sigma Function)
  11. 阿里巴巴高级算法专家威视:组建技术团队的一些思考
  12. html炫酷文本框,炫酷的input框实现
  13. 海南旅游自由行攻略怎么玩
  14. 人工智能方向本科生如何查看论文?
  15. 威联通NAS实现定时任务
  16. 华为防火墙USG6309E开局基础配置之网络设置
  17. Arturia ARP 2600 V3 for Mac - 音响模拟合成工具
  18. linux生成xorg,生成xorg.conf文件
  19. 我谈阶梯博弈( Staircase Nim )
  20. 面向可解释AI的黑盒和白盒模型

热门文章

  1. Jetson Nano 硬件相关
  2. JavaApplet编程技巧
  3. 711问题-优化蛮力求解
  4. ucenter通信实现同步登录、同步退出(详细)
  5. 开源软件库TensorFlow最全教程和项目列表
  6. vue动态设置路由重定向
  7. ao史密斯定时设置_下图ao史密斯热水器的预约定时怎么用?
  8. cookie详解,即什么是cookie。
  9. win7 桌面计算机不显示器,教你解决win7检测不到第二个显示器的方法
  10. cobra是什么鬼?