嚴林祥,張紅雨
(電子科技大學(xué) 電子工程學(xué)院,四川 成都 611731)
2.45 G無線通信的工作頻段處于2.405~2.485 GHz之間,這個頻段是國際規(guī)定的免費頻段。這就為2.45G無線技術(shù)的發(fā)展性提供了必要的有利條件。目前工業(yè)中可以采用的成熟且有統(tǒng)一的協(xié)議標準的應(yīng)用領(lǐng)域有:微波爐、無繩電話、ZigBee、WI-FI、藍牙等。但也有采用封閉協(xié)議通信的2.45G無線通信技術(shù),如:無線語音導(dǎo)游機,無線鼠標,2.45G有源RFID讀寫器等。它們在硬件上多使用 Nordic Semiconductor公司的nRF24L01系類芯片,各個廠家可以根據(jù)自己的需求制定自己的通信協(xié)議[1-2]。雖然藍牙、ZigBee都是標準協(xié)議,但是協(xié)議復(fù)雜、開發(fā)難度大、周期長,而非標準無線射頻協(xié)議具有低功耗、低成本、易開發(fā)等優(yōu)點。
由于Linux操作系統(tǒng)具有開源、授權(quán)免費等優(yōu)勢,因此基于Linux操作系統(tǒng)的嵌入式平臺在工業(yè)控制、遠程通信等領(lǐng)域有著廣泛的應(yīng)用前景。當nRF24L01射頻模塊作為嵌入式Linux平臺下的2.45G無線通信單元時,必須開發(fā)相應(yīng)的驅(qū)動程序。因為在Linux系統(tǒng)中,所有的外部設(shè)備都被看作是目錄/dev下的一個文件,并為用戶的訪問提供了一種標準接口[3]。因此當我們設(shè)計好nRF24L01射頻模塊的驅(qū)動程序,我們就可以很方便用于項目的開發(fā),而不必知道它的具體存在形式。
nRF24L01是一款工作在 2.4~2.5 GHz世界通用 ISM頻段的超低功耗單片無線收發(fā)器芯片。芯片內(nèi)置頻率發(fā)生器、功率放大器、晶體振蕩器、調(diào)制器和解調(diào)器等功能模塊,外圍擴展少量的器件就可以利用全雙工的SPI串行接口與MCU實現(xiàn)通信。芯片有125個頻點,能夠?qū)崿F(xiàn)點對點、點對多點的無線通信[1-2]。文中基于S3C2440-Linux的嵌入式平臺對nRF24L01射頻模塊進行驅(qū)動程序的設(shè)計。S3C2440可以使用GPIO模擬SPI接口的工作時序或者使用SPI控制器的方式對射頻模塊進行操作。使用GPIO模擬SPI接口的工作時序比較容易實現(xiàn),但是會導(dǎo)致大量的時間耗費在模擬SPI接口的時序上,訪問效率比較低[4]。因此本文研究S3C2440 SPI控制器的情況。S3C2440與nRF24L01射頻模塊通信主要由6根信號線組成,它們分別為:主機出從機進數(shù)據(jù)線(MOSI)、主機進從機出數(shù)據(jù)線(MISO)、時鐘線(SCK)、設(shè)備選擇線(CS)、中斷標志線(IRQ)和接收發(fā)送模式選擇線(CE)[4-5]。nRF24L01射頻模塊原理圖及其與S3C2440的接口連接圖,如圖1所示。
nRF24L01射頻模塊主要由nRF24L01芯片、天線和晶體振蕩電路組成。S3C2440通過SPI接口對nRF24L01的相關(guān)寄存器進行操作,以實現(xiàn)對射頻模塊的初始化和相關(guān)信息處理。如當射頻模塊發(fā)送信息時,S3C2440通過GPG14選擇nRF24L01芯片,利用SPI接口控制nRF24L01芯片工作在發(fā)送模式,并通過天線將數(shù)據(jù)發(fā)送出去。發(fā)送完成后,則使芯片進入低功耗模式(掉電模式、待機模式Ⅰ和待機模式Ⅱ)。在S3C2440對nRF24L01芯片進行寄存器設(shè)置階段則一般使其進入待機模式Ⅰ。此時部分芯片內(nèi)部振蕩器停振,射頻收發(fā)單元停止工作。待機模式Ⅱ在待機模式Ⅰ的基礎(chǔ)上激活了部分必須的時鐘緩存器[1-2]。
圖1 nRF24L01射頻模塊與S3C2440連接圖Fig.1 Connect diagram of nRF24L01 RF module and S3C2440
文中根據(jù)Linux字符設(shè)備開發(fā)的方法來設(shè)計nRF24L01射頻模塊驅(qū)動程序。應(yīng)用程序通過系統(tǒng)調(diào)用對射頻模塊的設(shè)備文件進行操作,而系統(tǒng)調(diào)用則通過設(shè)備文件的主設(shè)備號找到相應(yīng)的設(shè)備驅(qū)動程序,然后讀取數(shù)據(jù)結(jié)構(gòu)file_operations中相應(yīng)的函數(shù)指針,最后把控制權(quán)就交給該指針所指向的函數(shù)[3]。因此nRF24L01射頻模塊的驅(qū)動程序的主要工作就是編寫子函數(shù),并填充file_operations的各個域。主要包括open()、read()、ioctl()、pol()l、write()等函數(shù)。 調(diào)用 ioctl()函數(shù)可為用戶程序提供各種硬件控制的操作,從而滿足模塊在不同情況下的應(yīng)用。
應(yīng)用程序在打開設(shè)備文件時需要調(diào)用open()函數(shù)。文中open()的主要功能:首先,通過函數(shù) ioremap()完成 SPI物理地址到虛擬地址的重映射操作并使能SPI時鐘;然后,對S3C2440的SPI寄存器和S3C2440與nRF24L01的接口進行設(shè)置。打開設(shè)備的時候先使片選信號線失效,當具體對從設(shè)備操作時再使之有效。最后,初始化信號量和等待隊列,并且調(diào)用函數(shù)request_irq()來注冊中斷處理例程。打開設(shè)備的具體流程如圖2所示。
nRF24L01的 IRQ引腳根據(jù)nRF24L01控制寄存器的不同配置可以代表不同突發(fā)情況的中斷事件:nRF24L01在發(fā)送模式下成功發(fā)送數(shù)據(jù)中斷;nRF24L01在接收模式下正確接收數(shù)據(jù)中斷;nRF24L01在發(fā)送模式下,達到最大重傳次數(shù)中斷[2]。中斷處理函數(shù)主要完成區(qū)分中斷類型,清除中斷標志,設(shè)置全局變量的功能。
圖2 open函數(shù)的流程圖Fig.2 Flow chart of the function open
應(yīng)用程序?qū)RF24L01射頻模塊這個設(shè)備進行操作時,使用select()或poll()系統(tǒng)調(diào)用查詢是否可對其進行訪問可以提高內(nèi)核運行效率[3]。這個系統(tǒng)調(diào)用進而執(zhí)行內(nèi)核中射頻模塊驅(qū)動程序中的poll()函數(shù)。Linux內(nèi)核中poll()函數(shù)用來監(jiān)測文件的狀態(tài),在文件的狀態(tài)未發(fā)生變化且未超時的情況下它的用戶態(tài)select()函數(shù)將一直阻塞當前進程的運行。若射頻模塊作為2.45G無線通信的接收單元時,該函數(shù)用于和中斷函數(shù)配合,使得應(yīng)用系統(tǒng)只有在接收到發(fā)射單元發(fā)送的數(shù)據(jù)時才會向下執(zhí)行,其他時候則處于阻塞狀態(tài)。poll()函數(shù)的部分代碼如下:
當用戶空間調(diào)用poll函數(shù)返回文件為可讀或可寫狀態(tài)時,則調(diào)用ioctl()函數(shù)中定義的相關(guān)命令對射頻模塊接收或發(fā)送的數(shù)據(jù)進行處理。
ioctl()函數(shù)主要由一些switch分支選擇語句構(gòu)成,用于配置設(shè)備的相關(guān)參數(shù)。對于nRF24L01射頻模塊來說由于它可以工作于“ShockBurst?”和增強型“ShockBurst?”這兩種方式,通過自定義的SET_NRFMOD命令來進行設(shè)置,可以通過設(shè)置nRF24L01的寄存器EN_AA,和自動重傳寄存器來進行選擇[2]。
在控制函數(shù)中也可以實現(xiàn)對射頻模塊設(shè)備文件進行讀寫操作的命令。讀寫操作的命令與file_operations結(jié)構(gòu)中read()和write()函數(shù)的原理相同,都是將應(yīng)用程序要傳送數(shù)據(jù)通過函數(shù) copy_from_user()或 get_user()傳到內(nèi)核空間。 然后把數(shù)據(jù)調(diào)用送到設(shè)備或芯片。讀操作的功能與寫相反,它讀取設(shè)備的相關(guān)信息,調(diào)用 copy_to_user()或 put_user()把數(shù)據(jù)傳到用戶空間。
為了創(chuàng)建唯一的控制命令號以避免與內(nèi)核中已有的命令相沖突,可以把每個命令分成:幻數(shù)、序數(shù)、傳輸方向和參數(shù)大小這四個位段。這些命令的構(gòu)造放在nrf24l01.h頭文件中:
其中nrf24l01_config()函數(shù)的主要功能是根據(jù)用戶空間傳遞到內(nèi)核的參數(shù)對nRF24L01射頻模塊的寄存器進行賦值。而send_id()函數(shù)則是將要發(fā)送的數(shù)據(jù)寫入到nRF24L01的發(fā)送緩沖區(qū),然后設(shè)置發(fā)送模式信號線。send_id()函數(shù)如下:
測試時我們將nRF24L01設(shè)置為工作在“ShockBurst?”方式,在此工作方式下的數(shù)據(jù)包格式由前導(dǎo)碼、地址地、數(shù)據(jù)域和CRC校驗這4部分組成。其中前導(dǎo)碼由硬件自動進行處理,當nRF24L01在發(fā)送模式下自動加入前導(dǎo)碼,在接收模式下自動去除前導(dǎo)碼。它的作用是給芯片穩(wěn)定接收或發(fā)送預(yù)留一定的時間。地址長度為3~5字節(jié),它由寄存器SETUP_AW進行設(shè)定。數(shù)據(jù)域為發(fā)送包的有效載荷,長度可以為1~32字節(jié)。CRC校驗是可以選擇的,它由控制寄存器中的EN_CRC位來決定[2]。
文中采用如圖3的系統(tǒng)結(jié)構(gòu)對上面設(shè)計的驅(qū)動程序進行簡單測試。我們采用單發(fā)單收的方式進行測試。發(fā)射單元中,應(yīng)用程序調(diào)用ioctl()函數(shù)對內(nèi)核中與nRF24L01寄存器相關(guān)的參數(shù)進行設(shè)置。然后調(diào)用SENDID命令將要發(fā)送的數(shù)據(jù)發(fā)送出去。
圖3 測試系統(tǒng)結(jié)構(gòu)圖Fig.3 Schematic diagram of the test system
發(fā)送單元部分關(guān)鍵代碼如下:
接收單元程序流程圖如圖4所示,當nRF24L01設(shè)置為接收模式時,芯片內(nèi)部的基帶協(xié)議引擎會不停地搜索合法的數(shù)據(jù)包。若數(shù)據(jù)包的地址和較驗位匹配則將數(shù)據(jù)包的數(shù)據(jù)域放入接收緩沖區(qū),將置位nRF24L01的狀態(tài)寄存器的成功接收數(shù)據(jù)位(RX_DR),同時IRQ中斷信號線輸出為低電平。當接收到數(shù)據(jù)后會觸發(fā)中斷處理函數(shù),并使select()系統(tǒng)調(diào)用返回設(shè)備文件為可讀狀態(tài)。則從接收緩沖區(qū)中提取數(shù)據(jù),并將數(shù)據(jù)包中的數(shù)據(jù)通過串口發(fā)送到PC機進行顯示。測試系統(tǒng)的實驗截圖如圖5所示。
圖4 接收單元流程圖Fig.4 Flow chart of the receiving unit
圖5(a)是發(fā)射單元將發(fā)送數(shù)據(jù)加載到內(nèi)核并運行用戶空間進程的實驗結(jié)果截圖;圖5(b)是接收單元將接收到的數(shù)據(jù)通過串口傳輸?shù)絇C機進行顯示的實驗結(jié)果截圖。值得注意的是接收單元和發(fā)送單元的數(shù)據(jù)域長度寄存器的值要設(shè)置成一樣。若射頻模塊之間要實現(xiàn)一對多或多對多的方式進行通信,由于nRF24L01在接收模式下有6個數(shù)據(jù)通道可供選擇,因此可以將發(fā)射模塊發(fā)送數(shù)據(jù)包的地址設(shè)置為接收單元6個數(shù)據(jù)通道中某個未被利用的通道地址。從而實現(xiàn)一個nRF24L01可以接收6個發(fā)射單元的數(shù)據(jù)。若要實現(xiàn)接收單元可以對大于6個發(fā)射單元的數(shù)據(jù)進行接收處理則要采用一些防碰撞算法,如ALOHA算法和二進制搜索算法[6]。
圖5 測試系統(tǒng)的實驗截圖Fig.5 Experimental screenshot of the test system
文中介紹了nRF24L01[7]射頻模塊電路與驅(qū)動程序的設(shè)計,該射頻模塊體積小、功耗低,能夠廣泛地應(yīng)用于2.45G無線通信領(lǐng)域中。在嵌入式Linux平臺下,該射頻模塊以字符設(shè)備的文件形式提供給用戶空間,并給應(yīng)用程序提供了統(tǒng)一操作接口,從而可以加快具體項目的開發(fā)。經(jīng)測試若本射頻模塊采用PCB天線,空中傳輸速率為1 Mbps,輸出功率為0 dBm,接收與發(fā)送單元可以在7 m范圍內(nèi)實現(xiàn)通信。若引入防碰撞算法,則本設(shè)計可以用于RFID讀卡器等具體項目中。
[1]黃智偉.單片無線發(fā)射與接收電路設(shè)計[M].西安:西安電子科技大學(xué)出版社,2009.
[2]Semiconductor N.nRF24L01 Single Chip 2.4GHz Transceiver Product Specification[EB/OL].[2007].http://www.nordicsemi.com/eng/Products/2.4GHz-RF/nRF24L01.
[3]鄭強.Linux驅(qū)動開發(fā)入門與實戰(zhàn)[M].北京:清華大學(xué)出版社,2011.
[4]怯肇乾,陳永超.ARM-Linux下SPI設(shè)備的添加與驅(qū)動實現(xiàn)[J].單片機與嵌入式系統(tǒng)應(yīng)用,2012,12(4):80-81.
KAI Zhao-qian,CHEN Yong-chao.SPI device increment and driver design in ARM-Linux[J].Microcontrollers&Embedded Systems,2012,12(4):80-81.
[5]馬瑾,裴東興,張少杰.基于nRF24L01的無線溫濕度測試系統(tǒng)[J].電子設(shè)計工程,2012,20(2):64-66.
MA Jin,PEI Dong-xing,ZHANG Shao-jie.Wireless temperature and humidity test system based on nRF24L01[J].Electronic Design Engineering,2012(2):64-66.
[6]鄧一文,張紅雨,張鵬程,等.RFID高頻讀寫器防碰撞算法研究[J].電子設(shè)計工程,2011(19):31-34.
DENG Yi-wen,ZHANG Hong-yu,ZHANG Peng-cheng,et al.Study on the anti-collision algorithm of the RFID read/write device[J].Electronic Design Engineering,2011(19):31-34.
[7]陳暉,張軍國,李默涵,等.基于SIC89C52和nRF24L01的智能小車設(shè)計[J].現(xiàn)代電子技術(shù),2012(17):12-15.
CHEN Hui,ZHANG Jun-guo,LI Mo-han,et al.Design of smart car based on STC89C52 and nRF24L01[J].Modern Electronics Technique,2012(17):12-15.