nrf24l01是適合初學入門的無線模塊_第1頁
nrf24l01是適合初學入門的無線模塊_第2頁
nrf24l01是適合初學入門的無線模塊_第3頁
nrf24l01是適合初學入門的無線模塊_第4頁
nrf24l01是適合初學入門的無線模塊_第5頁
免費預覽已結束,剩余14頁可下載查看

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、24101 的多機通信采用頻分多子的方法,只需要在接受端對不同的通道配置地址即可。發送端使用相應的地址作為本機地址。接受數據時通過讀取 STATU 汕相關位即可得知接收的是哪個通道的數據。以下僅給出多對一的通信代碼。至于一對多,以及多對多等情況讀者可以自行研究了。只給出相關部分,其他部分請參考前兩篇文章接受端uintconstADDRESS0ADR_WIDTH=0 x34,0 x43,0 x10,0 x10,0 x01;/uintconstADDRESS1ADR_WIDTH=0 xc4,0 xc3,0 xc2,0 xc1,0 xc0;/頻道 0 接收地址頻道 1 接收地址ucharwho=0

2、xff;/*/*NRF24L01 初始化/*/voidinit_NRF24L01(void)us(100);CE=0;/chipenableCSN=1;/SpidisableSCK=0;/SpiclocklineinithighSPI_Write_Buf(WRITE_REG+TX_ADDR,ADDRESS0,ADR_WIDTH);/寫本地地址SPI_Write_Buf(WRITE_REG+RX_ADDR_P0,ADDRESS0,ADR_WIDTH);/頻道 0 地址SPI_Write_Buf(WRITE_REG+RX_ADDR_P1,ADDRESS1,ADR_WIDTH);/頻道 1 地址SP

3、I_RW_Reg(WRITE_REG+EN_AA,0 x03);/頻道 0、1 自動應答SPI_RW_Reg(WRITE_REG+EN_RXADDR,0 x03);/允許頻道 0、1SPI_RW_Reg(WRITE_REG+RF_CH,0);/設置信道工作為 2.4GHZ,收發必須一SPI_RW_Reg(WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);/諼收數諼收數據長度SPI_RW_Reg(WRITE_REG+RX_PW_P1,RX_PLOAD_WIDTH);接接收數據長度SPI_RW_Reg(WRITE_REG+RF_SETUP,0 x07);/設置發射速率為 1MH

4、Z 發射功率為最大值 0dB,*/*函數:unsignedcharnRF24L01_RxPacket(unsignedchar*rx_buf)/*功能:數據讀取后放如 rx_buf 接收緩沖區中/*/unsignedcharnRF24L01_RxPacket(unsignedchar*rx_buf)unsignedcharrevale=0;sta=SPI_Read(STATUS);/讀取狀態寄存其來判斷數據接收狀況if(RX_DR)/判斷是否接收到數據CE=0;SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);revale=1;who=sta&am

5、p;0 x0e;who|=0 xf0;/通道 0:who=0 xf0;通道 1:who=0 xf2SPI_RW_Reg(WRITE_REG+STATUS,0 xff);/接收至 U 數據后 RX_DR,TX_DS,MAX_PtB 置高為 1,通過寫 1 來清楚中斷標志CSN=0;SPI_RW(FLUSH_RX);CSN=1;returnrevale;voidmain(void)uchari;ucharRxBufTX_PLOAD_WIDTH;init_NRF24L01();StartUART();ms(6000);while(1)/如果接收到數據,發往 PCSetRX_Mode();if(nRF

6、24L01_RxPacket(RxBuf)R_S_Byte(who);ms(10000);for(i=0;iTX_PLOAD_WIDTH;i+)R_S_Byte(RxBufi);ms(10000);))發送1-uintconstADDRESS0ADR_WIDTH=0 x34,0 x43,0 x10,0 x10,0 x01;其余與雙工通信相同發送2-uintconstADDRESS1ADR_WIDTH=0 xc4,0 xc3,0 xc2,0 xc1,0 xc0;/頻道 1 接收地址其余與雙工通信相同以上就是簡要的代碼。也是重要的地方。如果發送端要發送數據的話,可能在配置自動應答的接受地址時會遇到

7、一些問題。(因為是以通道 0 作為應答通道,而發送模式又必須使得接收發送地址一致,這樣給兩臺發送機發數據就要對 0 實時配置地址)筆者嘗試過配置,沒有成功,只好不配置了,都是這樣接收端無法接收到自動應答的信號24l01雙向通訊2010-11-1921:28一周的時間過去了,終于搞出來了雙向通訊,中間出了點莫名奇妙的情況,導致我迷惘了很久。上次發的頭文件和.c文件有個模式設置的選項。在做雙向通信的時候發現這個有點多余。所以就刪掉了,內容也做了些小改動。所以就只發修改的部分24l01.h這個文件和之前的一樣。只去掉#defineTMODE這幾行24l01.c修改了三個地方。分別是1、*/*NRF2

8、4L01初始化/*這里不用設置什么模式,等需要接受或發送數據時指定模式/*/voidinit_NRF24L01(void)us(100);CE=0;/chipenableCSN=1;/SpidisableSCK=0;/SpiclocklineinithighSPI_Write_Buf(WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH);同本應地址SPI_Write_Buf(WRITE_REG+RX_ADDR_P0,RX_ADDRESS,RX_ADR_WIDTHf/接遍!地址SPI_RW_Reg(WRITE_REG+EN_AA,0 x01);/頻道0自動ACK應

9、答允許SPI_RW_Reg(WRITE_REG+EN_RXADDR,0 x01);施許接收地址只有頻道0,如果需要多而道可以參考Page21SPI_RW_Reg(WRITE_REG+RF_CH,0);/設置信道工作為2.4GHZ;收安必須一致SPI_RW_Reg(WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH)置掇收數據長度,本次設置%32字節SPI_RW_Reg(WRITE_REG+RF_SETUP,0 x07);/設置發射速率為1MHZ發射功率為最大值0dB)2、/*/*函數:voidSetRX_Mode(void)/*功能:數據接收配樂/*/voidSetRX_Mod

10、e(void)(CE=0;SPI_RW_Reg(WRITE_REG+CONFIG,0 x0f);/IRQ收發完成中斷響應,16位CRC,主接收CE=1;us(130);3、 /*/*函數:voidnRF24L01_TxPacket(unsignedchar*tx_buf)/*功能:發送tx_buf中數據/*/voidnRF24L01_TxPacket(unsignedchar*tx_buf)(CE=0;/StandByI模式SPI_Write_Buf(WRITE_REG+RX_ADDR_P0,TX_ADDRESS,TX_ADR_WIDTH裝/載接收端地址SPI_Write_Buf(WR_TX_

11、PLOAD,tx_buf,TX_PLOAD_WIDTH);/裝載數據SPI_RW_Reg(WRITE_REG+CONFIG,0 x0e);/IRQ收發完成中斷響應,16位CRC主發送CE=1;/置高CE激發數據發送us(10);以上就是全部的修改。這兩個文件同樣適用于單工通信。以下給出這次測試用的兩個主函數。為了方便與上次的文章對應。這里還是以接收,發送區分。接收#includenrf24l01.h#includedelay.hucharTxBufTX_PLOAD_WIDTH=0 x55,0 xaa;*串口初始化*voidStartUART(void)/波特率2400SCON=0 x50;TM

12、OD=0 x20;TH1=0 xF3;TL1=0 xF3;PCON=0 x00;TR1=1;H*voidR_S_Byte(ucharR_Byte)SBUF=R_Byte;while(TI=0);/查詢法TI=0;通過用將接收到數據發送給PC端/*主函數*voidmain(void)uchari;ucharRxBufTX_PLOAD_WIDTH;init_NRF24L01();StartUART();ms(6000);while(1)/如果接收到數據,發往PCSetRX_Mode();if(nRF24L01_RxPacket(RxBuf)for(i=0;iTX_PLOAD_WIDTH;i+)R_

13、S_Byte(RxBufi);/發送0 x55,0 xaa要求發送端發數據nRF24L01_TxPacket(TxBuf);/SPI_RW_Reg(WRITE_REG+STATUS,0XFF)加上這句后,會出現接收到幾組數據后停了B收的現象,疝因未知ms(130);/這個延時很重要,延時過短,數據包丟失。/延時過長,減慢速度,甚至無法接收(實驗時出現的問題,原因未知)RxBuf0=0;RxBuf1=0;發送includenrf24l01.h#includedelay.hucharTxBufTX_PLOAD_WIDTH=0 x01,0 x02;voidmain()charRxBufTX_PLOA

14、D_WIDTH=0;init_NRF24L01();nRF24L01_TxPacket(TxBuf);ms(6000);while(1)SetRX_Mode();if(nRF24L01_RxPacket(RxBuf)/將收到的數據發回接收端檢驗是否正確/如果設置的數據較長,應使用for循環TxBuf0=RxBuf0;TxBuf1=RxBuf1;nRF24L01_TxPacket(TxBuf);SPI_RW_Reg(WRITE_REG+STATUS,0XFF);ms(90);/這個延時一樣很重要RxBuf0=0;RxBuf1=0;)以上就是這周忙活的東西了,高手不要見笑。PS:原先想要使用自動重

15、發功能的,結果發現自動重發的話,傳輸速率很慢,沒有延時的快。也可能是我自動重發的延時沒設置好。另外最開始幾天一直在做中斷通信,如果使用IRQ上中斷來接受數據,可以明顯減輕MCU勺負擔。可是我測試了幾天下來發現一個無語的結果。在中斷里讀出來的STATUS的值是0 x00,頓時心灰意冷。網上有其他人貌似做出來了,可惜我寫的跟他們一樣也不行啊一,不知道問題在哪。但有一點是肯定的:接收到數據時必然引起中斷。過幾天繼續貼出多機通信的代碼。nrf24l01的51驅動程序2010-11-1318:58隨著物聯網時代的到來,無線通信技術日趨重要。nrf24l01是適合初學入門的無線模塊。于是乎我就一頭埋進去,

16、苦干一周有余。發現網上的程序都是抄來抄去的,不甚寒心。抄也就算了,光抄錯的!后來自己動手研究,完成了SPI接口的操作,繼續攻克無線模塊,最終無果,只好再找代碼。終于找到了一個可以的。本來想直接貼出來的,但為了許多和我曾經一樣迷茫的同胞可以順利進入無線領域。我特意修改代碼,整理出nrf24l01.h與nrf24l01.c,一則便于模塊化管理,二則,便于使用,便于二次開發。同時,增加了許多注釋。代碼中應該還有許多不足的,甚至多余的東西,后續將會繼續發表一篇關于無線模塊開發的注意事項。/nrf24l01.h#ifndefNRF24L01_H#defineNRF24L01_H#include#defi

17、neTMODEtypedefunsignedcharuchar;typedefunsignedcharuint;*sbitCE=P1A0;3sbitSCK=P1A1;/5sbitMISO=P1A2;/7sbitCSN=P1A5;/4sbitMOSI=P1A6;/6sbitIRQ=P1A7;/8*#defineTX_ADR_WIDTH5/5uintsTXaddresswidth#defineRX_ADR_WIDTH5/5uintsRXaddresswidth#defineTX_PLOAD_WIDTH32/20uintsTXpayload#defineRX_PLOAD_WIDTH32/20uint

18、sTXpayload*配置收發狀態,CRCK驗模式以及收發狀態自動應答功能設置可用信道設置收發地址寬度設置自動重發功能設置工作頻率設置發射速率、功耗功能設置狀態寄存器發送監測功能地址檢測頻道0接收數據地址頻道1接收數據地址*SPI-IO端口地址、數據長度*NRF24L01寄存器指令#defineREAD_REG0 x00/#defineWRITE_REG0 x20/#defineRD_RX_PLOAD0 x61/#defineWR_TX_PLOAD0 xA0/#defineFLUSH_TX0 xE1/#defineFLUSH_RX0 xE2/#defineREUSE_TX_PL0 xE3/#d

19、efineNOP0 xFF/*讀寄存器指令寫寄存器指令讀取接收數據指令寫待發數據指令沖洗發送FIFO指令沖洗接收FIFO指令定義重復裝載數據指令保留寄存器地址*SPI(nRF24L01)#defineCONFIG0 x00/響應方式#defineEN_AA0 x01/#defineEN_RXADDR0 x02/#defineSETUP_AW0 x03/#defineSETUP_RETR0 x04/#defineRF_CH0 x05/#defineRF_SETUP0 x06/#defineSTATUS0 x07/#defineOBSERVE_TX0 x08/#defineCD0 x09/#def

20、ineRX_ADDR_P00 x0A/#defineRX_ADDR_P10 x0B/0 x0C/頻道2接收數據地址0 x0D/頻道3接收數據地址0 x0E/頻道4接收數據地址0 x0F/頻道5接收數據地址0 x10/發送地址寄存器0 x11/接收頻道0接收數據長度0 x12/接收頻道0接收數據長度0 x13/接收頻道0接收數據長度0 x14/接收頻道0接收數據長度0 x15/接收頻道0接收數據長度0 x16/接收頻道0接收數據長度0 x17/FIFO棧入棧出狀態寄存器設置/*voidinit_NRF24L01(void);uintSPI_RW(uintuchar);ucharSPI_Read(

21、ucharreg);voidSetRX_Mode(void);uintSPI_RW_Reg(ucharreg,ucharvalue);uintSPI_Read_Buf(ucharreg,uchar*pBuf,ucharuchars);uintSPI_Write_Buf(ucharreg,uchar*pBuf,ucharuchars);unsignedcharnRF24L01_RxPacket(unsignedchar*rx_buf);voidnRF24L01_TxPacket(unsignedchar*tx_buf);/*#endif/nrf24l01.c#includenrf24l01.h#

22、includedelay.huintbdatasta;/狀態標志sbitRX_DR=staA6;sbitTX_DS=staA5;sbitMAX_RT=staA4;uintconstTX_ADDRESSTX_ADR_WIDTH=0 x34,0 x43,0 x10,0 x10,0 x01;/本地地址uintconstRX_ADDRESSRX_ADR_WIDTH=0 x34,0 x43,0 x10,0 x10,0 x01;/接收地址*#defineRX_ADDR_P2#defineRX_ADDR_P3#defineRX_ADDR_P4#defineRX_ADDR_P5#defineTX_ADDR#d

23、efineRX_PW_P0#defineRX_PW_P1#defineRX_PW_P2#defineRX_PW_P3#defineRX_PW_P4#defineRX_PW_P5#defineFIFO_STATUS/nrf24l01.h結束/*NRF24L01初始化*/voidinit_NRF24L01(void)(us(100);CE=0;/chipenableCSN=1;/SpidisableSCK=0;/SpiclocklineinithighSPI_Write_Buf(WRITE_REG+TX_ADDR,TX_ADDRESS,TX_ADR_WIDTH);/g本地地址SPI_Write_B

24、uf(WRITE_REG+RX_ADDR_P0,RX_ADDRESS,RX_ADR_WIDTHf/接遍!地址SPI_RW_Reg(WRITE_REG+EN_AA,0 x01);/頻道0自動ACK應答允許SPI_RW_Reg(WRITE_REG+EN_RXADDR,0 x01);施許接收地址只有頻道0,如果需要多而道可以參考Page21SPI_RW_Reg(WRITE_REG+RF_CH,0);/設置信道工作為2.4GHZ;收無必須一致SPI_RW_Reg(WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH)置掇收數據長度, 本次設3為32字節SPI_RW_Reg(WRITE_R

25、EG+RF_SETUP,0 x07);/設置發射速率為1MHZ發射加率為最大值0dB#ifdefRMODESPI_RW_Reg(WRITE_REG+CONFIG,0 x0f);/IRQ收發完成中斷響應,16位CRC,主接收#endif#ifdefTMODESPI_RW_Reg(WRITE_REG+CONFIG,0 x0E);/IRQ收發完成中斷響應,16位CRC,主接收#endif)/*/*函數:uintSPI_RW(uintuchar)/*功能:NRF24L0酌SPI寫時序/*/uintSPI_RW(uintuchar)(.uintbit_ctr;for(bit_ctr=0;bit_ctr8

26、;bit_ctr+)/output8-bit(MOSI=(uchar&0 x80);/outputuchar,MSBtoMOSIuchar=(uchar1);/shiftnextbitintoMSB.SCK=1;/SetSCKhigh.uchar|=MISO;/capturecurrentMISObitSCK=0;/.thensetSCKlowagainreturn(uchar);/returnreaduchar/*/*函數:ucharSPI_Read(ucharreg)/*功能:NRF24L0宿SPI時序/*/ucharSPI_Read(ucharreg)(.ucharreg_val

27、;CSN=0;/CSNlow,initializeSPIcommunication.SPI_RW(reg);/Selectregistertoreadfrom.reg_val=SPI_RW(0);/.thenreadregistervalueCSN=1;/CSNhigh,terminateSPIcommunication/*/*功能:NRF24L0慎寫寄存器函數/*/uintSPI_RW_Reg(ucharreg,ucharvalue)(一一uintstatus;CSN=0;/CSNlow,initSPItransactionstatus=SPI_RW(reg);/selectregister

28、SPI_RW(value);/.andwritevaluetoit.CSN=1;/CSNhighagainreturn(status);/returnnRF24L01statusuchar/*/*函數:uintSPI_Read_Buf(ucharreg,uchar*pBuf,ucharuchars)/*功能:用于讀數據,reg:為寄存器地址,pBuf:為待讀出數據地址,uchars:讀出數據的個數/*/uintSPI_Read_Buf(ucharreg,uchar*pBuf,ucharuchars)(uintstatus,uchar_ctr;return(reg_val);/returnreg

29、istervalueCSN=0;/SetCSNlow,initSPItranactionstatus=SPI_RW(reg);/Selectregistertowritetoandreadstatusucharfor(uchar_ctr=0;uchar_ctruchars;uchar_ctr+)pBufuchar_ctr=SPI_RW(0);/CSN=1;return(status);/returnnRF24L01statusuchar)/*/*函數:uintSPI_Write_Buf(ucharreg,uchar*pBuf,ucharuchars)/*功能:用于寫或據:Z寄存器地址,pBuf

30、:為待寫入數據地址,uchars:寫入數據的個數/*/uintSPI_Write_Buf(ucharreg,uchar*pBuf,ucharuchars)(一一uintstatus,uchar_ctr;CSN=0;/SPI使能status=SPI_RW(reg);for(uchar_ctr=0;uchar_ctruchars;uchar_ctr+)/SPI_RW(*pBuf+);CSN=1;/關閉SPIreturn(status);/)/*/*函數:voidSetRX_Mode(void)/*功能:數據接收配A/*voidSetRX_Mode(void)CE=0;#ifdefTMODESPI_

31、RW_Reg(WRITE_REG+CONFIG,0 x0f);/IRQ收發完成中斷響應,16位CRC,主接收#endifCE=1;us(130);/*/*函數:unsignedcharnRF24L01_RxPacket(unsignedchar*rx_buf)/*功能:數據讀取后放如rx_buf接收緩沖區中/*/unsignedcharnRF24L01_RxPacket(unsignedchar*rx_buf)unsignedcharrevale=0;sta=SPI_Read(STATUS);/讀取狀態寄存其來判斷數據接收狀況if(RX_DR)/CE=0;/SPISPI_Read_Buf(RD

32、_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);/readreceivepayloadfromRX_FIFObufferSPI_RW_Reg(WRITE_REG+STATUS,sta);/掇收至U數據后RX_DR,TX_DS,MAX_PT都置高為1,通過寫1來清楚中斷標志returnrevale;/*/*函數:voidnRF24L01_TxPacket(unsignedchar*tx_buf)/*功能:發送tx_buf中數據/*/voidnRF24L01_TxPacket(unsignedchar*tx_buf)CE=0;/StandByI模式SPI_Write_Buf(WR

33、ITE_REG+RX_ADDR_P0,TX_ADDRESS,TX_ADR_WIDTH裝/載向I攵端地址SPI_Write_Buf(WR_TX_PLOAD,tx_buf,TX_PLOAD_WIDTH);/裝載數據#ifdefRMODESPI_RW_Reg(WRITE_REG+CONFIG,0 x0e);/IRQ收發完成中斷響應,16位CRC主發送#endifCE=1;/置高CE激發數據發送判斷是否接收到數據使能revale=1;/讀取數據完成標志us(10);/nrf24101c結束文中用到的“delay.h”中一個us延時,一個ms延時,讀者可以自己寫。(由于晶振不同,延時函數不同,這里就不列出了)這兩個文件同時包含了收發模式。通過/模式選擇#defineRMODE/#defineTMODE進行切換。以下順便給出接收,發送主函數,便于

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論