日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

radio 事件_nRF52832/51822系列RADIO外设介绍/使用

發布時間:2025/3/21 编程问答 54 豆豆
生活随笔 收集整理的這篇文章主要介紹了 radio 事件_nRF52832/51822系列RADIO外设介绍/使用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

nRF52/51系列

以nRF52832的RADIO外設(下文簡稱RADIO)為例,操作寄存器的方式介紹和使用該外設;

目的在于充分認識RADIO外設,和記錄自己走過的坑;

全為自己理解,可能有不對的地方感謝指正。

1.空中無線協議

這是RADIO從天線發出的數據。順序固定但是內容可以配置。

*【PREAMBLE】為前導碼/前同步碼:根據地址自動設置,我們無需關心,但是它是8bit還是16bit可以通過PCNF0寄存器的PLEN配置。(除2Mb/s BLE模式外,前導碼長度都為1字節。 如果【ADDRESS】的第一位為0,則前導碼將設置為0xAA,否則0x55)PS:Ble_1Mbit為帶寬250 kHz,NRF_1Mbit帶寬160 kHz。

*【ADDRESS】是“接入地址”,由我們的代碼設置,這個地址由 BASE和PREFIX兩部分組成,BASE分為BASE0(4Bytes)、BASE1(4Bytes); PREFIX分為PREFIX0(4Bytes)、PREFIX1(4Bytes),BASEn 和 PREFIXn 的值可以在RADIO的寄存器中設置。

BASEn 和 PREFIXn要怎么組合成“接入地址”呢?見下表:

地址共有8種組合方式,啟用哪幾種方式可以在RADIO的寄存器中設置。(下面代碼啟用0方案)

NRF_RADIO->TXADDRESS = 0 << RADIO_TXADDRESS_TXADDRESS_Pos; //TX使用的某一個地址 NRF_RADIO->RXADDRESSES = RADIO_RXADDRESSES_ADDR0_Enabled << RADIO_RXADDRESSES_ADDR0_Pos; //RX使用的某些地址,可以是多個

其中PREFIXn固定貢獻1字節,BASEn可以貢獻2~4字節(NRF_RADIO->PCNF1中的BALEN設置)一起組成“接入地址”,所以“接入地址”長度范圍為 3~5字節。(PS:BLE廣播時“接入地址”為0x8E89BED6)

*【S0、LENGTH、S1、PAYLOAD】這些數據都是我們自己要傳輸的數據,NRF_RADIO->PACKETPTR寄存器保存這些數據的起始地址(指針);

S0、LENGTH、S1、PAYLOAD可以通過NRF_RADIO->PCNFn 寄存器配置 有無、bit大小、大小端。例如NRF_RADIO->PCNF0 = 0即沒有S0、LENGTH、S1,那么PACKETPTR指向的地址就全是PAYLOAD數據。

PCNF1寄存器中的STATLEN暫時不清楚是做什么的,可能是被一幀數據的固定長度,但是好像跟分組有關。

PCNF1寄存器中的MAXLEN可以設置PAYLOAD最大長度(最大255),如果過長會直接丟棄,防止RAM越界;所以S0+LENGTH+S1+PAYLOAD最大長度=258

*【CRC】CRC是硬件自動計算并加入的,可以配置其 有無、位數、多項式。

*數據白化:防止空中數據連續多0或1bit出現,可以進行數據白化,白化功能可以通過寄存器配置。配置之后,RADIO會自動進行白化和去白化。

2.RADIO狀態與發送數據

RADIO可以進入多個狀態,見下圖,圖中:圓角矩形為各個狀態、線上名稱為執行某種動作、帶 / 符號的為RADIO產生的事件

以發送一幀數據為例,分析要執行的操作 和 RADIO的狀態:

要讓RADIO發出數據,RADIO必須要進入 [ TX ] 狀態(圖中右上角)。

第一步:初始化各個參數后(還要使能使用外部32M時鐘),此時RADIO處于[DISABLED]狀態,執行下面的代碼

NRF_RADIO->EVENTS_READY = 0; //清除標志位 NRF_RADIO->TASKS_TXEN = 1; //使能TX while(NRF_RADIO->EVENTS_READY == 0); //等待READY事件:就緒

RADIO將會啟動TXRU,成功后將產生READY事件,此時RADIO處于[TXIDLE]狀態,可以進行 數據傳輸。

第二步:處于處于[TXIDLE]狀態后,通過START任務啟動RADIO,注:RADIO的EasyDMA使用相同的PACKETPTR來接收和發送數據包。 每次通過START任務啟動RADIO之前,CPU都應重新配置此指針。

NRF_RADIO->EVENTS_END = 0; //清除標志位 NRF_RADIO->TASKS_START = 1; //開始發送數據 while(NRF_RADIO->EVENTS_END == 0); //等待產生END事件:發送完成

這時RADIO將會處于[TX]狀態并自動發送數據。發送完成后將產生END事件,RADIO回到[TXIDLE]狀態。這時可以再次更新要發送的數據,然后再次執行第二步發送、或可以執行下面的代碼結束發送狀態。

NRF_RADIO->EVENTS_DISABLED = 0; NRF_RADIO->TASKS_DISABLE = 1; while(NRF_RADIO->EVENTS_DISABLED == 0);//等待停止

等待生成DISABLED事件,RADIO將會回到[DISABLED]狀態。

PS:發送過程其他狀態也會產生相應的事件:發送完ADDEESS、發送完PAYLOAD;所有事件可以啟用對應的中斷。。。上面的過程可以見下面的時序圖:

優化:

上面的過程中,執行第一步需要等到產生READY事件后,才能執行第二步的TASKS_START = 1,這個過程會有一定的延時,那么RADIO可不可以自動執行這個過程呢?就是:產生READY事件后,自動執行START,答案是可以的,詳見NRF_RADIO->SHORTS寄存器,里面有各種自動執行的配置,優化后的發送過程,見下圖

上圖中READY--START、END--DISABLE(第二次END)就是使用了這個功能,配置代碼如下:

NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Enabled << RADIO_SHORTS_READY_START_Pos; //READY后自動開始執行START| RADIO_SHORTS_END_DISABLE_Enabled << RADIO_SHORTS_END_DISABLE_Pos; //END后,自動讓DISABLE

所以此時發送代碼就可以精簡為:

void RADIO_SendStart(void) { NRF_RADIO->PACKETPTR = (uint32_t)&TxBuff; //每次通過START任務啟動RADIO之前,CPU都應重新配置此指針//此時RADIO要處于DISABLE或 TXIDLE狀態 (RXIDLE應該也可以未測試)NRF_RADIO->EVENTS_DISABLED = 0; //清除標志位NRF_RADIO->TASKS_TXEN = 1; //開始后會內部自己操作 while(NRF_RADIO->EVENTS_DISABLED == 0); //等待事件,RADIO回到DISABLE狀態***開啟END事件中斷后可以不用死循環等待 }

3.RADIO狀態與接收數據

RADIO能夠接收數據包之前,它必須處在[RX]模式下

進入[RX]狀態方式和TX類似,見下面的時序圖:

代碼如下(沒有使能NRF_RADIO->SHORTS相關功能):

void RADIO_ReceiveStart(void) {NRF_RADIO->EVENTS_READY = 0; //清除標志位NRF_RADIO->TASKS_RXEN = 1; //使能RXwhile(NRF_RADIO->EVENTS_READY == 0); //等待READY事件:就緒NRF_RADIO->EVENTS_END = 0; //清除標志位NRF_RADIO->TASKS_START = 1; //開始發送數據while(NRF_RADIO->EVENTS_END == 0); //等待產生END事件:接收完成NRF_RADIO->EVENTS_DISABLED = 0;NRF_RADIO->TASKS_DISABLE = 1;while(NRF_RADIO->EVENTS_DISABLED == 0);//等待停止 }

時序圖中的 ‘X’表示從START開始,直到RADIO收到帶有有效前同步碼(P)的數據包;

直到收到并校驗CRC為止,RADIO產生END事件,表示RX接收一幀完成。

優化:

和TX過程一樣,可以讓RADIO自動完成一些狀態的切換,比如READY--START、END--DISABLE

所以此時接收代碼就可以精簡為:

void RADIO_ReceiveStart(void) {NRF_RADIO->PACKETPTR = (uint32_t)&RxBuff; //每次通過START任務啟動RADIO之前,CPU都應重新配置此指針NRF_RADIO->EVENTS_END = 0U;NRF_RADIO->TASKS_RXEN = 1; while (NRF_RADIO->EVENTS_END == 0U);//等待事件,RADIO回到DISABLE狀態 }

進一步優化:

由于接收有效前同步碼(P)的數據包時間不定,可能會等待很久,所以代碼可能會阻塞很長時間,因此可以用END事件的中斷,就不用阻塞代碼了。

同樣的:TX也可以使用該中斷,來指示發送完成,所以發送也不需要等待END事件,TX功能被進一步優化。

void NRF_RADIO_init(void) {... ...... ...NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Enabled << RADIO_SHORTS_READY_START_Pos; //TXEN(RXEN) 后如果EVENTS_READY=1(處于TXIDLE(RXIDLE)狀態)后自動開始執行START=1(進行TX(RX))NRF_RADIO->INTENSET = RADIO_INTENSET_END_Enabled << RADIO_INTENSET_END_Pos;NVIC_SetPriority(RADIO_IRQn, 1);NVIC_ClearPendingIRQ(RADIO_IRQn);NVIC_EnableIRQ(RADIO_IRQn); } void RADIO_IRQHandler(void) {if(NRF_RADIO->EVENTS_END) //接收 或 發送 完成{NRF_RADIO->EVENTS_END = 0;//-----接收 或 發送 完成 相關代碼------------ } } void RADIO_ReceiveStart(void) {NRF_RADIO->PACKETPTR = (uint32_t)&RxBuff; //每次通過START任務啟動RADIO之前,CPU都應重新配置此指針NRF_RADIO->EVENTS_END = 0;NRF_RADIO->TASKS_RXEN = 1; } void RADIO_SendStart(void) { NRF_RADIO->PACKETPTR = (uint32_t)&TxBuff; //每次通過START任務啟動RADIO之前,CPU都應重新配置此指針//此時RADIO要處于DISABLE或 TXIDLE狀態 (RXIDLE應該也可以未測試)NRF_RADIO->EVENTS_END = 0; //清除標志位NRF_RADIO->TASKS_TXEN = 1; //開始后會內部自己操作 }

4.其他遺留問題

4.1 RX過程的如果CRC校驗不通過,會不會也產生END中斷?

4.2 RX要怎么實現地址自動過濾?也就是自動進行地址匹配?如果地址不正確則放棄本次數據。

可能是用DACNF選擇,但是 DAB與DAP又有啥用呢?

5.其他選擇

當然也可以直接使用Nordic SDK中的外設庫進行上面的設置,這樣就無需關心寄存器的事情。也可以是使用SDK中的esb庫,可以有更多實用的功能,但是代價就是要額外使用別的外設,比如 PPI、NRF_TIMER、SWI

總結

以上是生活随笔為你收集整理的radio 事件_nRF52832/51822系列RADIO外设介绍/使用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。