1. 程式人生 > >STC89C52 STC89LE52 NRF24L01無線 教程 (二)

STC89C52 STC89LE52 NRF24L01無線 教程 (二)

原帖地址:http://www.dowellbbs.com/forum.php?mod=viewthread&tid=570&extra=page%3D1 程式下載地址:http://www.dowellbbs.com/forum.php?mod=viewthread&tid=571&extra=page%3D1 接前一篇文章 可以看到它的暫存器偏移是0x01,這裡說明一下,如果想要進行寫操作那麼操作的暫存器地址是WRITE_REG + EN_AA,也就是EN_AA加上寫指令的基地址,若是讀操作那麼是READ_REG + EN_AA,也就是EN_AA加上讀指令的基地址。 我們看看EN_AA這個暫存器的功能是什麼。它的位為8位初始化的值為00111111即0x3f,每個位的功能上表已經很詳細了。 這個送的資料是0x01,那麼表示什麼意思呢?意思是允許資料通道0自動應答,而其他的通道禁止,明白了吧。其他的都是這個樣子滴。 這是NRF24L01設定發射模式時的初始化過程。下面我們看看怎麼用NRF24L01進行無線資料發射傳輸。 我們從主函式main開始。

主函式很簡單,我們為您提供了兩個模式的發射方式:手動發射(按鍵控制)和自動發射(每隔一段時間傳送一次資料)。  
這是模式1,該模式為自動發射。可以看到主函式呼叫的就是模式1,對於模式0手動方式,大家把主函式的Mode1改為Mode0就可以驗證了。詳細請看程式原始碼。 在Mode1()這個函式中我們看看是怎麼樣的一個操作順序。先延時1500ms左右,然後裝載資料到NRF24L01,LED的操作就很簡單了只是一個提示的作用,最後再清除NRF24L01的狀態標誌位,為下一次傳送資料準備。大家要了解資料的傳送是這個樣子的。 我們來看看NRF24L01_TxPacket()這個函式。
註釋的部分是裝載接收端的地址,也就是為應答訊號服務的,由於在初始化的時候已經初始化過了,所以這裡可以不需要,但是當您使用NRF24L01跟多的功能時,如使用了多通道通訊,需要應答時,這句就有用了,需要設定為對應接收通道的地址才能收到應答訊號。這些功能大家知道就可以了,本教程也是讓大家會用NRF24L01,後續還是靠大家自行努力了。 接著是裝載資料了,WR_TX_PLOAD是裝載資料的命令地址,tx_buf是接收的資料指標,TX_PLOAD_WIDTH是指要傳送的資料位元組數。定義如下:

注意TX_PLOAD_WIDTH最大為32位元組,不得超過此數。 資料裝載完成後需要的是傳送命令了。 這句就是設定了為傳送的狀態,在CE被拉高的時間裡自動啟動傳送。那麼緊接著CE=1就是此目的了。
上面的三句用於傳送完成判斷以及中斷狀態的清除,為下次傳送準備。
CONFIG為什麼設定資料為0x5e(0101 1110)就是傳送呢,那麼看下這個暫存器各個位的功能就明白了。
看看最低位的功能:1 接收模式  0 發射模式,這明白了吧。其他位大家自己看看是什麼功能吧。 這樣一個完整的發射過程就完成了,剛才說了Mode1()是迴圈發射模式,一次完成後就會進入下一次發射了。 那麼到這裡我們的專案任務算是完成了一半了,還剩下另一半了。
看了發射模式之後,我們再來看接收模式就不會很困難了。 接收模式的配置初始化為:

1.             設定TX節點的地址,也就是發射地址,接收端需與這個地址相同,否則接收不到資料。在接收模式中此配置可不用。暫存器為:TX_ADDR 2.             設定RX節點的地址,也就是接收時的地址,如果是在發射模式下那麼功能是為自動應答服務的(AUTO ACK)。暫存器為:RX_ADDR_P0 3.             允許AUTO ACK功能,意思是傳送資料後都會等待接收端的應答訊號,目的是保證資料正確傳送。暫存器為:EN_AA 4.             設定允許的接收通道,總共有6個通道,我們只使用通道0,其他通道的功能應用大家熟悉了NRF24L01之後嘗試吧。暫存器為:EN_RXADDR 5.             配置自動重發次數。在接收模式中此配置可不用。暫存器為:SETUP_RETR 6.             選擇通訊的頻率。暫存器為:RF_CH 7.             設定接收通道0的接收資料有效寬度,與第四步對應。暫存器為:RX_PW_P0 8.             配置發射的引數,主要為低噪放大器增益、發射的功率、無線傳輸的速率。暫存器為:RF_SETUP 9.             配置收發狀態(這時配置為接收模式),CRC校驗模式以及收發狀態響應方式。發射模式和接收模式在初始化時只要這裡設定為接收模式即可,也只有這裡不一樣,其他配置都是一樣的(把配置都設定成一樣的)。暫存器為:CONFIG 10.          清除NRF24L01的指定通道中斷狀態標誌,注意傳送和接收這部分清除的通道的選擇必須一致。暫存器為:STATUS
為此操作起來就更加簡單了。從上面的初始化方式我們可以看到接收與發射的設定基本一致,只是接收模式中CONFIG暫存器的最低位變成高位即可,另外設定TX地址和設定重發次數,對於接收時也是無關緊要的,所以設定不設定我們可不比理會,當然直接刪除也是沒問題的。在接收模式中仍然使用發射模式下的初始化函式Init_NRF24L01(),我們的例程就是如此。 前面說到發射與接收模式的不同就在於CONFIG這個暫存器的設定不同,發射模式這個暫存器的最後一位需要置0,那麼接收就得置1,所以在判斷接收前把這個位設定一下不就可以了。 我們寫一個函式來實現這個功能:
在接收模式中我們最需要注意的就是這個接收模式的設定了。向CONFIG些0x3f就可以把最後一位設定為1了,且選擇接收到資料時IRQ引腳變低,這樣就成了接收模式了。 我們也從主函數出發,看看是怎麼操作的。
前面的初始化我們需要了解的是InitUSART()這個函式,我們專案最開始的要求有一項是接收端接收到的資料需要傳送到PC進行檢視,InitUSART()這個函式就是初始化串列埠通訊的。看它的原型:
這個初始化就不多說了,對於不同的波特率使用  這兩個巨集定義就行了,FOSC表示當前系統時鐘,BAUD表示需要的波特率。注意使用的是定時器1而不是定時器0。 串列埠傳送資料的函式是Rx_Byte()原始碼如下:
只要按照Rx_Byte(Dat)這樣呼叫就能把Dat這個資料傳送到PC了,PC需要用串列埠助手來檢視資料,我們使用的STC-ISP下載軟體即可使用,設定如下:
選擇到串列埠助手介面,在下面設定COM口和波特率,其他預設就可以了。點選  這個按鈕就可進入串列埠助手模式了。 我們接著看主函式的程式碼,LED=1是熄滅LED的,如果接收不到資料那麼是長滅的狀態,接收到資料且資料完全正確後才被點亮一段時間(閃爍一下的效果)用於提示。 緊接著是  這個if條件語句,它就是查詢判斷NRF24L01的接收狀態的。我們來看著這個被呼叫的函式:
這句用來判斷是否有資料的接收,前面我們配置中開啟了接收中斷,也就是說當有資料接收後,這個引腳會變成低電平,由NRF24L01輸出拉低的。這樣判斷相對於判斷NRF24L01內部的狀態效率會更高。 是讀取NRF24L01的狀態,目的是判斷是否有資料接收。為什麼要加上這句,還要判斷內部狀態呢。答案是:這句不是必須的,但如果你想確實保證正確的資料接收狀態也未嘗不可(相當於一個保險,O(∩_∩)O~),當然了,刪除也是可以的,但是這個判斷24L01內部狀態和判斷中斷引腳的方法必須保留一個,大家知道有這樣的方法就行了  是STATUS的巨集定義,是狀態暫存器的地址。 SPI_Read()的原始碼為:
前面說了所有的暫存器操作都是先設定暫存器地址,然後在寫(或讀)資料或命令()狀態。那麼這裡呢SPI_Read()這個函式就不說了。這裡值得一提的是  這個呼叫,傳入的實參是  ,有很多人不明白這個。這裡呢簡單說一下,可以看到對於讀來說這個資料是沒有用的,所以可以是任何的資料。然而習慣上都愛使用0xff,希望大家慢慢能夠明白。 在NRF24L01_RxPacket()這個函式中還有個特別的變數sta,它的宣告為: 可以看到這個使用了位操作,目的是什麼呢?這樣可以使位操作變得非常簡單,對於判斷狀態是很有用的。 我們來看STATUS這個暫存器的意義: 可以看到對於接收我們需要判斷RX_DR這個位是否為1,為1就表示有資料了。那麼用這個定義  就可以直接訪問sta這個變數的第七位了,很方便,也不用使用位運算來實現了。 當查詢到有資料了就會呼叫  讀出資料放到rx_buf中也就是主函式的RxBuf[]中了(rx_buf指向的地址為RxBuf[])。這樣就完成了資料的讀出操作,下面是置位  這個接收完成且成功標誌位。 完成接收後不要忘記狀態的清除操作,為下次接收準備。
在NRF24L01_RxPacket()這個函式中的最後就是返回ReceiveComplete_Flag這個變量了。在主函式中用於判斷是否有資料接收成功。 若接收資料成功了,那麼我們接著看主函式。在專案的開始我們要求傳送到PC端進行接收資料的檢視,為此我們用下面的程式碼實現:
32次迴圈依次把接收到的資料通過Rx_Byte()這個函式由串列埠傳送到PC。 要求中還有一個是要求是檢驗接收的資料是否與傳送端完全一樣,這個怎麼完成呢?思路是這樣的:我們也定義一個數組CheckBuf[],這個陣列中的資料與傳送端傳送的陣列資料完全一樣,然後把接收陣列RxBuf[]中的資料與CheckBuf[]一一對比即可達到檢驗的目的了。接收和傳送端的陣列資料如下圖: 傳送端資料:
接收端用於檢測的資料:
對於這個檢驗程式碼如下:
以上的設計思路為:在向PC每傳送一個位元組的資料,都會檢測一次RxBuf[]接收緩衝中的資料,如果相等那麼Right_Count正確個數計數器會自加一,32個數據向PC端傳送完成後,檢驗比較也就完成了,如果相等那麼Right_Count將會等於32。然後再判斷Right_Count是否大於等於32(特別建議:如果在判斷一個變數是否等於某個數時,儘量使用大於等於或者小於等於判斷的方法,可防止出錯,是對於程式安全穩定來說的),就可知道接收的資料是否通過檢測沒有錯誤了。如果完全相等,那麼會有LED=0執行,LED被點亮用於提示校驗成功。 好啦到這裡就講解完成了,大家就仔細研究研究吧。多玩玩程式。
PC端接收的資料如下:
可以看到資料也是完全正確的 經過我們的下載測試,LED指示也是完全正確的。大家可以把這個程式下載來看看了。 到這裡對於這個小專案的要求就都完成了。
您如果成功了是不是很開心呢,O(∩_∩)O! 最後提示,若您是自己搭建的,那線的連線不要錯了哦!若您使用我們的板子有任何問題,請您及時聯絡我們。
之後我們還會推出更多關於NRF24L01有趣的應用的,敬請期待!這算是個入門的教程,大家多多支援。我們水平也是有限的不可能面面俱到,有問題或者錯誤請聯絡我們,感激不盡。