【无线通信开发应用】nRF905数据手册深度解读

【无线通信开发应用】nRF905数据手册深度解读文章详细解析了如何使用 STM32 和 NRF905 模块通过串口进行两机通信 包括引脚定义 工作模式 SPI 通信过程及重要寄存器的使用

大家好,欢迎来到IT知识分享网。

希望通过两个stm32、两个nRF905无线通信模块、串口来实现两机通信。具体功能为:


一、功能原理

在这里插入图片描述

TRX_CE:芯片收/发的使能 CD: 载波检测 AM: 地址匹配 TX_EN: 发送/接收使能 

其中,TRX_CE 和 TX_EN 都为输入,需要 MCU 对其写入高低电平来控制 NRF905 的发送、接收模式的启动与否。CD 和 AM 都为输出,用来告诉 MCU “我检测到了空中跟我有相同载波频率的发送器了,并且它发过来的数据包也是发给我的(通过地址判断)”,主要是在接收模式下使用。
关于它们四个的具体解释如下:

  • NRF905 的工作模式
    在这里插入图片描述
    总的来说,在Power使能状态下,TRX_CE 和 TX_EN 共同控制 NRF905 的工作模式。
    在模块发送之前,需要将数据包写入到模块中,这需要通过SPI编程,故此需要将 TRX_CE 拉低;
    将 TRX_CE 和 TX_EN 都置1则设置为发送模式;
    将 TX_EN 拉低,设置为接收模式。




另外,工作模式的转换还需要遵守规定。 从待机模式切换到接收或发送模式都需要延迟一个650us的时间,这样才能够保证数据包被成功接收/发送。
在这里插入图片描述

MOSI: 主机发送从机接收 MISO: 从机发送主机接收 SCK: SPI 通信的时钟线 SCN: SPI的使能位,置0为使能 

与 MCU 进行通信。置于 SPI 的使用时序,数据手册里也有所提及,在Figure 6. 到 Figure 8,不再展示。

那么 MCU 具体是如何通过 SPI 总线与 NRF905 进行通信的呢? 发送的频率、功率、目标设备的地址、数据信息都是写入到 NRF905 的哪里呢?

  • Status – RegisterDR 标志位,当发送完一个完整的数据包(数据包的格式见下图)时或者接收到一个有效的数据包时,DR标志位置一;AM 标志位,接收模式下,当CD标志位置一后检查数据包中的地址是否和寄存器初始化时设置的本设备地址号一致,如果一致则AM标志位置一。(具体的描述见 数据手册-12 nRF905 features)
    在这里插入图片描述
    数据包中的 ADDR 和 PAYLOAD 是我们需要写入的,但是在真正发送之前,前导码和循环冗余校验会自动生成一并发送。

  • RF – Configuration Register :收发器的初始化配置,包括频率、输出功率、设备ID等。(具体的配置见下表)
    配置时需按照下表来写 RF配置寄存器的这10个字节,至于每位代表的含义需要搭配表15使用。在这里插入图片描述在这里插入图片描述
    先来大概看一下,我们需要结合Byte0和Byte1来设置发送频率、输出功率,需要Byte2来设置发送地址、接收地址的宽度,Byte5-8用来设置设备ID,最后的Byte9用来设置CRC模式等等。具体的配置待下文书写。

  • TX – Address:设置目标设备的的地址,也就是数据包中的ADDR。具体为多少个字节要在RF配置寄存器中设置。
  • TX – Payload:用来存放具体的发送信息了,具体为多少个字节要在RF配置寄存器中设置。
  • RX – Payload:用来存放具体的接收信息了,具体为多少个字节要在RF配置寄存器中设置。

现在我们知道了MCU通过SPI总线与模块的具体哪些寄存器进行读/写操作。在对具体的寄存器进行读/写操作之前,需要先发送SPI指令。

在这里插入图片描述
主要是用到三个指令:

  • WC指令。写RF配置寄存器,所以我们需要通过SPI总线写入0x00(从0位置开始)
  • WTA指令。向TX-ADDR寄存器写入目标设备的地址,需要SPI写入0x22.
  • RRP指令。读取RX-payload寄存器,接收到的有效数据包就存在这里面。需要SPI写入0x24.

二、一些函数的封装

  1. SPI写一个字节
    根据SPI时序来就好。
    在SCK低电平时,将一位数据通过MOSI放入,在SCK高电平时读取MOSI上的一位数据。经过循环移位,可以读取到一个字节的数据。
    void NRF905_SPI_Write_Byte(uint8_t data) { 
             for (uint8_t i=0; i<8; i++) { 
             if (data & (0x80 << i)) { 
             NRF905_MOSI_H; // 已宏定义,表示释放MOSI线。以下宏定义均同理 } else { 
             NRF905_MOSI_L; // 拉低MOSI线 } NRF905_SCK_H; // 释放SCK线 NRF905_SCK_L; // 拉低SCK线 } } 



  2. 写 RF – Configuration Register 配置寄存器
    上一章节中提到,配置寄存器总共有10个字节,我们一个个来看。
    在这里插入图片描述
    每一个字节都需要搭配着查找 Table 15. Configuration register description 来使用。


  • 写Byte0
    在这里插入图片描述
    查找表15,可以看到九位CH_NO加上一个HFREQ_PLL位共同才能决定工作频率。具体的频率需要查找表24:
    在这里插入图片描述
    可以看到,欲使得工作频率为433MHz,需CH_NO[7:0]=[01001100]=0x4c,CH_NO[8]=0,HFREQ_PLL=0,而这后两位都属于Byte1.
    总之,Byte0= 0x4c。




  • Byte1

在这里插入图片描述
bit[7:6]=00,AUTO_RETRAN=0(不自动重发),RX_RED_PWR=0(普通模式),PA_PWR=11(+10dBm),HFREQ_PLL=0,CH_NO[8]=0。因此,Byte1=00001100=0x0c。

  • Byte2
    在这里插入图片描述

bit[7]=0,TX_AFW[2:0]=100,bit[3]=0,RX_AFW[2:0]=100。因此,Byte2=0=0x44.

  • Byte3
    在这里插入图片描述
    bit[7:6]=0, RX_PW[5:0]=100000(32个字节的接收Buffer)。因此,Byte3=00100000=0x20.

  • Byte4
    在这里插入图片描述
    bit[7:6]=0, TX_PW[5:0]=100000(32字节的发送数据包)。因此,Byte4=00100000=0x20.

  • Byte5~Byte8
    4个字节从高到低来写设备ID。
  • Byte9
    CRC_MODE=0(8位CRC校验位),CRC_EN=1(开启CRC校验), XOF[2:0]=011(外部晶振频率16MHz), UP_CLK_EN=0,UP_CLK_FREQ[1:0]=00(输出时频)。因此,Byte9=0101 1000=0x58.
    /* 配置RF – Configuration Register */ void NRF905_Config(void) { 
           NRF905_CSN_ENABLE; // 已宏定义,使能SPI NRF905_SPI_Write_Byte(WC); // SPI指令 /* * 将配置寄存器的10个字节依次写入,代码省略 */ NRF905_CSN_DISABLE; // 失能SPI } 
  1. 写要发送的数据包
    在这里插入图片描述
    根据这个流程图来,首先将TX_EN置一、TRX_CE置零,然后通过SPI总线向TX – Address写入目标地址、向TX – Payload写入32个字节的数据,随后将TRX_CE置一,设置NRF905为发送模式。之后会根据配置寄存器的设置自动生成CRC和前导码,从而组成一个完成发送数据包。
    /* * NRF905在一般状态下长时间处于接收模式,当中断事件发生,方在回调函数中发送数据包。 */
    void SendPacket(uint32_t TxBuffer)
    { 
             
    	NRF905_TX_EN_H;
    	NRF905_TRX_CE_L;
    	delay_us(650); // 从待机模式切换到发送模式,需要650us
    	NRF905_CSN_ENABLE;
    	NRF905_SPI_Write_Byte(WTP); // Write TX-payload
    	for (uint8_t i = 0; i < 32; i++)
    	{ 
             
    		NRF905_SPI_Write_Byte(TxBuffer[i]); // 写入数据
    	}
    	NRF905_SPI_Write_Byte(WTA); 
    	for (uint8_t i = 0; i < 4; i++)
    	{ 
             
    		NRF905_SPI_Write_Byte(RF_Config[i + 5]); // 写入目标地址
    	}
    	NRF905_CSN_DISABLE;
    	NRF905_TRX_CE_H; //开启发送模式
    	
    	/* * 延时至少10us(根据Data rate,见Figure 9.TX timing) */
    	NRF905_TRX_CE_L;
    }
    



  2. 接收一个数据包
    在这里插入图片描述
    根据流程图,保证TX_EN为低,将TRX_CE置一,接收器开始检测目标频率,一旦检测到则CD标志位置一,随后再检查数据包中的ADDR与自身设备ID是否一致,一致的话AM标志位置一,对接收的数据包进行循环冗余校验,如果是有效信息则DR数据位置一。
    int main(void){          /* 许多初始化,省略。 */	NRF905_Config(); // 写RF配置寄存器,对NRF905进行初始化	NRF905_TX_EN_L;	NRF905_TRX_CE_H;	delay_us(650);		while(1)	{          		if(!binarySignal) // 一个二值信号量,常为0,当中断事件发生时变为1		{          			while(!(CD_ifH() & AM_ifH())) // CD标志位和AM标志位都置1			{          				delay_ms(100);				NRF905_TX_EN_L;				NRF905_TRX_CE_H;			}			ReceivePacket(RxBuffer);						/* 处理逻辑 */					}	}}
    void ReceivePacket(uint32_t RxBuffer){          	NRF905_CSN_ENABLE;	NRF905_TRX_CE_L;	NRF905_SPI_Write_Byte(RRP); // Read RX-payload	for (uint8_t i = 0; i < 32; i++)	{          		RxBuffer[i] = NRF905_SPI_Read_Byte();	}	NRF905_CSN_DISABLE;	NRF905_TRX_CE_L;}




本文的目的在于掌握阅读数据手册的能力,张贴的代码中包含许多伪代码,故而不能直接运行。此次阅读完英文数据手册,只觉层层递进、环环相扣、逻辑清晰。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/136338.html

(0)
上一篇 2025-06-28 13:26
下一篇 2025-06-28 13:33

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信