性能參數
◆422.4~473.5MHz工作頻段
◆512個通訊頻道,滿足多點通訊、分組、跳頻等套用需求,通道切換時間≤6us
◆發射功率可設定為:10dBm、6dBm、-2dBm和-10dBm
◆通過SPI接口與MCU連線
◆支持50kbps傳輸速率
◆ShockBurst傳輸模式,自動生成前導碼和CRC校驗碼
◆工作電壓範圍:1.9V~3.6V,待機模式下電流僅為12.5μA
◆工作溫度範圍:-40℃~+85℃
工作模式
nRF905採用Nordic公司的VLSI ShockBurst技術。ShockBurst技術使nRF905能夠提供高速的數據傳輸,而不需要昂貴的高速MCU來進行數據處理/時鐘覆蓋。通過將與RF協定有關的高速
信號處理放到晶片內,nRF905提供給套用的微控制器一個SPI接口,速率由微控制器自己設定的接口速度決定。nRF905通過ShockBurst工作模式在RF以最大速率進行連線時降低數字套用部分的速度來降低在套用中的平均電流消耗。在ShockBurst RX模式中,地址匹配AM和數據
準備就緒DR信號通知MCU一個有效的地址和
數據包已經各自接收完成。在ShockBurst TX模式中,nRF905自動產生前導碼和CRC校驗碼,數據準備就緒DR信號通知MCU數據傳輸已經完成。總之,這意味著降低MCU的存儲器需求也就是說降低MCU成本,又同時縮短軟體開發時間。
1)典型ShockBurst TX模式:
①、當套用MCU有遙控數據
節點時,接收節點的地址TX-address和有效數據TX-payload通過SPI接口傳送給nRF905套用協定或MCU設定接口速度;
②、MCU設定TRX_CE、TX_EN為高來激活nRF905 ShockBurst傳輸;
③、nRF905 ShockBurst:
無線系統自動上電
數據包完成(加前導碼和CRC校驗碼)
④、如果AUTO_RETRAN被設定為高nRF905將連續地傳送數據包直到TRX_CE被設定為低;
⑤、當TRX_CE被設定為低時,nRF905結束數據傳輸並自動進入standby模式。
2)典型ShockBurst RX模式
①、通過設定TRX_CE高,TX_EN低來選擇ShockBurst模式;
②、650us以後,nRF905監測空中的信息;
③、當nRF905發現和接收頻率相同的載波時,載波檢測CD被置高;
④、當nRF905接收到有效的地址時,地址匹配AM被置高;
⑤、當nRF905接收到有效的數據包(CRC校驗正確)時,nRF905去掉前導碼、地址和CRC位,數據準備就緒(DR)被置高;
⑥、MCU設定TRX_CE低,進入standby模式低電流模式;
⑦、MCU可以以合適的速率通過SPI接口讀出有效數據;
⑧、當所有的有效數據被讀出後,nRF905將AM和DR置低;
⑨、nRF905將準備進入ShockBurst RX、ShockBurst TX或Powerdown模式。
3)掉電模式
在掉電模式中,nRF905被禁止,電流消耗最小,典型值低於2.5uA。當進入這種模式時,nRF905是不活動的狀態。這時候平均電流消耗最小,電池使用壽命最長。在掉電模式中,配置字的內容保持不變。
4)STANDBY模式
Standby模式在保持電流消耗最小的同時保證最短的ShockBurstRX、ShockBurstTX的啟動時間。當進入這種模式時,一部分晶體振盪器是活動的。電流消耗取決於晶體振盪器頻率,如:當頻率為4MHZ時,IDD=12uA;當頻率為20MHZ 時,IDD=46uA。如果uPCLK(Pin3)被使能,電流消耗將增加。並且取決於負載電容和頻率。在此模式中,配置字的內容保持不變。
器件配置
nRF905的所有配置都通過SPI接口進行。SPI接口由5個
暫存器組成,一條SPI指令用來決定進行什麼操作。SPI接口只有在掉電模式和Standby模式是激活的。
暫存器包含數據就緒DR和地址匹配AM狀態。
2)RF配置暫存器(RF-Configuration Register)
暫存器包含收發器的頻率、輸出功率等配置信息。
3)傳送地址(TX-Address)
暫存器包含目標器件地址,位元組長度由配置暫存器設定。
4)傳送有效數據(TX-Payload)
暫存器包含傳送的有效ShockBurst數據包數據,位元組長度由配置暫存器設定。
5)接收有效數據(RX-Payload)
暫存器包含接收到的有效ShockBurst數據包數據,位元組長度由配置暫存器設定。在暫存器中的有效數據由數據準備就緒DR指示。
套用領域
● 超低功耗無線收發器
● 無線感測網路
● 家庭和樓宇自動化
● 無線報警安全系統
●無線數據傳輸系統
●報警及安全系統
●家庭自動化
●遙感監測
●無線門禁系統
●無線滑鼠
●遙控開鎖
●遙控玩具
程式
傳送部分
/****************************
//寫發射數據命令:20H
//讀發射數據命令:21H
//寫發射地址命令:22H
//讀發射地址命令:23H //讀接收數據命令:24H
******************************/
#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit TXEN = P2^7; //配置口定義5`6`7//
sbit TRX_CE = P2^6;
sbit PWR = P2^5;
sbit MISO = P2^2; //SPI口定義0`1`2`3//
sbit MOSI = P2^3;
sbit SCK = P2^1;
sbit CSN = P2^0;
sbit DR = P2^4; //狀態輸出口4//
sbit led=P1^0;
/************//*RF
暫存器配置*//*************
// 0x00, //配置命令//
// 0x6C, //CH_NO,配置頻段在433.2MHZ
// 0x0E, //輸出功率為10db,不重發,節電為正常模式
// 0x44, //地址寬度設定,為4位元組
// 0x03,0x03, //接收傳送有效數據長度為3位元組
// 0xE7,0xE7,0xE7,0xE7,//接收地址,16位CRC校驗,外部
時鐘信號使能,16M晶振//UP_CLK輸出1MHZ頻率
// 0xDE, //CRC充許
//******************************/
/*uchar code RFConf[11]={0x00,0x6c,0x0e,0x44,0x03,0x03,
0xe7,0xe7,0xe7,0xe7,0xde};
*/
uchar RFConf[11]=
{
0x00, //配置命令//
0x4c, //CH_NO,配置頻段在423MHZ
0x0C, //輸出功率為10db,不重發,節電為正常模式
0x44, //地址寬度設定,為4位元組
0x02,0x02, //接收傳送有效數據長度為32位元組
0xCC,0xCC,0xCC,0xCC, //接收地址
0x58, //CRC充許,8位CRC校驗,外部
時鐘信號不使能,16M晶振
};
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void SpiWrite(uchar date) //用SPI口寫數據至NRF905內//
{
uchar i;
for(i=0;i<8;i++)
{
delay(1);
SCK=0;
MOSI=(date&0x80);
date<<=1 ;
delay(1);
SCK=1;
delay(1);
SCK=0;
}
SCK=0;
}
void TxPacket(void)
{
// TXEN=1;
CSN=0;
SpiWrite(0x22); //寫傳送地址,後面跟4位元組地址//
SpiWrite(0xcc);
SpiWrite(0xcc);
SpiWrite(0xcc);
SpiWrite(0xcc);
CSN=1;
delay(1);
CSN=0;
SpiWrite(0x20); //寫傳送數據命令,後面跟三位元組數據//
SpiWrite(0x01);
SpiWrite(0x02);
// SpiWrite(0x04);
CSN=1;
delay(1);
TRX_CE=1;
TXEN=1; //CE,EN同時為1,為傳送模式
delay(1); //等待傳送完成//
led=~led;
// while(!DR); //在非禁止狀態下,只能發射一次
TRX_CE=0;
//led=~led; //加上led後,對接收產生了一定的影響,
//while(!DR); //有時多接收一次的數據
}
void Ini_System(void)
{ //初始化配置暫存器//
uchar i;
// delay(1);
CSN=1;
SCK=0;
DR=0;
PWR=1; //進入掉電模式
TRX_CE=0;
TXEN=0;
delay(1);
CSN=0; //進入SIP模式
for(i=0;i<11;i++)
{
SpiWrite(RFConf[i]); //設定配置暫存器
}
CSN=1; //關閉SPI,進入發射狀態
// PWR=1;
}
void main(void)
{
led=1;
Ini_System(); //設定配置,並進入發射模式
// PWR=1; //進入掉電模式
while(1)
{
TxPacket(); //傳送數據
led=~led;
DR=0;
}
}
接收部分
#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
bit lcdbit;
sbit TXEN = P2^7; //配置口定義7`6`5//
sbit TRX_CE = P2^6;
sbit PWR = P2^5;
sbit MISO = P2^2; //SPI口定義0`1`2`3//
sbit MOSI = P2^3;
sbit SCK = P2^1;
sbit CSN = P2^0;
sbit DR = P2^4; //狀態輸出口4//
sbit led=P1^0;
/************//*RF暫存器配置*//*************
// 0x00, //配置命令//
// 0x6C, //CH_NO,配置頻段在433.2MHZ
// 0x0E, //輸出功率為10db,不重發,節電為正常模式
// 0x44, //地址寬度設定,為4位元組
// 0x03,0x03, //接收傳送有效數據長度為3位元組
// 0xE7,0xE7,0xE7,0xE7,//接收地址,16位CRC校驗,外部時鐘信號使能,16M晶振//UP_CLK輸出1MHZ頻率
// 0xDE, //CRC充許
//******************************/
/*uchar code RFConf[11]={0x00,0x6c,0x0e,0x44,0x03,0x03,
0xe7,0xe7,0xe7,0xe7,0xde};
*/
uchar RFConf[11]={ //配置命令//
0x00,0x4c,0x0c,0x44,0x02,0x02,
0xcc,0xcc,0xcc,0xcc,0x58 //CRC充許,8位CRC校驗,外部時鐘信號不使能,16M晶振
};
uchar TxRxBuffer[2];
uchar date;
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void SpiWrite(unsigned char date) //用SPI口寫數據至NRF905內//
{
uchar i;
for(i=0;i<8;i++)
{
delay(1);
SCK=0;
MOSI=(date&0x80);
date<<=1 ;
delay(1);
SCK=1;
delay(1);
SCK=0;
}
SCK=0;
}
unsigned char SpiRead(void) //from 905 read data//
{
uchar i;
for(i=0;i<8;i++)
{
date<<=1 ;
SCK=0;
delay(1);
date|=MISO;
SCK=1 ;
delay(1);
}
SCK=0;
return(date);
}
void RxPacket(void) //接收數據包//
{
uchar i;
//while(DR)
for (i = 0 ;i < 2 ;i++)
{
//led=~led;
TxRxBuffer[i] = SpiRead();
//i++;
}
}
void Wait_Rec_Packet(void) //等待接收數據包//
{
// uchar temp;
// PWR=1;
TXEN=0; //接收模式
TRX_CE=1;
delay(2);
while(!DR)
{ delay(10);
// if(DR) //數據接收成功
{
led=~led;
TRX_CE=0; //如果數據準備好,則進入待機模式,以便SPI口操作
CSN=0;
delay(1);
SpiWrite(0x24); //讀nRF905所接受到的數據
RxPacket(); //保存數據
CSN=1;
delay(10);
TRX_CE=1;
/*temp=TxRxBuffer[0]+TxRxBuffer[1]+TxRxBuffer[2];
if(temp==0x07)
{
lcdbit=!lcdbit; //lcdbit=0
}*/
break;
}
}
}
void Ini_System(void) //初始化配置暫存器//
{
uchar i;
//lcdbit=1;
CSN=1;
SCK=0;
DR=0;
PWR=1; //進入掉電模式
TRX_CE=0;
TXEN=0;
delay(1);
CSN=0; //進入SIP模式
for(i=0;i<11;i++)
{
SpiWrite(RFConf[i]); //設定配置暫存器
}
CSN=1; //關閉SPI,進入接收狀態
PWR=1;
//TRX_CE=1;
//TXEN=0;
}
void main(void)
{
P0=0x00;
led=1;
Ini_System(); //設定配置,並進入接收模式 (收)
PWR=1; //進入掉電模式
while(1)
{
Wait_Rec_Packet(); //等待接收完成,保存完接收數據(保存數據+地址)
//CSN=0;
P0 = TxRxBuffer[0];
delay(600);
P0 = TxRxBuffer[1];
delay(600);
P0 = TxRxBuffer[2];
delay(600);
//CSN=1;
}
}
程式經本人測試後沒太大問題,如要深入研究,本人附加詳細資訊,希望對您有所幫助。
接口
1)、模式控制接口:
該接口由 PWR 、TRX_CE、TX_EN組成控制由nRF905組成的高頻頭的四種工作模式:掉電和 SPI編程模式;待機和SPI編程模式 ;發射模式;接收模式。
2)、SPI接口:
SPI 接口由 CSN、SCK、MOSI以及MISO組成。在配置模式下
單片機通過SPI接口配置高頻頭的工作參數;在發射/接收模式下單片機SPI接口傳送和接收數據。
3)、狀態輸出接口:
提供載波檢測輸出CD,地址匹配輸出AM,數據就緒輸出DR。
外圍
1)、晶體規格
為了實現晶體振盪器低功耗和
快速啟動時間的解決方案,推薦使用低值晶體負載電容。指定CL=12pF是可以接受的。但是,也可能增大到16pF。指定一個晶體並行相等電容,Co=1.5pF也是很好的,但這樣一來會增加晶體自身成本。典型的設定晶體電容Co=1.5pF,指定Co_max=7.0pF。
2)、外部參考時鐘
一個外部參考時鐘如MCU時鐘,可以用來代替晶體震盪器。這個
時鐘信號應該直接連線到XC1
引腳,XC2引腳為高阻態。當使用外部時鐘代替晶體時鐘工作時,始終必須工作在Standby模式以降低電流消耗。如果器件被設定成Standby模式而沒有使用外部時鐘或晶體時鐘,則電流消耗最大可達1mA。
在默認情況下,微處理器提供輸出時鐘。在Standby模式下提供輸出時鐘將增加電流消耗。在Standby模式電流消耗取決於頻率和外部晶體負載、輸出時鐘的頻率和提供輸出時鐘的電容負載。
4)、天線輸出
ANT1和ANT2輸出腳給天線提供穩定的RF輸出。這兩個腳必須有連線到VDD_PA的直流通路,通過RF扼流圈,或者通過天線雙極的中心點。在ANT1和ANT2之間的負載阻抗應該在200-700Ω範圍內,通過簡單的匹配網路或RF變壓器(不平衡變壓器)可以獲得較低的阻抗(例如50Ω)。
拓展
基於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 模組傳送過程處理:
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;
}
}
}