NRF24L01中断双向传输数据
NRF24L01是一款比较常见的无线通讯芯片,不过有个缺点就是只能半双工通讯,当涉及到双向通讯时就比较麻烦一些·,特别是想要做无线IAP数据需要一直来回发送,这点无疑然人恶心到想吐,不过还好有数据中断可以用来做切换。
前些时间做的无线IAP用到双向通讯,现在分享如下
省去初始化SPI,等一些初始化
- 初始化接口,以及中断引脚IRQ
- void EXTIInitialize(void) //外部中断初始化
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- EXTI_InitTypeDef EXTI_InitStructure;
- NVIC_InitTypeDef NVIC_InitStructure;
- NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //通道设置为串口1中断
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //中断抢占优先级1
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //中断响应优先级2
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //打开中断
- NVIC_Init(&NVIC_InitStructure);
- GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0);
- GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0; //外部中断0
- GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU; //上拉输入
- GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- EXTI_ClearITPendingBit(EXTI_Line0);
- EXTI_InitStructure.EXTI_Line = EXTI_Line0;
- EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
- EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
- EXTI_InitStructure.EXTI_LineCmd = ENABLE;
- EXTI_Init(&EXTI_InitStructure);
- }
- void EXTI0_IRQHandler(void)
- {
- if(EXTI_GetITStatus(EXTI_Line0)!=RESET)
- {
- DataProces();
- EXTI_ClearITPendingBit(EXTI_Line0);
- }
- }
、模式初始化选择数据中断void NRF_Mode(char mode)
- {
- NRF24L01_CE=0;
- NRF24L01_Write_Reg(WRITE_REG_NRF+SETUP_AW,0x03);//地址宽度
- NRF24L01_Write_Buf(WRITE_REG_NRF+TX_ADDR,(u8*)TX_ADDRESS,TX_ADR_WIDTH);//写TX节点地址
- NRF24L01_Write_Buf(WRITE_REG_NRF+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH);//写RX节点地址
- NRF24L01_Write_Reg(WRITE_REG_NRF+EN_AA,0x00); //使能通道0的自动应答
- NRF24L01_Write_Reg(WRITE_REG_NRF+EN_RXADDR,0x01);//使能通道0的接收地址
- NRF24L01_Write_Reg(WRITE_REG_NRF+SETUP_RETR,0x1a);
- NRF24L01_Write_Reg(WRITE_REG_NRF+RF_CH,124); //设置RF通信频率
- NRF24L01_Write_Reg(WRITE_REG_NRF+RX_PW_P0,RX_PLOAD_WIDTH);//选择通道0的有效数据宽度
- NRF24L01_Write_Reg(WRITE_REG_NRF+RF_SETUP,0x0f);//设置TX发射参数,0db增益,2Mbps,低噪声增益开启
- //tx
- if(mode==1)
- NRF24L01_Write_Reg(WRITE_REG_NRF+CONFIG,0x5e);//0101
- //rx
- else
- NRF24L01_Write_Reg(WRITE_REG_NRF+CONFIG, 0x3f);
- NRF24L01_CE = 1; //CE为高,启动配置
- }
、接受到数据后产生中断以及发送完成产生中断,中断相对于主机而言,对于只是产生一个高电平,用中断去处理相关数据void DataProces(void)
- {
- u8 sta,i;
- sta=NRF24L01_Read_Reg(STATUS); //读取状态寄存器的值
- NRF24L01_Write_Reg(WRITE_REG_NRF+STATUS,0x70); //清除中断标志
- if(sta&TX_OK)//发送完成
- {
- NRF24L01_Write_Reg(FLUSH_TX,0xff);//清除TX FIFO寄存器
- ChangeMode(2);
- my_delay_us(10); //粗略等待15us,不调用滴答定时器影响整体时序
- }
- if(sta&RX_OK)//接收到数据
- {
- NRF24L01_Read_Buf(RD_RX_PLOAD,RxNrfBuf,RX_PLOAD_WIDTH);//读取数据
- NRF24L01_Write_Reg(FLUSH_RX,0xff);//清除RX FIFO寄存器
- ChangeMode(1);
- IAP(RxNrfBuf);
- //不调用滴答定时器影响整体时序
- //延时30等待对方切换模式s
- my_delay_us(50);
- //TxNrfBuf[0] = test++;
- NrfSend(TxNrfBuf);
- }
- }
4、接受或者发送完成之后便可以做响应的处理,其中为了提高数据准确性我将中断数据处理定义成两个模式分为主接受,和主发送。’主接受模式接收到数据后就切换发送模式根据需要去返回数据,发送完成后就立马切换为接收模式,以接收模式作为常态,为下一次的接收做准备;主发送模式发送完数据后就切换为接收模式,等待有数据返回,返回后就立马切换为发送模式,以发送模式作为常态。其中有一个小小的技巧,在主发送模式下等待接收数据时可开启定时器,用来做超时处理,超时后重新发送,当然,NRF25L01上面自带重发功能,但我不太喜欢上面的自动重发,那个是不可控的,我比较喜欢可控的数据收发,这样更为灵活,可以根据自己单片机的速度以及环境因素设定 符合自己的所需要的重发时间
- void ChangeMode(char mode)
- {
- NRF24L01_CE=0;
- //TX
- if(mode == 1)
- NRF24L01_Write_Reg(WRITE_REG_NRF+CONFIG,0x5e);
- else
- NRF24L01_Write_Reg(WRITE_REG_NRF+CONFIG,0x3f);
- NRF24L01_CE=1;//启动
- }
NRF24L01中断双向传输数据的更多相关文章
- 【Java】学习路径55-练习:制作一个聊天室(多线程、UDP、双向传输数据)
创建四个类,实现双向聊天的功能. 接收线程: import java.io.IOException; import java.net.*; public class ReceiveThread imp ...
- NRF24L01使用外部中断读取数据的问题
NRF24L01读取数据不能使用中断的方式,原因如下: 首先NRF24L01中断触发时,IRQ引脚会一直保持低电平直到状态寄存器中的中断标志被重新清零. stm32的外部中断触发方式只有上升沿或者下降 ...
- NRF24L01学习
一.工作模式 PWR_UP和PRIM_RX在寄存器0x00中的第0位和第1位. 待机模式I:只是使用晶振工作,CE=0时是拉低? 待机模式II:部分时钟缓冲器处在工作模式.TX FIFO为空并且CE为 ...
- [stm32] NRF24L01+USART搞定有线和无线通信
前言 一般进行远程监控时,2.4G无线通信是充当远程数据传输的一种方法.这时就需要在现场部分具备无线数据发送装置,而在上位机部分由于一般只有串口,所以将采集到的数据送到电脑里又要在上位机端设计一个数据 ...
- 总线接口与计算机通信(四)USB外部总线(初级认识)
USB简介 USB是英文Universal Serial BUS(通用串行总线)的缩写,是一个外部总线标准,用于规范电脑与外部设备的连接和通讯,是应用在PC领域的接口技术.USB接口支持设备的即插 ...
- java NIO详解
http://zalezone.cn/2014/09/17/NIO%E7%B2%BE%E7%B2%B9/ 1. 前言 我们在写java程序的时候,为了进行优化,把全部的精力用在了处理效率上,但是对IO ...
- 网卡phy9161A
硬件1. 网口网口使用4根信号线:两根发送,两根接收.一对信号线中一根承载0——+2.5V信号电压,而另一根负载的电压是0——-2.5V,因此可产生一个5Vpp的信号差.RJ45中有用的就是4根信号线 ...
- 计算机网络之传输层 下(TCP)
1. TCP的特点 特点:它是一个点到点的通信机制,只能有一个发送方和一个接收方:它提供是一个可靠的,按序的字节流机制:使用流水线机制,通过拥塞控制和流量控制的机制设置窗口尺寸:发送方和接收方都有缓存 ...
- C# WinForm 跨线程访问控件(实用简洁写法)
C# WinForm 跨线程访问控件(实用简洁写法) 1.<C# WinForm 跨线程访问控件(实用简洁写法)> 2.<基于.NET环境,C#语言 实现 TCP NAT ...
随机推荐
- 如何修改 app.config 的配置信息
如何修改 app.config 的配置信息 收藏 最问这个问题的人有点多,其实 .Net 提供了这样的功能我们可以在 app.config 中 userSettings 节点中保存我们的应用程序设置信 ...
- iOS 十种线程锁
锁 是什么意思? 我们在使用多线程的时候多个线程可能会访问同一块资源,这样就很容易引发数据错乱和数据安全等问题,这时候就需要我们保证每次只有一个线程访问这一块资源,锁 应运而生. 这里顺便提一下,上锁 ...
- 015.Oracle数据库,取本月月初,取本月月末
/*取本月月初,取本月月末*/ SELECT trunc( SYSDATE, 'mm' ) AS 月初 , last_day(trunc(sysdate)) AS 月末 FROM dual; 修改如下 ...
- javascript 原型链污染
原理①javascript中构造函数就相当于类,并且可以将其实例化 ②javascript的每一个函数都有一个prototype属性,用来指向该构造函数的原型同样的javascript的每一个实例对象 ...
- Day 26:Dom4j修改xml
Dom4j:Writing a document to a file import java.io.File; import java.io.FileOutputStream; import org. ...
- symbol数据类型
symbol声明的类型独一无二 概念:表示独一无二的值,永远不相等 s1 = Symbol() s2 = Symbol() s1 !== s2 基本使用: 通过Symbol函数生成,得到一个symbo ...
- CheckBox标签和属性
CheckBox的作用:可以提供复选 下面是我点击按钮查看所选内容的代码:定义按钮监听器,并在onClick方法中调用shoeAlt方法(此方法会在第二块代码定义) Button btn=(Butto ...
- Linus Torvalds正式宣布Linux Kernel 5.1RC2 发布,相当正常
导读 Linus Torvalds刚刚发布了Linux Kernel 5.2-rc2,这是继上周关闭合并窗口和随后的RC1之后的第一个内核测试版本. 在本周合并后的窗口活动中,Linus评论道,“嘿, ...
- Ajax学习系列——向服务器发送请求
1.如何发送请求? 如果需要向服务器发送请求,我们使用的是XMLHttpRequest对象中的open()和send()方法. var xhr = new XMLHttpRequest();//具体创 ...
- 剑指offer - 顺时针打印矩阵 - JavaScript
题目描述 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下 4 X 4 矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印 ...