打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
nRF905

基于nRF905 模块的AT89S 单片机无线收发系统设计

管脚 名称 管脚功能 说明

1 VCC 电源 电源+3.3~3.6V DC

2 TX_EN 数字输入 工作模式选择

3 TRX_CE 数字输入 使能芯片发射或接收

4 PWR_UP 数字输入 芯片上电

5 uCLK 时钟输出 (未使用)

6 CD 数字输出 载波检测

7 AM 数字输出 地址匹配

8 DR 数字输出 接收或发射数据完成

9 MISO SPI 接口 SPI 输出

10 MOSI SPI 接口 SPI 输入

11 SCK SPI 时钟 SPI 时钟

12 CSN SPI 使能 SPI 使能

13、14 GND 地 接地

下面为典型的 nRF905 模块数据发送流程[3]:

(1)当微控制器要发送数据时,将接收机的地址和发

送数据通过SPI 接口传输给nRF905 模块;

(2)微控制器设置TRX_CE 和TX_EN 管脚同时置为

高电平,启动发送端的nRF905 模块为发送模式;

(3)发送端的nRF905 模块发送过程处理:

a)射频寄存器开启;

b)数据打包(加字头和CRC 校验码);

c)数据包发送;

d)当数据包发送结束,将数据发送完成管脚(DR 管脚)

置为高电平;

(4)如果AUTO_RETRAN 被设置为高,nRF905 模块

将连续地发送数据包,直到TRX_CE 被设置为低;

(5)TRX_CE 被设置为低时,nRF905 模块数据包发送

过程结束并回到待机模式。

AT89S单片机控制nRF905 模块数据发送流程图如图3

所示。

下面为典型的 nRF905 模块数据接收流程[4]:

(1)微控制器控制TRX_CE 为高电平、TX_EN 为低电

平,nRF905 模块进入接收模式;

(2)650us 后,nRF905 模块监测空中的信息,等待接

收数据;

(3)当nRF905 模块检测到与接收频率相同的载波时,

设置载波检测管脚(CD 管脚)为高电平;

(4)当nRF905 模块接收到有效的地址时,设置地址匹

配管脚(AM 管脚)为高电平;

(5)当一个正确的数据包接收完毕后,nRF905 模块自

动去掉数据包的字头、地址和CRC 校验码,然后将数据接

受完成管脚置为高电平;

(6)微控制器将TRX_CE 设置为低电平;

(7)微控制器通过SPI 接口以一定的速率提取数据包

中的有效接收数据;

(8)当所有的有效数据接收完毕,微控制器控制nRF905

模块数据接收完成管脚(DR 管脚)和地址匹配管脚(AM

管脚)为低电平;

(9)nRF905 进入待机模式。

说明:(1)VCC电压范围为DC 3.3V~3.6V之间,不能超过3.6V否则会烧坏模块。

(2)模块

附加更加详细的收发程序,包括解释:

////////////////////////////////////////////整体参数////////////////////////////////////////////////////

//NewMsg-RF905-共有四种工作模式,其中有两种活动RX/TX模式和两种节电模式。

//活动模式

// ShockBurst RX

//ShockBurst TX

//节电模式

//掉电和SPI编程

//工作模式:

//┏━━━━┳━━━━┳━━━━┳━━━━━━━━━━━━━━━━┓

//┃PWR UP ┃ TRX CE ┃ TX_EN ┃工作模式 ┃

//┣━━━━╋━━━━╋━━━━╋━━━━━━━━━━━━━━━━┫

//┃0 ┃ x ┃ x ┃掉电和SPI编程 ┃

//┣━━━━╋━━━━╋━━━━╋━━━━━━━━━━━━━━━━┫

//┃1 ┃ 0 ┃ x ┃ Standby和SPI编程 ┃

//┣━━━━╋━━━━╋━━━━╋━━━━━━━━━━━━━━━━┫

//┃1 ┃ 1 ┃ O ┃ShockB urst RX ┃

//┣━━━━╋━━━━╋━━━━╋━━━━━━━━━━━━━━━━┫

//┃ 1 ┃ l ┃ 1 ┃ShockBurst T X ┃

//┗━━━━┻━━━━┻━━━━┻━━━━━━━━━━━━━━━━?

//ShockBurst TX发送流程:

//典型的RF905发送流程分以下几步:

//A.当微控制器有数据要发送时,通过SPI接口,按时序把接收机的地址和要发送的数据送传给RF905,

//SPI接口的速率在通信协议和器件配置时确定;

//B.微控制器置高TRX_CE和TX_EN,激发RF905的ShockBurs发送模式;

//C.RF905的ShockBurs tTMI发送:

//(1)射频寄存器自动开启;

//(2)数据打包(加字头和CRC校验码);

//(3)发送数据包;

//(4)当数据发送完成,数据准备好引脚被置高;

//D.AUTO_REI'RAN被置高,RF905不断重发,直到TRX_CE被置低;

//E.当TRX-CE被置低,RF905发送过程完成,自动进入空闲模式。

//注意:ShockBurs tTM工作模式保证,一旦发送数据的过程开始,无

// 论TRX_EN和TX-EN引脚是高或低,发送过程都会被处理完。只有

// 在前一个数据包被发送完毕,RF905才能接受下一个发送数据包

//ShockBurst RX接收流程

// 接收流程

//A.当TRX_CE为高、TX_EN为低时,RF905进入ShockBurs tTM接收模式;

//B.650us后,RF905不断监测,等待接收数据;

//C.当RF905检测到同一频段的载波时,载波检测引脚被置高;

//D.当接收到一个相匹配的地址,AM引脚被置高;

//E.当一个正确的数据包接收完毕,RF905自动穆去字头、地址和CRC

// 校验位,然后把DR引脚置高

//F.微控制器把TRX_CE置低,nRF905进入空闲模式;

//G.微控制器通过SPI口,以一定的速率把数据穆到微控制器内;

//H.彼?械氖?萁邮胀瓯希琻RF905把DR引脚和AM引脚置低;

//当正在接收一个数据包时,TRX_CE或TX_EN引脚的状态发生改变,

//RF905立即把其工作模式改变,数据包则丢失。当微处理器接到AM

//引脚的信号之后, 其就知道RF905正在接收数据包,其可以决定是

//让RF905继续接收该数据包还是进入另一个工作模式。

///////节能模式

//RF905的节能模式包括关机模式和节能模式。

//在关机模式,RF905的工作电流最小,一般为2.SuA。进入关机模

//式后,RF905保持配置字中的内容,但不会接收或发送任何数据。空

//闲模式有利于减小工作电流,其从空闲模式到发送模式或接收模式的

//启动时间也比较短。在空阑模式下,RF905内部的部分晶体振荡器处

//于工作状态?

//五、配置NeWMsg-RF905模块

//所有配置字都是通过SPlI接口送给RF905。SIP接口的工作方式可

//通过SPlI指令进行设置。当RF905处于空闲模式或关机模式时,SPI

//按口可以保持在工作状?

//SPI寄存器配置

//SPI接口由5个内部寄存器组成。执行寄存器的回读模式来确认寄存器的内容。

//状态寄存器(Status-Register)

//寄存器包含数据就绪(DR)和地址匹配(AM)状态。

//RF配置寄存器(RF-Configuration Register)

//寄存器包含收发器的频率,输出功率等配置信息。

//发送地址(IX-Address)

//寄存器包含目标器件地址,字节长度由配置寄存器设置。

//发送有效数据( IX-Payload)

//寄存器包含发送的有效ShockBurst数据包数据,字节长度由配置寄存器设置。

//接收有效数据( IX-Payload)

//寄存器包含接收到的有效ShockBurst数据包数据,字节长度由配置寄存器设置。在寄存器中的有效数据由

//数据准备就绪(DR)指荆

//SPI指令设置

//用于SPI接口的有用命令见下表。当CSN为低时,SPI接口开始等待一条指令,任何一条新指令均由CSN

//的由高到低的转换开始。

//┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓

//┃ SPI串行接口指令 ┃

//┣━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫

//┃指令名称 ┃指令格式 ┃操作 ┃

//┣━━━━━━╋━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫

//┃W CONFIG ┃ OOOOAAAA ┃写配置寄存器。AAAA指出写操作的开始字节,字节数量取决于 ┃

//┃(WC) ┃ ┃AAAA指出的开始地址。 ┃

//┣━━━━━━╋━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫

//┃R CONFIG ┃ OOOIAAAA ┃读配置寄存器。AAAA指出读操作的开始字节,字节数量取决于 ┃

//┃(RC) ┃ ┃AAAA指出的开始地址。 ┃

//┣━━━━━━╋━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫

//┃W TX PAYLOA ┃ 00100000 ┃写TX有效数据:1-32字节。写操作全部从字节o开始。 ┃

//┃D ┃ ┃ ┃

//┃(WTP) ┃ ┃ ┃

//┣━━━━━━╋━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫

//┃R TX PAYLOA ┃ 00100001 ┃读TX有效数据:1-32字节。读操作全部从字节o开始。 ┃

//┃D ┃ ┃ ┃

//┃(RTP) ┃ ┃ ┃

//┣━━━━━━╋━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫

//┃W TX ADDRES ┃00100010 ┃写TX地址:1-4字节。写操作全部从字节o开始 ┃

//┃S ┃ ┃ ┃

//┃(WTA) ┃ ┃ ┃

//┣━━━━━━╋━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫

//┃R TX ADDRES ┃0010001 1 ┃读TX地址:1-4字节。读操作全部从字节o开始。 ┃

//┃S ┃ ┃ ┃

//┃(RTA) ┃ ┃ ┃

//┣━━━━━━╋━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫

//┃R RX PAYLOA ┃ 001 001 00 ┃读RX有效数据:1-32字节。读操作全部从字节o开始。 ┃

//┃D ┃ ┃ ┃

//┃(RRP) ┃ ┃ ┃

//┣━━━━━━╋━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫

//┃CHANNEL CON ┃lOOOpphc ┃快速设置配置寄存器中CH NO,HFREQ_PLL和PA PWR的专用 ┃

//┃FIG ┃cccccccc ┃命令_ CH NO=ccccccccc: HFREQ_PLL=h: PA_PWR=pp ┃

//┃(CC) ┃ ┃ ┃

//┗━━━━━━┻━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━タ

#include <reg52.h>

//#include <ABSACC.h>

//#include <intrins.h>

//#include <stdio.h>

////----------------------------------------------------------------------------------------------------------------

#define uint unsigned int

#define uchar unsigned char

//----------------------------------------------------------------------------------------------------------------

#define BYTE_BIT00x01

#define BYTE_BIT1 0x02

#define BYTE_BIT2 0x04

#define BYTE_BIT3 0x08

#define BYTE_BIT4 0x10

#define BYTE_BIT5 0x20

#define BYTE_BIT6 0x40

#define BYTE_BIT70x80

//----------------------------------------------------------------------------------------------------------------

bdata unsigned char DATA_BUF;//可位寻址的片内RAN

#define DATA7((DATA_BUF&BYTE_BIT7) != 0)

#define DATA0 ((DATA_BUF&BYTE_BIT0) != 0)

sbitflag=DATA_BUF^7;

sbitflag1=DATA_BUF^0;

//------------------------------------ 发送数据缓冲区-------------------------------------------------

#define TxRxBuf_Len 4

unsigned char TxRxBuf[TxRxBuf_Len]={0x29,0x30,0x31,0x32,};

code TxAddress[4]={0xcc,0xcc,0xcc,0xcc};

char tf;

//----------------------------------------NRF905工作模式控制端口------------------------------------------------------

sbitTXEN=P2^4;//发射使能

sbitTRX_CE=P3^2;//发射接收使能

sbitPWR=P2^3;

//----------------------------------------LED显示端口---------------------------------------------------

sbit LED=P1^0;

//----------------------------------------NRF905 数据交换端口(SPI)---------------------------------------------------

sbitMISO=P2^6;//输出

sbitMOSI=P2^1;//输入

sbitSCK=P2^5;//时钟

sbitCSN=P2^0;//使能

//----------------------------------------nrf905状态端口---------------------------------------------------------

sbitAM=P2^7;

sbitDR=P3^3;

sbitCD=P2^2;

//---------------------------------------------------------------------------------------------------------------

//----------------------------------------按键端口-------------------------------------------------------

sbitKEY=P3^7;

//---------------------nrf905控制指令-------------------------------------------

#define WC0x00 //写配置寄存器

#define RC0x10 //读配置寄存器

#define WTP0x20 //向TX-Payload寄存器写入发送有效数据

#define RTP0x21 //向TX-Payload寄存器读取发送有效数据

#define WTA0x22 //向TX-Addtess寄存器写入发送地址

#define RTA0x23 //向TX-Addtess寄存器读取发送地址

#define RRP0x24 //从RX-Payload寄存器读取接收到的有效数据

//------------------------------------------NRF905寄存器配置------------------------------------------------

unsigned char idata RFConf[11]=

{

0x00, //配置命令//

0x4c, //CH_NO,配置频段在430MHZ字节0,配置频段

0x0c, //输出功率为10db,不重发,节电为正常模式 字节1,000 1100

0x44, //地址宽度设置,为4字节字节2,6:4 是TX地址宽度, 2:0是RX地址宽度

0x04,0x04, //接收发送有效数据长度为4字节字节3(RX),字节(TX):可设置为1,2,4,8,16,32 字节,其中6,7 两位为空,写00,则4字节为:0000 0100 : 0x04 依次类推

0xCC,0xCC,0xCC,0xCC, //接收地址字节5到字节8

0x58, //CRC充许,8位CRC校验,外部时钟信号不使能,16M晶振 字节9,

};

//================================================延时===========================================================

void nrf905_Delay(int n)

{

uint i;

while(n--)

for(i=0;i<80;i++);

}

//=================================================SPI读函数=======================================================

//步骤一:MISO线准备好需要发送的数据位

//步骤二:SCK置高,主机读取MISO线上的数据

//步骤三:SCK置低,准备接收数据的下一位

// 以上步骤循环执行8次,通过SPI从器件上读取数据完成!

//数据传送时候。高位在前,低位在后。

unsigned char SpiRead(void)

{

unsigned char j;

for (j=0;j<8;j++)

{

DATA_BUF=DATA_BUF<<1;

SCK=1;

if (MISO)//读取最高位,保存至最末尾,通过左移位完成整个字节

{

DATA_BUF|=BYTE_BIT0;

}

else

{

DATA_BUF&=~BYTE_BIT0;

}

SCK=0;

}

return DATA_BUF;

}

//===========================================SPI写函数===============================================================

//步骤一:MOSI线准备好需要发送的数据位

//步骤二:SCK置高,器件读取MOSI线上的数据

//步骤三:SCK置低,准备发送数据的下一位

// 以上步骤循环执行8次,通过SPI从器件上发送数据完成!

//数据传送时候。低位在前,高位在后。

void SpiWrite(unsigned char send)

{

unsigned char i;

DATA_BUF=send;

for (i=0;i<8;i++)

{

if (DATA7)//总是发送最高位

{

MOSI=1;//SPI输入,主机写操作

}

else

{

MOSI=0;

}

SCK=1;

DATA_BUF=DATA_BUF<<1;

SCK=0;

}

}

//--------------------------------------初始化nRF905---------------------------------------------

void nRF905Init(void)

{

CSN=1;// Spi disable

SCK=0;// Spi clock line init low

DR=1;// Init DR for input

AM=1;// Init AM for input

CD=1;// Init CD for input

PWR=1;// nRF905 power on

TRX_CE=0;// Set nRF905 in standby mode

TXEN=0;// set radio in Rx mode

}

//-----------------------------------------------------初始化寄存器-----------------------------------------------

//步骤一:CSN置低电平,SPI接口开始等待第一条命令

//步骤二:调用SpiWrite函数,向nrf905发送WC指令,准备写入配置信息

//步骤三:反复调用SpiWrite函数,向器件配置寄存器写入配置信息

//步骤四:CSN置高电平,结束SPI通讯。即nrf905配置完成!

void Config905(void)

{

uchar i;

CSN=0;// CSN片选信号,SPI使能

//SpiWrite(WC);// 向905芯片写配置命令

for (i=0;i<11;i++)// 循环写入配置信息

{

SpiWrite(RFConf[i]); //RxTxConf保存预先设置好的配置信息

}

CSN=1;// 结束SPI数据传输

}

//-------------------------------发送数据打包---------------------------------------------------

//步骤一:通过SpiWrite函数发送WTP命令,准备写入TX有效数据

//步骤二:循环调用SpiWrite向TX-Payload寄存器写入有效数据(中间必须夹有CSN电平变化)

//步骤三:延时

//步骤四: 通过SpiWrite函数发送WTA命令,准备写入TX地址

//步骤五:循环调用SpiWrite向TX-Address寄存器写入TX地址

//步骤六:TRC_CE=1;开始发送数据,延时,nrf905数据发送完成,

//当nrf905接收到一条完成的信息时,会将DR引脚置高。

void TxPacket(uchar *TxRxBuf)

{

uchar i;

//Config905();

CSN=0;

SpiWrite(WTP);// Write payload command

for (i=0;i<4;i++)

{

SpiWrite(TxRxBuf[i]);// 写入32直接发送数据

}

CSN=1;

nrf905_Delay(1);// 关闭SPI,保存写入的数据

CSN=0;// SPI使能,保存写入的数据

SpiWrite(WTA);// 写数据至地址寄存器

for (i=0;i<4;i++)// 写入四字节地址 写入与对方地址一样的地址

{

SpiWrite(TxAddress[i]);

}

CSN=1;// 关闭SPI

TRX_CE=1;// 进入发送模式,启动射频发送

nrf905_Delay(1);//进入ShockBurst发送模式后,芯片保存数据

TRX_CE=0;// 发送完成后返回ATANDBY模式 while (DR!=1);

}

//----------------------------------------------设置发送初始状态---------------------------------------------

void SetTxMode(void)

{

TRX_CE=0;

TXEN=1;

nrf905_Delay(1); // nrf905_Delay for mode change(>=650us)

}

//步骤一:TRX_ce=0;必须将次引脚置低,使905进入standby模式

//步骤二:发送RRP指令

//步骤三:循环调用SpiWrite函数,读取接收到的数据

//步骤四:等待DR和AM引脚复位为低电平

// AM 地址匹配,接收到有效地址,被置高

// DR 接收到有效数据包,并解码后,被置高,当所有有效数据被读取后,

// nrf905降AM和DR置低,最后需要注意的是,必须首先设置器件的

// 发送/接收模式才能保证有效的数据发生接收

//-----------------------------------------------设置nrf905进入接收模式---------------------------------------------------

void SetRxMode(void)

{

TXEN=0;

TRX_CE=1;

nrf905_Delay(1); // nrf905_Delay for mode change(>=650us)

}

//-------------------------------------判断数据接收状态-----------------------------------------------------

unsigned char CheckDR(void)//检查是否有新数据传入 Data Ready

{

DR=1;

//通过对端口写1,可以使端口为输入状态,这51的 特性。不熟悉者可以参阅51相关书籍作证(将DR端口设置为输入状态。)

if (DR==1)

{

DR=0;

return 1;

}

else

{

return 0;

}

}

//----------------------------NRF905接收到数据后读取保存------------------------------------------------------------

void RxPacket(void)

{

uchar i;

nrf905_Delay(1);

//TRX_CE=0;// 设置905进入待机模式

nrf905_Delay(100);

TRX_CE=0;

CSN=0;// 使能SPI

nrf905_Delay(1);

SpiWrite(RRP); //准备读取接收到的数据

for (i = 0 ;i < 4 ;i++)

{

TxRxBuf[i]=SpiRead();// 通过SPI接口从905芯片读取数据

}

CSN=1;//禁用SPI

nrf905_Delay(10);

TRX_CE=1;

}

//--------------------------------------------------------数据接收------------------------------------------------

void RX(void)

{

SetRxMode();

// while (CheckDR()==0); 为了实现双向通信,就不能一直处于接收等待状态,所以注释掉

nrf905_Delay(10);

RxPacket();

if(TxRxBuf[0]==0x29)

{

LED=0;

nrf905_Delay(300);

LED=1;

nrf905_Delay(300);//接收到数据 后闪烁

}

}

//-----------------------------------------------------------------------------------------------------------------

void main(void)

{

nRF905Init();

Config905();

LED=1;

while(1)

{

RX();

if(KEY ==0 )

{

while(KEY==0);

tf = 1 ;

TxRxBuf[0]=0x29;

}

if (tf==1)

{

SetTxMode();

TxPacket(TxRxBuf);// 发送命令数据

LED=0;

nrf905_Delay(300);

LED=1;

nrf905_Delay(300);//发送后LED闪烁

tf = 0;

}

}

}

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
NRF24L01 MSP430发送接收程序
nrf24l01中文资料
调试51+nrf905无线模块,可以保证稳定的收发,正在完善中。。 (www.ouravr...
用89C51驱动nRf905收发C源代码
Linux下驱动2.4G无线模块(NRF24L01) - jammy_lee的日志 - 网...
STC89C52 STC89LE52 NRF24L01无线 教程 (一)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服