李賀+程祥+曾令國(guó)
摘 要: 介紹一種基于STC89C52單片機(jī)﹑STM32系列MCU和無(wú)線射頻收發(fā)芯片nRF24L01的無(wú)線通信系統(tǒng)設(shè)計(jì),描述了nRF24L01的主要引腳特性﹑具體應(yīng)用﹑SPI指令,詳細(xì)闡述了在Enhanced ShockBurst模式下的配置方法,同時(shí)給出了根據(jù)nRF24L01的SPI時(shí)序用通用IO口模擬SPI接口和配置STM32系列MCU硬件SPI接口的詳細(xì)說(shuō)明。
關(guān)鍵詞: nRF24L01; STM32; STC89C52; Enhanced ShockBurst模式; SPI指令
中圖分類號(hào): TN919?34 文獻(xiàn)標(biāo)識(shí)碼: A 文章編號(hào): 1004?373X(2014)15?0032?03
Design for short?range wireless communication system based on chip nRF24L01
LI He, CHENG Xiang, ZENG Ling?guo
(School of Mechanical Engineering, Shandong University of Technology, Zibo 250200, China)
Abstract: Design for a wireless communication system based on STC89C52, MCU in STM32F103 series and wireless RF transcieving chip nRF24L01 is introduced in this paper. The main pin characteristics, concrete applications and SPI instructions are described. The configuration method in Enhanced ShockBurst mode is elaborated. The metnods to simulate SPI by using the general IO interface according to SPI time sequence of nRF24L01and configure STM32 hardware SPI are given.
Keywords: nRF24L01; STM32; STC89C52; Enhanced ShockBurst mode; SPI instruction
0 引 言
在有線數(shù)據(jù)通信系統(tǒng)中,數(shù)據(jù)的傳輸需要依賴于電纜,布線復(fù)雜,成本高,工作量大,操作不方便,采用無(wú)線數(shù)據(jù)通信方式可以克服以上缺點(diǎn)。nRF24L01是Nordic公司推出的一款工作在2.4~2.48 GHz ISM頻段的單片無(wú)線射頻收發(fā)器件,數(shù)據(jù)傳輸速率可達(dá)到2 Mb/s,內(nèi)置頻率發(fā)生器﹑Enhanced ShockBurst模式控制器﹑功率放大器等,只需要少量的外圍器件就可以組成射頻收發(fā)電路[1]。nRF24L01操作簡(jiǎn)單,用戶只需要通過(guò)它的一個(gè)標(biāo)準(zhǔn)SPI接口和規(guī)定的SPI配置字就可以方便地實(shí)現(xiàn)對(duì)它的控制。
1 Enhanced ShockBurst模式工作原理
nRF24L01被設(shè)置為接收模式時(shí),可以同時(shí)接收6路不同數(shù)據(jù)通道的數(shù)據(jù),每個(gè)通道都有各自的地址但6路通道采用相同的頻率[2]。也就是說(shuō),配置為接收模式的nRF24L01可以同時(shí)接收6個(gè)不同的nRF24L01發(fā)送的數(shù)據(jù),接收端每個(gè)通道的地址要與相應(yīng)發(fā)送端TX_ADDR內(nèi)容相同。每一路通道都可以被設(shè)置為Enhanced ShockBurst模式,成功接收數(shù)據(jù)后記錄地址并以此地址作為目標(biāo)地址自動(dòng)發(fā)送應(yīng)答信號(hào)。
nRF24L01被設(shè)置為Enhanced ShockBurst發(fā)送模式時(shí),數(shù)據(jù)發(fā)送完畢后會(huì)自動(dòng)跳轉(zhuǎn)到接收模式使用數(shù)據(jù)通道0等待接收端的應(yīng)答信號(hào),若接收到應(yīng)答信號(hào),則將TX_DS標(biāo)志位硬件置高,表示數(shù)據(jù)發(fā)送完成并產(chǎn)生中斷,此時(shí)需要向STATUS寄存器的TX_DS位以軟件方式寫1,清除中斷標(biāo)志;
若未接收到應(yīng)答信號(hào)將繼續(xù)發(fā)送數(shù)據(jù),直到發(fā)送數(shù)據(jù)次數(shù)達(dá)到軟件設(shè)置的最大重發(fā)次數(shù)后,nRF24L01會(huì)將MAX_RT位硬件置高,產(chǎn)生最大重發(fā)次數(shù)中斷[3]。這種數(shù)據(jù)處理模式使得開(kāi)發(fā)人員無(wú)需單獨(dú)處理雙向鏈接協(xié)議,編程方便。
2 SPI指令
外部MCU對(duì)nRF24L01所有寄存器的訪問(wèn)都是通過(guò)SPI指令完成的,一條SPI指令包括命令字和數(shù)據(jù)字節(jié),每一條SPI指令的執(zhí)行都必須伴隨片選信號(hào)CSN由高電平到低電平的突變,同時(shí)STATUS寄存器的內(nèi)容將通過(guò)MISO引腳串行移出,在CSN保持為低電平時(shí)完成數(shù)據(jù)字節(jié)的寫入或讀取。
nRF24L01是通過(guò)一個(gè)SPI接口與MCU相連的,對(duì)于沒(méi)有硬件SPI接口的控制器,需要使用通用IO口模擬[3]。這里給出了用51單片機(jī)IO口模擬SPI對(duì)nRF24L01的數(shù)據(jù)讀寫函數(shù)。函數(shù)是根據(jù)nRF24L01的SPI時(shí)序編寫的。
圖1和圖2給出了nRF24L01的SPI讀寫時(shí)序,在每個(gè)時(shí)鐘脈沖的上升沿完成一個(gè)數(shù)據(jù)位的存取,循環(huán)8次后完成一個(gè)字節(jié)的存取。第一個(gè)送入nRF24L01的字節(jié)是命令字,通過(guò)MOSI串行移入,高位在前低位在后,同時(shí)STATUS寄存器內(nèi)容通過(guò)MISO串行移出[4],隨后分別是數(shù)據(jù)字節(jié)的寫入和讀出。以讀數(shù)據(jù)為例,讀寄存器命令寫入nRF24L01后,MCU可以向MOSI寫任意字節(jié)即可從MISO讀出相應(yīng)寄存器的內(nèi)容。
uchar Spi_RW(uchar byte)
{
uchar i;
for(i=0;i<8;i++)
{
MOSI=(byte&0x80);
byte=byte<<1;
SCK=1;
byte=byte|MISO;
SCK=0;
}
return byte;
}
3 系統(tǒng)設(shè)計(jì)
本文設(shè)計(jì)的系統(tǒng)流程圖如圖3所示。
圖3 軟件流程圖
初始化STC89C52并將nRF24L01初始化為Enhanced ShockBurst發(fā)送模式,單片機(jī)上電后開(kāi)始發(fā)送數(shù)據(jù),若產(chǎn)生TX_DS中斷則數(shù)據(jù)發(fā)送成功并繼續(xù)發(fā)送數(shù)據(jù);若產(chǎn)生MAX中斷則數(shù)據(jù)超過(guò)最大重發(fā)次數(shù),清空FIFO寄存器重新發(fā)送數(shù)據(jù)[5]。
初始化STM32F103,將nRF24L01初始化為Enhanced ShockBurst接收模式,等待接收數(shù)據(jù),接收到數(shù)據(jù)后產(chǎn)生中斷,進(jìn)入中斷服務(wù)程序,判斷TX_DS位是否置1,若置1則清除中斷標(biāo)志并讀取數(shù)據(jù),將讀取到的數(shù)據(jù)通過(guò)串口發(fā)送給上位機(jī);否則清除中斷標(biāo)志后繼續(xù)等待接收數(shù)據(jù)。下面給出對(duì)nRF24L01的具體操作方法:
void NRF24L01_Init(u8 model)
{
SPI_CE_L(); //CE引腳置低,進(jìn)入待機(jī)模式
Write_Buf(NRF_WRITE_REG+RX_ADDR_P0,RX_ADDRESS,RX_ADR_WIDTH); //寫RX節(jié)點(diǎn)地址
Write_Reg(NRF_WRITE_REG+EN_AA,0x01);
//使能通道0的自動(dòng)應(yīng)答
Write_Reg(NRF_WRITE_REG+EN_RXADDR,0x01); //使能通道0的接收地址
Write_Reg(NRF_WRITE_REG+RF_CH,40); //設(shè)置RF通道為CHANAL
Write_Reg(NRF_WRITE_REG+RF_SETUP,0x0f);
//設(shè)置TX發(fā)射參數(shù),0 dB增益,2 Mb/s,低噪聲增益開(kāi)啟
if(model==RXMODE)
//進(jìn)入接收模式
{
Write_Reg(NRF_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH); //選擇通道0的有效數(shù)據(jù)寬度
Write_Reg(NRF_WRITE_REG + CONFIG, 0x0f);
// IRQ收發(fā)完成中斷開(kāi)啟,16位CRC校驗(yàn),接收模式
}
else if(model==TXMODE) //進(jìn)入發(fā)送模式
{
Write_Reg(NRF_WRITE_REG+SETUP_RETR,0x1a);
//設(shè)置自動(dòng)重發(fā)間隔時(shí)間:500 μs;最大自動(dòng)重發(fā)次數(shù):10次
Write_Buf(NRF_WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH); //寫TX節(jié)點(diǎn)地址
Write_Reg(NRF_WRITE_REG + CONFIG, 0x0e);
// IRQ收發(fā)完成中斷開(kāi)啟,16位CRC校驗(yàn),發(fā)送模式
}
這是nRF24L01的初始化函數(shù),根據(jù)需要選擇工作在接收模式還是發(fā)射模式。本文中nRF24L01采用數(shù)據(jù)處理方式是Enhanced ShockBurst模式,所以必須使能數(shù)據(jù)通道的自動(dòng)應(yīng)答功能并設(shè)置重發(fā)間隔時(shí)間和最大重發(fā)次數(shù)。發(fā)射端和中斷在配置工作通道頻率﹑發(fā)射功率和數(shù)據(jù)傳輸速率時(shí)必須完全相同[3]。
uchar Write_Reg(uchar reg, uchar value)
{
uchar status;
SPI_CSN_L(); /*選通SPI接口*/
status = Spi_RW(reg);
/*寫寄存器地址同時(shí)讀取狀態(tài)寄存器內(nèi)容*/
Spi_RW(value); /*寫數(shù)據(jù)*/
SPI_CSN_H(); /*禁止該SPI接口*/
return status; /*返回狀態(tài)寄存器內(nèi)容*/
}
這個(gè)函數(shù)用于向地址為reg的寄存器中寫入一個(gè)字節(jié)的數(shù)據(jù)value并返回狀態(tài)寄存器內(nèi)容,實(shí)際上reg是由寫寄存器指令0x20與寄存器地址共同組成的。
ucharRead_Reg(uint8_t reg)
{
uchar reg_val;
SPI_CSN_L(); /*選通SPI接口*/
Spi_RW(reg); /*寫寄存器地址*/
reg_val = Spi_RW(0); /*讀取該寄存器返回?cái)?shù)據(jù)*/
SPI_CSN_H(); /*禁止該SPI接口*/
return reg_val;
}
這個(gè)函數(shù)用于從地址為reg的寄存器中讀出一個(gè)字節(jié)的數(shù)據(jù)reg_val,實(shí)際上reg是由讀寄存器指令0x00與寄存器地址共同組成的。
uchar Write_Buf(uchar reg, uchar*pBuf, uchar count)
{
uint8_t i;
uint8_t status;
SPI_CSN_L(); /*選通SPI接口*/
status = Spi_RW(reg); /*寫寄存器地址*/
for(i=0; i { Spi_RW(pBuf[i]); /*寫數(shù)據(jù)*/ } SPI_CSN_H(); /*禁止該SPI接口*/ return status; } 這個(gè)函數(shù)的作用是向地址為reg的寄存器中寫入大小為count的數(shù)組,數(shù)組的首地址為pBuf,需要注意的是,當(dāng)讀寫多字節(jié)寄存器時(shí),首先讀寫低字節(jié)再讀寫高字節(jié)。從寄存器讀取多字節(jié)函數(shù)實(shí)現(xiàn)與此類似,本文不再贅述。 經(jīng)驗(yàn)證,在上位機(jī)串口通信助手中成功顯示所發(fā)數(shù)據(jù),本系統(tǒng)可行。 4 結(jié) 語(yǔ) 本文介紹了nRF24L01芯片在Enhanced ShockBurst數(shù)據(jù)處理模式下的工作原理,詳細(xì)介紹了如何根據(jù)它的SPI時(shí)序模擬SPI接口。設(shè)計(jì)了一種基于STM32,STC89C52MCU和nRF24L01芯片的近距離無(wú)線通信系統(tǒng),經(jīng)調(diào)試,STM32終端成功接收數(shù)據(jù)并通過(guò)串口成功地將數(shù)據(jù)發(fā)送給上位機(jī)??梢愿鶕?jù)需要(有無(wú)SPI接口,通信距離遠(yuǎn)近等)對(duì)本系統(tǒng)的軟件進(jìn)行移植,只需做少量修改即可。需要注意,nRF24L01的工作電壓是1.9~3.6 V,51單片機(jī)的[VCC]是5 V,因此需要電平轉(zhuǎn)換,因設(shè)計(jì)簡(jiǎn)單,本文沒(méi)有詳細(xì)介紹。 注:本文通訊作者為程祥。 參考文獻(xiàn) [1] 時(shí)志云,蓋建平,王代華,等.新型高速無(wú)線射頻器件nRF24L01及其應(yīng)用[J].國(guó)外電子元器件,2007(8):42?44. [2] Nordic Semiconductor. nRF24L01 datasheet [R]. [S.l.]: Nordic Semiconductor, 2009. [3] 朱慧彥,林林.基于MCU和nRF24L01的無(wú)線通信系統(tǒng)設(shè)計(jì)[J].電子科技,2012(4):81?83. [4] 劉靖,陳在平,李其林.基于nRF24L01無(wú)線數(shù)字傳輸系統(tǒng)[J].天津理工大學(xué)學(xué)報(bào),2007(3):38?40. [5] 莢慶,王代華,張志杰.基于nRF24L01的無(wú)線數(shù)據(jù)傳輸系統(tǒng)[J].現(xiàn)代電子技術(shù),2008,31(3):68?70. [6] 盧明,劉黎輝.基于nRF24L01的數(shù)控機(jī)床無(wú)線手輪設(shè)計(jì)[J].現(xiàn)代電子技術(shù),2013,36(7):103?106.
status = Spi_RW(reg); /*寫寄存器地址*/
for(i=0; i { Spi_RW(pBuf[i]); /*寫數(shù)據(jù)*/ } SPI_CSN_H(); /*禁止該SPI接口*/ return status; } 這個(gè)函數(shù)的作用是向地址為reg的寄存器中寫入大小為count的數(shù)組,數(shù)組的首地址為pBuf,需要注意的是,當(dāng)讀寫多字節(jié)寄存器時(shí),首先讀寫低字節(jié)再讀寫高字節(jié)。從寄存器讀取多字節(jié)函數(shù)實(shí)現(xiàn)與此類似,本文不再贅述。 經(jīng)驗(yàn)證,在上位機(jī)串口通信助手中成功顯示所發(fā)數(shù)據(jù),本系統(tǒng)可行。 4 結(jié) 語(yǔ) 本文介紹了nRF24L01芯片在Enhanced ShockBurst數(shù)據(jù)處理模式下的工作原理,詳細(xì)介紹了如何根據(jù)它的SPI時(shí)序模擬SPI接口。設(shè)計(jì)了一種基于STM32,STC89C52MCU和nRF24L01芯片的近距離無(wú)線通信系統(tǒng),經(jīng)調(diào)試,STM32終端成功接收數(shù)據(jù)并通過(guò)串口成功地將數(shù)據(jù)發(fā)送給上位機(jī)??梢愿鶕?jù)需要(有無(wú)SPI接口,通信距離遠(yuǎn)近等)對(duì)本系統(tǒng)的軟件進(jìn)行移植,只需做少量修改即可。需要注意,nRF24L01的工作電壓是1.9~3.6 V,51單片機(jī)的[VCC]是5 V,因此需要電平轉(zhuǎn)換,因設(shè)計(jì)簡(jiǎn)單,本文沒(méi)有詳細(xì)介紹。 注:本文通訊作者為程祥。 參考文獻(xiàn) [1] 時(shí)志云,蓋建平,王代華,等.新型高速無(wú)線射頻器件nRF24L01及其應(yīng)用[J].國(guó)外電子元器件,2007(8):42?44. [2] Nordic Semiconductor. nRF24L01 datasheet [R]. [S.l.]: Nordic Semiconductor, 2009. [3] 朱慧彥,林林.基于MCU和nRF24L01的無(wú)線通信系統(tǒng)設(shè)計(jì)[J].電子科技,2012(4):81?83. [4] 劉靖,陳在平,李其林.基于nRF24L01無(wú)線數(shù)字傳輸系統(tǒng)[J].天津理工大學(xué)學(xué)報(bào),2007(3):38?40. [5] 莢慶,王代華,張志杰.基于nRF24L01的無(wú)線數(shù)據(jù)傳輸系統(tǒng)[J].現(xiàn)代電子技術(shù),2008,31(3):68?70. [6] 盧明,劉黎輝.基于nRF24L01的數(shù)控機(jī)床無(wú)線手輪設(shè)計(jì)[J].現(xiàn)代電子技術(shù),2013,36(7):103?106.
status = Spi_RW(reg); /*寫寄存器地址*/
for(i=0; i { Spi_RW(pBuf[i]); /*寫數(shù)據(jù)*/ } SPI_CSN_H(); /*禁止該SPI接口*/ return status; } 這個(gè)函數(shù)的作用是向地址為reg的寄存器中寫入大小為count的數(shù)組,數(shù)組的首地址為pBuf,需要注意的是,當(dāng)讀寫多字節(jié)寄存器時(shí),首先讀寫低字節(jié)再讀寫高字節(jié)。從寄存器讀取多字節(jié)函數(shù)實(shí)現(xiàn)與此類似,本文不再贅述。 經(jīng)驗(yàn)證,在上位機(jī)串口通信助手中成功顯示所發(fā)數(shù)據(jù),本系統(tǒng)可行。 4 結(jié) 語(yǔ) 本文介紹了nRF24L01芯片在Enhanced ShockBurst數(shù)據(jù)處理模式下的工作原理,詳細(xì)介紹了如何根據(jù)它的SPI時(shí)序模擬SPI接口。設(shè)計(jì)了一種基于STM32,STC89C52MCU和nRF24L01芯片的近距離無(wú)線通信系統(tǒng),經(jīng)調(diào)試,STM32終端成功接收數(shù)據(jù)并通過(guò)串口成功地將數(shù)據(jù)發(fā)送給上位機(jī)??梢愿鶕?jù)需要(有無(wú)SPI接口,通信距離遠(yuǎn)近等)對(duì)本系統(tǒng)的軟件進(jìn)行移植,只需做少量修改即可。需要注意,nRF24L01的工作電壓是1.9~3.6 V,51單片機(jī)的[VCC]是5 V,因此需要電平轉(zhuǎn)換,因設(shè)計(jì)簡(jiǎn)單,本文沒(méi)有詳細(xì)介紹。 注:本文通訊作者為程祥。 參考文獻(xiàn) [1] 時(shí)志云,蓋建平,王代華,等.新型高速無(wú)線射頻器件nRF24L01及其應(yīng)用[J].國(guó)外電子元器件,2007(8):42?44. [2] Nordic Semiconductor. nRF24L01 datasheet [R]. [S.l.]: Nordic Semiconductor, 2009. [3] 朱慧彥,林林.基于MCU和nRF24L01的無(wú)線通信系統(tǒng)設(shè)計(jì)[J].電子科技,2012(4):81?83. [4] 劉靖,陳在平,李其林.基于nRF24L01無(wú)線數(shù)字傳輸系統(tǒng)[J].天津理工大學(xué)學(xué)報(bào),2007(3):38?40. [5] 莢慶,王代華,張志杰.基于nRF24L01的無(wú)線數(shù)據(jù)傳輸系統(tǒng)[J].現(xiàn)代電子技術(shù),2008,31(3):68?70. [6] 盧明,劉黎輝.基于nRF24L01的數(shù)控機(jī)床無(wú)線手輪設(shè)計(jì)[J].現(xiàn)代電子技術(shù),2013,36(7):103?106.