1. 程式人生 > >nRF24L01+如何檢測通道被佔用-RSSI暫存器實戰分享

nRF24L01+如何檢測通道被佔用-RSSI暫存器實戰分享

檢測通道佔用的需求場景

在使用nRF24L01模組做一對多或多對一的組網通訊中,大家都會擔心一個問題就是在傳送的時候,希望不要有其他的模組也進行傳送,因為這樣就會使無線訊號發生碰撞,通道被堵塞,造成通訊失敗。

為了避免這種情況發生,就希望在傳送前能知道當前通道是否處於空閒,如果空閒就傳送,否則就等待一會,直到空閒下來再執行傳送。利用這個機制,可以很大程度上規避碰撞的發生。

在nRF24L01+中怎樣知道通道被佔用了

在nRF24L01+中有個RSSI暫存器,地址是0x09,該暫存器的0號位是代表當前通道訊號強度的。當接收訊號強度小於-60dBm時0號位為0,大於-60dBm時為1,該暫存器7-1號位是保留位,固定為0。這樣我們通過直接讀取該暫存器的值是0還是大於0就知道通道是否被佔用了。

下面是該暫存器在一些模組廠家官方例程裡的定義:

#define RPD         0x09            //接收功率檢測暫存器

#define RSSI        0x09            //接收功率檢測暫存器

下面是通過讀暫存器函式讀取該暫存器的狀態值的程式碼:

StatusRPD = nRF24L01P_Read_Reg(RPD);        //如果定義的是RSSI,那語句中RPD換成RSSI

通過上面語句得到的StatusRPD值,如果大於0則是通道被佔用,在邏輯程式碼中通過這個判斷就可以識別通道是否被佔用了。也可以在傳送前用迴圈等待這個值的變化,直到為0時進入傳送狀態。如下面的程式碼:

while(nRF24L01P_Read_Reg(RPD));

為什麼用迴圈等待,有時候會死迴圈(一直返回1)

在實際應用中,使用上述方法的確可以得到當前的通道訊號強度,達到判斷通道是否佔用的目的。但是在迴圈等待的時候,偶爾會出現死迴圈的現象。也就是讀回來的狀態值一直是1,但是的確沒有模組在傳送,已經將其他模組全部斷電了,周圍也沒有強訊號干擾,那麼問題出在哪裡呢?

仔細檢視晶片手冊,只找到下面這段話:

在接收模式下,可以通過RSSI暫存器檢測接收訊號功率。當接收到的訊號強度大於-60dBm時,RSSI暫存器的RSSI位的值將被設定為1。否則,RSSI=0。。RSSI暫存器的更新方法有兩種:當接收到有效的資料包後,RSSI會自動更新,此外,將晶片從RX模式換到Standby模式時RSSI也會自動更新。RSSI的值會隨溫度的變化而變化,範圍在±5dBm以內

經過仔細分析和反覆試驗,理解了這段話所描述的具體內涵:
1、這個訊號強度檢測必須在接收模式下進行,在傳送模式下是不準確的。
2、並不是無論什麼情況下,這個暫存器都會被更新,只有CE由1變為0時才更新一次;或者在接收到有效資料的時候,會自動更為1。
3、當收到有效資料將該暫存器置1後,只有再接收FIFO暫存器的資料被讀出後,才會變為1,否則你變化幾次CE都無效(這是手冊沒有提到的,多數會踩到這個坑)。

上面的死迴圈情況一般發生在執行傳送的前夕,剛好收到一個有效資料時,RSSI暫存器被置1,而程式碼正在處理髮送,又沒有去讀出資料,所以就一直保持著1,所以迴圈條件一直滿足,就成了死迴圈了。

解決辦法建議是在檢測到為RSSI為1的時候,判斷一下是否收到資料,如果收到資料先讀出來,至於讀出來的資料要不要處理,根據您自己的業務邏輯決定即可。然後操作一次CE引腳,再次更新檢測一下是否有訊號佔用通道。此方法經過實際應用是有效的