各位网友们好,相信很多人对nrf905无线收发模块实战教程都不是特别的了解,因此呢,今天就来为大家分享下关于nrf905无线收发模块实战教程以及nrf905无线传输模块的问题知识,还望可以帮助大家,解决大家的一些困惑,下面一起来看看吧!
本文目录一览
1、nRF905的拓展
2、您好,我需要nrf905与stc12c5608ad单片机构成的无线收发应用电路原理图及程序,求助 谢谢
nRF905的拓展
基于nRF905 模块的AT89S 单片机无线收发系统设计管脚 名称 管脚功能 说明1 VCC 电源 电源 3.3~3.6V DC2 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) itflag=DATA_BUF^7; itflag1=DATA_BUF^0;// 发送数据缓冲区 #define TxRxBuf_Len 4unsigned char TxRxBuf[TxRxBuf_Len]={0x29,0x30,0x31,0x32,};code TxAddress[4]={0xcc,0xcc,0xcc,0xcc};char tf;// NRF905工作模式控制端口 itTXEN=P2^4;//发射使能 itTRX_CE=P3^2;//发射接收使能 itPWR=P2^3;// LED显示端口 it LED=P1^0;// NRF905 数据交换端口(SPI) itMISO=P2^6;//输出 itMOSI=P2^1;//输入 itSCK=P2^5;//时钟 itCSN=P2^0;//使能// nrf905状态端口 itAM=P2^7; itDR=P3^3; itCD=P2^2;// // 按键端口 itKEY=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 11000x44, //地址宽度设置,为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到字节80x58, //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 disableSCK=0;// Spi clock pne init lowDR=1;// Init DR for inputAM=1;// Init AM for inputCD=1;// Init CD for inputPWR=1;// nRF905 power onTRX_CE=0;// Set nRF905 in standby modeTXEN=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 commandfor (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;// 关闭SPITRX_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;// 使能SPInrf905_Delay(1);SpiWrite(RRP); //准备读取接收到的数据for (i = 0 ;i < 4 ;i ){TxRxBuf[i]=SpiRead();// 通过SPI接口从905芯片读取数据}CSN=1;//禁用SPInrf905_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;}}}
您好,我需要nrf905与stc12c5608ad单片机构成的无线收发应用电路原理图及程序,求助 谢谢
/******************************************************************************************\ 说明:看到网上好所人问51单片机 nRF905射频通信问题,所以将自己之前初学时写得测试代码贴出来,供初学者参考。 双工的,既能收也能发。可以通过按钮控制另一块板上的小灯亮灭(按住亮,松开灭), 也可将串口收到的数据通过无线方式发送出去,(发送1、2时也可控制LED灯亮),也可将收到的无线信号通过串口输出,日期:2012年4月23日硬件:单片机型号:STC89C52RC,晶振11.0592M,射频芯片通过10根导线与单片机IO口连接 射频芯片nRf905,模块自带天线长度约10cm,发射频率433M,频道1 其他外设:2个按键,2个led灯,一个串口功能:用于测试nRF905,可通过串口发送接收, 率9600,也可通过按键发送,led显示核心函数:Init905() RxPacket() TxPacket()/*******************************************************************************************///#include <reg9e5.h>//#include "ISD51.h"#include<reg52.h>#include <intrins.h>#include<stdpb.h>#include<string.h>#define INT8U unsigned char #define INT16U unsigned int#define TIMER1 0XFD //256 (110592/(12*32*96))//*****************************************************************************//寄存器宏定义//*****************************************************************************#define WRC 0x00 //W_RF_CONFIG#define RRC 0x10 //R_RF_CONFIG#define WTP 0x20 //W_TX_PAYLOAD#define RTP 0x21 //R_TX_PAYLOAD#define WTA 0x22 //W_TX_ADDRESS#define RTA 0x23 //R_TX_ADDRESS#define RRP 0x24 //R_RX_PAYLOAD#define RAD 0x40 //R_ADC_DATA #define WAC 0x44 //W_ADC_CONFIG#define RAC 0x46 //R_ADC_CONFIG#define WTU 0x50 //W_TEST_UNLOCK (use with data A5)#define WTR 0x52 //W_TEST_REGISTER#define RTR 0x53 //R_TEST_REGISTER#define CC 0x80 //CHANNEL_CONFIG#define SAV 0xC0 //START_ADC_CONV#define HFREQ 1 // 0=433MHz, 1=868/915MHz 19/08/2004 set 915mhz#define POWER 3 // 0=min power...3 = max power///////////////////////////////////////////////////////////////////////////////#define RFLEN 32 //数据长度,最大32INT8U data UartRecCnt=0; //串口接收计数#define do_uart() if(UartRecCnt<RFLEN 1){TxBuf[UartRecCnt ]=SBUF; } //串口中断处理宏INT8U RxBuf[RFLEN]={0}; //接收数据缓冲区INT8U TxBuf[RFLEN]={0}; //发送数据缓冲区//********定义与9e5不一样******************************************************//I/O口定义//***************************************************************************** it LED1 =P1^0; it LED2 =P1^1; it LED3= P1^2; it LED4= P1^3; it KEY1 =P1^6; it KEY2 =P1^7;/////////定义与9e5不一样////////////////////////////////////////////////////// it TX_EN = P0^0; it TRX_CE = P0^1; it POW_UP = P0^2; it CD = P0^3; it AM = P0^4; it DR = P0^5; it MISO = P0^6; it MOSI = P0^7; it SCK = P2^0; it CE_905 = P2^1;
//*****************************************************************************//配置寄存器//*****************************************************************************code INT8U Nrf905Config[10] = { 0x28, //频道设置 // 0x0e, //自动重发关,发送节电模式关,输出功率10dB,915MHZ 0x0c, //自动重发关,发送节电模式关,输出功率10dB,433MHZ 0x44, //收发地址都为4字节 RFLEN,// 0x04, //接收数据长度,4字节 RFLEN,// 0x04, //发送数据长度,4字节 0xe7, //4字节地址 0xe7, 0xe7, 0xe7, // 0xdf //CRC开,16位校验,16M晶振,外部时钟使能500KHZ输出 0x58 //CRC开,8位校验,16M晶振,禁止外部时钟 };///////////////////////////////////////////////////////////////////////////////
//*****************************************************************************//函数名:void Delay(INT8U n)//输入:时间//输出:无//功能描述:廷时100us//*****************************************************************************void Delay(INT8U n){ INT8U i; while(n ) for(i=0;i<40;i ); //for(i=0;i<35;i );}
//***************************** 该函数与nRF9e5不同 ****************************//函数名:INT8U SpiReadWrite(INT8U b)//输入:发送的数据//输出:收到的数据//功能描述:SPI发送接收一个字节//***************************************************************************** INT8U SpiReadWrite(INT8U dat){ INT8U i,temp; temp = 0; SCK = 0; for(i=0; i<8; i ) { if(dat & 0x80) { MOSI = 1; } else MOSI = 0; dat <<= 1;
SCK = 1; _nop_(); _nop_();
temp <<= 1; if(MISO)temp ; SCK = 0; _nop_(); _nop_(); } return temp;} //***************************** 该函数与nRF9e5不同 ****************************//函数名:void InitCpu(void)//输入:无//输出:无//功能描述:Cpu初始化//***************************************************************************** void InitCpu(void){ LED2=0; LED1=0; Delay(10);} //***************************** 该函数与nRF9e5不同 ****************************//函数名:InitUart(void)//输入:无//输出:无//功能描述:串口初始化//***************************************************************************** void InitUart(void){ SCON = 0x50; //串口方式1,允许接收 TMOD = 0x21; //定时器1工作方式2,定时器0工作方式1 TH1 = TIMER1; TL1 = TIMER1; TR1 = 1; //启动定时器1 ES = 1; EA = 1;}//*****************************************************************************//函数名:void SendCh(INT8U c)//输入:发送的数据//输出:无//功能描述:发送一个字节//*****************************************************************************void SendCh(INT8U c){// EA = 0;// TI = 0; SBUF = c; while(!TI);//等待发送完成 TI = 0;// EA = 1;}/*******************************************************************************************///发送字符串到串口void SendStr(INT8U *p){ while(*p!='\0') { SBUF=*p; //待发送的数据写入缓冲区 while(!TI); //等待发送完成 TI=0; //清零发送标志位 p ; //指针加1 } } /*****************************************************************************//函数名:void Init905(void)//输入:无//输出:无//功能描述:Nrf905初始化,这里我们配置成32位地址。//******************************************************************************/void Init905(void){ INT8U i; POW_UP = 1; //905上电 //Delay(200); SCK = 0; // Spi clock pne init high TRX_CE=0; TX_EN=0; //配置模式
CE_905 = 0; SpiReadWrite(WRC); for(i=0; i<10; i ) { SpiReadWrite(Nrf905Config[i]); //写入配置寄存器 } CE_905 = 1;}
//*****************************************************************************//函数名:Tran itPacket(INT8U *pBuf)//输入:发送的数据//输出:无//功能描述:发送发送缓冲区的数据//*****************************************************************************void Tran itPacket(INT8U *pBuf){ INT8U i; CE_905 = 0; SpiReadWrite(WTP); for(i=0; i<Nrf905Config[4]; i ) { SpiReadWrite(pBuf[i]);//写入发送数据缓冲区 } CE_905 = 1; TX_EN = 1; TRX_CE = 1; //使能发送 Delay(1); TRX_CE = 0;}//*****************************************************************************//函数名:INT8U Recepacket(INT8U *pBuf)//输入:接收数据缓冲区//输出:成功返回1,否则返回0//功能描述:接收数据存在缓冲区内//*****************************************************************************INT8U Recepacket(INT8U *pBuf){ INT8U i; TX_EN = 0;TRX_CE = 1; //进入接收模式 if(!DR)return 0; //查询DR的状态 //原始代码采用的是等待超时的方法/* ResetTimer(1);//复位超时计数器。 while(DR == 0)//有收到切换到空闲状态时退出接收状态。 { if(ReadTimer(1) > 300)//300MS超时退出。 { TRX_CE = 0; return 0; } }*/ TRX_CE = 0; // Set nRF905 in standby mode CE_905 = 0; // Spi enable for write a spi command SpiReadWrite(RRP);// Read payload command for(i=0; i<Nrf905Config[3]; i )//读出数据。 { pBuf[i] = SpiReadWrite(0); } while(DR);//直到DR为高。/* { SpiReadWrite(0); }*/ CE_905 = 1; return 1; } /*串口接收中断函数*/void int_rec(void) interrupt 4 using 2{ if(RI) //查询接收标志位(有数据发送过来时置为1) { RI = 0; //接收标志位清零 //SendCh(SBUF);//让从电脑上传到单片机的数据,传回的电脑显示 do_uart();//对接受到得字符操作 }}/************************************************************************///功能:把串口接收的数据通过无线发射出去//采取延时读取串口接收计数的方法,判读串口发送数据是否完毕,提高发送效率void UartToRf(void ){ INT8U Tmp=0; //临时变量,暂存UartRecCnt do { Tmp=UartRecCnt; Delay(5); //延时,等待 } while(Tmp!=UartRecCnt); //判段来自串口的字符串是否发送完毕
Tran itPacket(TxBuf); //通过射频发送 memset(TxBuf,0,UartRecCnt); //清空缓冲区 UartRecCnt=0; // 串口接受计数清零 }
//载波监听发送,重试3次,仍失败不发送unsigned char CDSend(void){ unsigned char i=0; do { if(!CD) //载波监听 { Tran itPacket(TxBuf);//发送数据 return 0; //发送成功,返回0 } SendCh(0x30 i); Delay(rand()&0x0f);//随机延时 LED3=~LED3; }while( i<3); //最多3次 SendStr("fail"); return 1; //发送失败,返回1 }
/***********************主程序*************************************************/main(){ Init905(); //初始化Nrf905 InitCpu(); //初始化CPU// InitTimer(); InitUart(); //初始化串口。 LED2 = 1; LED1 = 1; //两个LED灭。 //SendCh('R'); while(1) { LED2=1; LED1=1; if(KEY1 == 0) //按键1按下 { TxBuf[0] = 0x31; //Tran itPacket(TxBuf);//发送数据 CDSend(); } if(KEY2 == 0) //按键2按下 { TxBuf[0] = 0x32; //Tran itPacket(TxBuf);//发送数据 CDSend(); } if(Recepacket(RxBuf)) //接收到数据。 { if(RxBuf[0] == 0x31) { LED1 = 0; Delay(5); } else if(RxBuf[0] == 0x32) { LED2 = 0; Delay(5); } SendStr(RxBuf); //将从无线收到的数据发到串口 } if(UartRecCnt) //串口收到数据时相应处理 { /*Delay(2*RFLEN); //延时,等待字符串发送完毕.时间过短的话会出现串口数据未发完,缓冲区已情况的情况 Tran itPacket(TxBuf); //通过射频发送 memset(TxBuf,0,UartRecCnt); //清空缓冲区 UartRecCnt=0; // 串口接受计数清零 */ UartToRf(); //新编发送函数 } }}//end