哈哈哈哈哈操欧洲电影,久草网在线,亚洲久久熟女熟妇视频,麻豆精品色,久久福利在线视频,日韩中文字幕的,淫乱毛视频一区,亚洲成人一二三,中文人妻日韩精品电影

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

【CW32無線抄表項目】CW32搭配PAN3031通信教程

CW32生態(tài)社區(qū) ? 來源:CW32生態(tài)社區(qū) ? 2026-04-01 17:17 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

一、SPI通信基礎(chǔ)知識

SPI(Serial Peripheral Interface)是一種同步串行通信協(xié)議,常用于 MCU 與外設(shè)之間的高速通信。
SPI 通信通常包含以下信號線:
在本方案中:

CW32 作為 SPI 主機

PAN3031 作為 SPI 從機

SPI 通信由 CW32 主動發(fā)起

SCK(Serial Clock):由主機產(chǎn)生的時鐘信號

MOSI(Master Out Slave In):主機發(fā)送數(shù)據(jù)給從機

MISO(Master In Slave Out):從機發(fā)送數(shù)據(jù)給主機

CS/SS(Chip Select):片選信號,用于選擇通信的從機

二、IQR外部中斷知識

IRQ(Interrupt Request)是外設(shè)向 MCU 發(fā)出的中斷請求信號。

PAN3031 通過 IRQ 引腳向 CW32 通知以下事件(示例):

有數(shù)據(jù)可讀取

狀態(tài)發(fā)生變化

需要 MCU 處理的事件發(fā)生

MCU 在檢測到 IRQ 觸發(fā)后,會進(jìn)入中斷服務(wù)函數(shù)(ISR),通常只做:

事件標(biāo)志位設(shè)置

簡單狀態(tài)記錄

不建議在中斷中直接進(jìn)行 SPI 通信,而應(yīng)在主循環(huán)或任務(wù)中處理。

三、CW32與PAN3031的通信整體流程

CW32 與 PAN3031 的通信方式為:

以兩塊 CW32 搭配兩塊 PAN3031 為例:

主機端(Master):

A1: 第一塊 CW32(大腦/指揮官)

A2: 第一塊 PAN3031(嘴巴和耳朵/無線網(wǎng)卡)

從機端(Slave):

B1: 第二塊 CW32(大腦/指揮官)

B2: 第二塊 PAN3031(嘴巴和耳朵/無線網(wǎng)卡)

通信全過程分為兩部分:

第一段路:大腦指揮網(wǎng)卡 (板級有線通信 - SPI)

A1 與 A2 之間(以及 B1 與 B2 之間)是通過 SPI 接口 連接的。 這就像是老板(CW32)通過內(nèi)線電話指揮秘書(PAN3031)。

物理連接:它們之間用杜邦線線連接(CSN、SCK、MOSI、MISO)。

通信方式:

A1 (CW32) 發(fā)送指令:通過 MOSI 線告訴 A2 “把數(shù)據(jù)發(fā)出去”或者“把配置改一下”。

A2 (PAN3031) 反饋數(shù)據(jù):通過 MISO 線把收到的無線數(shù)據(jù)傳回給 A1。

通知機制 (IRQ):當(dāng) A2 收到無線數(shù)據(jù)或者發(fā)完數(shù)據(jù)時,它會拉動 IRQ 引腳(按門鈴),告訴 A1 “有情況,快來處理”。

第二段路:網(wǎng)卡隔空對話 (板間無線通信 - 2.4G RF)

A2 與 B2 之間是通過 2.4GHz 無線射頻信號 連接的。 這就像是兩個拿著對講機的人在隔空喊話。

物理連接:沒有導(dǎo)線,靠天線發(fā)射電磁波。

通信方式:

調(diào)制 (Tx):A2 把 A1 給它的數(shù)字信號(0101...)轉(zhuǎn)換成高頻無線電波發(fā)射出去。

解調(diào) (Rx):B2 的天線捕捉到這些電波,把它還原成數(shù)字信號(0101...)。

特點:這是半雙工的,也就是說 A2 在說的時候,B2 必須在聽;不能兩個人同時說話,否則信號會打架(同頻干擾)。

完整的數(shù)據(jù)傳輸接力跑 (以主機發(fā)送 "kunkun" 為例)

整個通信過程就像一次接力賽,數(shù)據(jù)是從 A1 的內(nèi)存 跑到 B1 的內(nèi)存:

打包 (A1):主機 CW32 (A1) 把字符串 "kunkun" 準(zhǔn)備好。

下達(dá)指令 (A1 -> A2):A1 通過 SPI 接口,把數(shù)據(jù)寫入 A2 的發(fā)送緩沖區(qū),并命令 A2:“發(fā)射!”

發(fā)射 (A2 -> 空中):A2 啟動射頻電路,把數(shù)據(jù)變成無線電波發(fā)向空中。

接收 (空中 -> B2):從機 PAN3031 (B2) 的天線捕捉到信號,解析出 "kunkun",存入自己的接收緩沖區(qū)。

按門鈴 (B2 -> B1):B2 拉高 IRQ 引腳,觸發(fā) B1 的外部中斷。

讀取 (B1 -> B2):從機 CW32 (B1) 收到中斷后,通過 SPI 接口 讀取 B2 緩沖區(qū)里的數(shù)據(jù)。

處理 (B1):B1 拿到了 "kunkun"。

四、SPI硬件連接說明

SPI 硬件連接如下(示例):

CW32 引腳 PAN3031 引腳 說明
SCK SCK SPI 時鐘
MOSI MOSI 主發(fā)從收
MISO MISO 從發(fā)主收
GPIOx CS SPI 片選
GPIOy IRQ 外部中斷

CS 信號通常為 低電平有效,需由軟件控制。

五、SPI工作模式說明

SPI 通信就像兩個人跳繩,必須在同一個節(jié)奏點上起跳才不會絆倒。為了讓 CW32(主機)能正確讀寫 PAN3031(從機),雙方的配置必須完全一致。

PAN3031 使用的是標(biāo)準(zhǔn)的 SPI Mode 0,CW32 初始化 SPI 時必須嚴(yán)格按照以下參數(shù)配置:

SPI 模式:Mode 0

時鐘極性 (CPOL) = 0:

表示 SCLK 時鐘線在空閑狀態(tài)(沒有傳輸數(shù)據(jù)時)保持 低電平 (Low Level)。

時鐘相位 (CPHA) = 0:

表示在時鐘的 第一個邊沿(對于 Mode 0 來說是 上升沿)進(jìn)行數(shù)據(jù)采樣(讀取數(shù)據(jù))。

而在第二個邊沿(下降沿)進(jìn)行數(shù)據(jù)切換(發(fā)送下一位數(shù)據(jù))。

數(shù)據(jù)位順序 (Bit Order):

MSB First(高位先發(fā))。

六、IRQ觸發(fā)方式說明

PAN3031 的 IRQ 信號為 上升沿 觸發(fā)。

CW32 需將對應(yīng) GPIO 配置為外部中斷輸入,并設(shè)置正確的觸發(fā)方式。

七、PAN3031模塊使用說明(詳細(xì)版)

PAN3031 SDK使用流程

初始化流程

wKgZO2nLyIGATcdrAABWJO81OQg291.jpg

參數(shù)配置流程

wKgZO2nM4J2AdkCgAAAzGVw1H_s625.jpg

wKgZPGnLyIKAEXUtAABDELgCPsc214.jpg

1. PAN3031_set_freq (設(shè)置中心頻率)

干什么用的: 設(shè)置模塊工作在哪個頻段(比如 2.4GHz、470MHz 等)。

小白比喻:調(diào)對講機頻道。如果主機在 1 頻道喊話,從機在 2 頻道聽,兩人永遠(yuǎn)對不上話。

2. PAN3031_set_code_rate (設(shè)置編碼糾錯率)

干什么用的: 決定在發(fā)送真實數(shù)據(jù)時,夾帶多少“冗余糾錯碼”。

小白比喻:給快遞包防震膜。空氣中干擾很多,容易丟包。糾錯率設(shè)得越高(膜包得越厚),就算數(shù)據(jù)在空中損壞了一點,接收端也能自己推算修復(fù)回來;但代價是有效數(shù)據(jù)的傳輸效率變低了。

3. PAN3031_set_bw (設(shè)置帶寬 Bandwidth)

干什么用的: 決定無線信號占據(jù)的頻率寬度。

小白比喻:修多寬的馬路。帶寬越大,數(shù)據(jù)傳得越快;但馬路越寬,越容易受到旁邊車道(其他無線電信號)的干擾,接收靈敏度會下降。

4. PAN3031_set_sf (設(shè)置擴(kuò)頻因子 Spreading Factor)

干什么用的: 這是擴(kuò)頻通信(如 LoRa 調(diào)制)里非常關(guān)鍵的參數(shù),決定每個數(shù)據(jù)符號的持續(xù)時間。

小白比喻:講話的語速。SF 值越大,相當(dāng)于你講話越慢、發(fā)音越長,哪怕距離很遠(yuǎn)、環(huán)境很吵對方也能聽清(穿墻能力大增);但缺點是一句話要說很久,模塊工作時間變長,非常費電。

5. PAN3031_set_tx_power (設(shè)置發(fā)射功率)

干什么用的: 設(shè)置芯片射頻引腳輸出的能量大小(比如 10dBm、22dBm)。

小白比喻:嗓門有多大。功率調(diào)得越高,信號覆蓋范圍越廣,但也意味著你的電池會被抽干得越快。

6. PAN3031_set_crc (設(shè)置 CRC 循環(huán)冗余校驗)

干什么用的: 開啟后,硬件會自動在數(shù)據(jù)包尾部追加一段校驗碼。

小白比喻:貼封條防偽。接收端拿到包裹后,會檢查封條是否完好。如果發(fā)現(xiàn)對不上,說明數(shù)據(jù)在空中被干擾串味了,直接丟棄,防止單片機讀到錯誤的 ADC 抄表數(shù)據(jù)。

圖片

發(fā)送流程

圖片

wKgZO2nLyIOAbQ0cAAA9WFzYDog316.jpg

接收流程

wKgZPGnLyIWAdlSZAABIBuBMt60678.jpg

wKgZO2nLyIWAY1sdAAAsqoqkbKw557.jpg

wKgZO2nLyIaAbgoJAAAackWkuLE697.jpg

PAN3031 部分SDK接口函數(shù)

圖片

agc(自動增益控制)

功能: 全稱 Automatic Gain Control。它會根據(jù)收到的無線信號強弱,自動調(diào)節(jié)內(nèi)部放大器的放大倍數(shù)。

小白比喻:“自動音量調(diào)節(jié)”。如果發(fā)射端離得很近,信號太強,它就調(diào)低增益防止“震耳朵”;如果離得遠(yuǎn)信號弱,它就自動調(diào)高增益,確保無論遠(yuǎn)近,芯片都能清晰地“聽見”數(shù)據(jù)。

AGC 的核心原理是一個 “檢測 -> 反饋 -> 調(diào)整” 的閉環(huán)系統(tǒng)。

技術(shù)實現(xiàn)流程:

信號進(jìn)入: 天線接收到的原始無線信號進(jìn)入芯片。

強度檢測: 芯片內(nèi)部有一個“偵察兵”(信號強度檢測器),實時測量這個信號的功率(也就是我們常說的 RSSI)。

比較判斷: 芯片內(nèi)部設(shè)定了一個“理想音量”范圍。

如果信號太強: 會導(dǎo)致后面的電路“破音”(飽和失真),數(shù)據(jù)就全亂了。

如果信號太弱: 背景噪音就會蓋過數(shù)據(jù)。

反饋調(diào)整: 偵察兵發(fā)現(xiàn)信號太強,就立刻下令讓 LNA(低噪聲放大器) 降低放大倍數(shù)(減小增益)。

發(fā)現(xiàn)信號太弱,就下令讓 LNA 全力放大(增大增益)。

antenna_init(天線初始化)

功能: 配置射頻端口和天線開關(guān)。

小白比喻:“切換車道”。無線芯片通常有一個天線,但有“發(fā)”和“收”兩條路。這個步驟是初始化天線開關(guān)的控制邏輯,確保你想發(fā)的時候數(shù)據(jù)能傳給天線,想收的時候天線信號能傳給芯片。

Antenna_init 的原理本質(zhì)上是 “單刀雙擲開關(guān)(SPDT)” 的邏輯配置。

技術(shù)實現(xiàn)流程:

鏈路分離: 無線芯片內(nèi)部其實有兩套完全獨立的系統(tǒng):發(fā)射機(TX)產(chǎn)生強大的信號,接收機(RX)負(fù)責(zé)捕捉微弱的信號。

物理矛盾: 但是,為了節(jié)省成本和空間,整個設(shè)備通常只有一根天線。

開關(guān)切換: 在天線和芯片之間,有一個射頻開關(guān)(RF Switch)。

發(fā)送時: 開關(guān)必須撥向“發(fā)射鏈路”,把功率放大器(PA)產(chǎn)生的信號推向天線。

接收時: 開關(guān)必須撥向“接收鏈路”,把天線捕捉到的微弱波浪送給接收器。

初始化保護(hù):antenna_init 就是在初始化階段,配置好控制這個“開關(guān)”的 GPIO 引腳邏輯。

wKgZPGnLyIaARBoQAABuCludVzw333.jpg

節(jié)能模式:芯片的“休息時間”

PAN3031_MODE_DEEP_SLEEP(深度睡眠)

狀態(tài): 芯片幾乎完全關(guān)閉,功耗降到最低(微安級)。

小白比喻:徹底關(guān)機。這是抄表系統(tǒng)最常用的狀態(tài)。電表每天 99% 的時間都應(yīng)該處于這個模式來省電。

PAN3031_MODE_SLEEP(睡眠)

狀態(tài): 功耗略高于深度睡眠,但保留了寄存器的配置。

小白比喻:電腦休眠。喚醒速度比深度睡眠快一點,不需要重新加載所有配置。

準(zhǔn)備模式:芯片的“熱身階段”

這三個 STB (Standby) 模式是處于休眠和工作之間的中間地帶,它們決定了芯片內(nèi)部哪些組件(如晶振、頻率合成器)是開著的。

PAN3031_MODE_STB1 / STB2

狀態(tài): 基礎(chǔ)待機。內(nèi)部晶振開始起振。

小白比喻:坐在板凳上熱身。雖然沒下場比賽,但已經(jīng)穿好運動鞋了。

STB1:深度省電的“淺睡”模式

在 STB1 模式下,芯片關(guān)閉了外部晶振,只靠內(nèi)部一個很弱的 RC 電路維持基本邏輯。

優(yōu)點: 非常省電,比 STB2 能多省下不少微安級的電流

缺點: 當(dāng)你需要發(fā)數(shù)據(jù)時,從 STB1 切換到 TX(發(fā)射)需要一段“暖機時間”,因為外部晶振從靜止到穩(wěn)定震蕩需要幾百微秒甚至毫秒級的時間。

STB2:隨時待命的“備戰(zhàn)”模式

在 STB2 模式下,芯片已經(jīng)把昂貴且精確的外部晶振給跑起來了。

優(yōu)點: 響應(yīng)極其靈敏。如果你在做一個需要頻繁快速回應(yīng)(比如 10ms 內(nèi)必須回信)的協(xié)議,STB2 是唯一的選擇。

缺點: 功耗相對較高。如果一直停在 STB2,你的電表電池可能撐不了幾年。

PAN3031_MODE_STB3

狀態(tài): 高級待機。頻率合成器(決定你發(fā)什么頻率)已經(jīng)鎖定。

小白比喻:在起跑線上蹲好了。這是進(jìn)入“發(fā)射”或“接收”之前的最后一站。在你之前的代碼里,進(jìn)入 rf_single_tx_data 之前都會先切換到這個模式。

工作模式:芯片的“上場比賽”

PAN3031_MODE_TX(發(fā)射模式)

狀態(tài): 功率放大器開啟,全力向天線推送電磁波。

小白比喻:放聲大喊。這是最費電的時刻,所以發(fā)送完數(shù)據(jù)一定要趕緊讓它睡覺。

PAN3031_MODE_RX(接收模式)

狀態(tài): 接收鏈路全開,實時捕捉空中的微弱信號。

小白比喻:豎起耳朵細(xì)聽。在抄表項目中,電表端通常只在發(fā)送完數(shù)據(jù)后的那幾百毫秒開啟這個模式來等確認(rèn)。

wKgZO2nLyIeAJAUFAAAWguGB0zk961.jpg

wKgZO2nM4J2AXHHIAAEWPTa_IvM214.jpg

wKgZPGnLyIiAf4dKAAAPChdL-IQ698.jpg

RF_PARA_TYPE_FREQ(中心頻率)

技術(shù)內(nèi)幕: 指無線電波能量最集中的那個點(例如 470MHz 或 433MHz)。

實戰(zhàn)要點:

必須匹配:主機和從機的頻率誤差不能超過一定范圍(通常是晶振精度的幾倍),否則由于“偏頻”會導(dǎo)致信號極差甚至搜不到包。

避開干擾:如果小區(qū)里有大量同頻段的無線設(shè)備,可以微調(diào)頻率(跳頻)來尋找一個“安靜”的頻道。

RF_PARA_TYPE_CR(編碼糾錯率)

技術(shù)內(nèi)幕: 全稱 Code Rate。它在原始數(shù)據(jù)中加入冗余的校驗位(例如 4/5 代表 4 位數(shù)據(jù)加 1 位冗余)。

實戰(zhàn)要點:

抗干擾性:設(shè)置越高(如 4/8),抗突發(fā)干擾能力越強,就算空中丟了幾位數(shù)據(jù),芯片也能靠算法補回來。

副作用:糾錯位越多,整個數(shù)據(jù)包就越長,空中飛行時間(ToA) 增加,從而增加功耗。

RF_PARA_TYPE_BW(帶寬)

技術(shù)內(nèi)幕: 指信號占據(jù)的頻率寬度(如 125kHz, 250kHz, 500kHz)。

實戰(zhàn)要點:

速率 vs. 靈敏度:馬路越寬(BW 大),車速越快(數(shù)據(jù)率高),但路上的噪音也多(底噪高,靈敏度差)。

抄表選擇:通常選擇較小的帶寬(如 125kHz)來換取更高的接收靈敏度,確保能穿透更厚的墻。

RF_PARA_TYPE_SF(擴(kuò)頻因子)

技術(shù)內(nèi)幕:Spreading Factor,是 LoRa/擴(kuò)頻通信的靈魂。它決定了一個數(shù)據(jù)符號被拉得有多長。

實戰(zhàn)要點:

穿墻神器:SF 越大(如 SF12),信號在噪聲中被識別的能力越強,距離翻倍。

功耗陷阱:SF 每增加一級,數(shù)據(jù)在空中停留的時間幾乎翻倍。這會導(dǎo)致 PAN3031 的發(fā)射電流持續(xù)時間變長,嚴(yán)重縮短電表壽命。

RF_PARA_TYPE_TXPOWER(發(fā)射功率)

技術(shù)內(nèi)幕: 芯片輸出信號的強度,單位通常為 dBm。

實戰(zhàn)要點:

按需調(diào)整:如果電表就在網(wǎng)關(guān)旁邊,沒必要開 20dBm(最大功率),調(diào)低功率能有效節(jié)省電量。

法規(guī)限制:不同國家和地區(qū)對不同頻段的最大功率有法律限制,開發(fā)時需查閱當(dāng)?shù)貥?biāo)準(zhǔn)。

RF_PARA_TYPE_CRC(循環(huán)冗余校驗)

技術(shù)內(nèi)幕: 在數(shù)據(jù)包末尾添加計算好的校驗碼。

實戰(zhàn)要點:

數(shù)據(jù)保真:無線環(huán)境非常臟,數(shù)據(jù)包很容易被干擾成亂碼。開啟 CRC 后,如果收到的包計算結(jié)果不符,硬件會自動丟棄,防止你的單片機讀到錯誤的“水費”或“電費”數(shù)據(jù)。

核心變量:內(nèi)部狀態(tài)記錄員

程序定義了兩個 static(靜態(tài))變量,它們就像是掛在實驗室門口的記事板,用來記錄無線模塊當(dāng)前的工作狀態(tài)。

packet_received:專門記錄接收的狀態(tài)。是收到了?還是超時了?還是出錯了?

packet_transmit:專門記錄發(fā)送的狀態(tài)。是正在發(fā)?還是發(fā)完了?

RxDoneParams:這是一個結(jié)構(gòu)體,它像是一個快遞暫存柜。當(dāng)收到新包裹(數(shù)據(jù))時,包裹的內(nèi)容、重量(長度)、信號強度等信息都會暫時存放在這里。

wKgZO2nM4J6ANxD4AAAuGjr91sE624.jpg

RADIO_FLAG_IDLE0 空閑。此時模塊沒活干,可以安排新任務(wù)

RADIO_FLAG_TXDONE1發(fā)送成功。信件已成功打向空中

RADIO_FLAG_RXDONE2接收成功。抓到了一個完整的有效數(shù)據(jù)包

RADIO_FLAG_RXTIMEOUT3接收超時。等了半天沒人理我,放棄等待

RADIO_FLAG_RXERR4接收錯誤。抓到了包,但數(shù)據(jù)內(nèi)容壞了(校驗失?。?/p>

RADIO_FLAG_PLHDRXDONE5報頭接收完成。 —— 報頭接收完成

wKgZO2nLyImAFMVHAAAR2iB0b7k386.jpg

wKgZPGnLyImAY3akAAATGCJdnqY939.jpg

(獲取函數(shù)):這是詢問窗口。比如 rf_get_recv_flag() 就是在問:“現(xiàn)在接收到哪一步了?”

(設(shè)置函數(shù)):這是更新窗口。比如 rf_set_recv_flag(status) 就是在通知系統(tǒng):“我已經(jīng)處理完這個包了,請把狀態(tài)重置為空閑?!?/p>

wKgZO2nLyImAVkvfAAALxPyneqE951.jpg

wKgZPGnLyIqAAdggAAAbknyI1Bo104.jpg

wKgZO2nLyIqAQCHJAAANhLSM8lg094.jpg

wKgZPGnLyIqAUPwaAAAL7g-aieA844.jpg

1. rf_enter_single_rx (進(jìn)入單次接收模式)

簡單理解: 這個函數(shù)相當(dāng)于讓無線模塊“張開耳朵聽一次”。

它的作用: 將模塊從空閑狀態(tài)切換到接收狀態(tài)。

它的執(zhí)行邏輯:

準(zhǔn)備: 同樣先進(jìn)入待機狀態(tài)并切換到發(fā)送模式。

點火: 調(diào)整振蕩器匹配發(fā)送頻率。

投遞: 調(diào)用 PAN3031_send_packet 正式把數(shù)據(jù)包打向空中。

記錄: 記錄下這次發(fā)送耗費的時間,方便后續(xù)計算功耗或排查延遲。

buf:要發(fā)送的“信件內(nèi)容”(數(shù)據(jù)緩沖區(qū)指針)。

size:這封信有多長(數(shù)據(jù)長度)。

tx_time:發(fā)送這封信花了多少時間(由函數(shù)自動計算并返回)。

熱身: 先進(jìn)入 STB3 (待機) 模式。

換向: 將射頻口切換到接收方向。

調(diào)頻: 調(diào)整內(nèi)部振蕩器 (VCO) 匹配接收頻率。

鎖定: 設(shè)置為 SINGLE (單次) 接收模式,意味著收到一個完整的數(shù)據(jù)包后,模塊會自動停下來,不會一直傻聽。

wKgZPGnM4J6AEJzdAADIcHlEbyk693.jpg


2. rf_single_tx_data (單次數(shù)據(jù)發(fā)送)
簡單理解: 這個函數(shù)相當(dāng)于“把寫好的信投遞出去”。

它的參數(shù):

它的執(zhí)行邏輯:

wKgZO2nLyIuAGHANAABFwN9LrgE608.jpg

wKgZPGnLyIuAB4FEAACZ9uRnLaI517.jpg

PAN3031 SDK示例加移植

wKgZO2nLyIyAd63yAACL-JYpGzs668.jpg

圖片

/* --- PAN3031 Tx-rx 模式示例程序 --- */
// 1. 初始化階段
ret = rf_init();                                        // 執(zhí)行射頻芯片初始化
if (ret != OK) {
    DDL_Printf(" RF Init Fail");                        // 如果初始化失敗,打印錯誤信息
    while (1);                                          // 程序在此死循環(huán),不再繼續(xù)運行
}
rf_set_default_para();                                  // 配置射頻芯片的默認(rèn)通信參數(shù)(頻率、功率等)
// 2. 初始數(shù)據(jù)發(fā)送
if (rf_single_tx_data(tx_test_buf, TX_LEN, &tx_time) != OK) { 
    DDL_Printf("tx fail rn");                         // 嘗試發(fā)送第一包數(shù)據(jù),若失敗則報錯
} 
else {
    txcnt++;                                            // 發(fā)送計數(shù)加 1
    DDL_Printf("Tx cnt %drn", txcnt);                 // 打印當(dāng)前發(fā)送次數(shù)

    while (RADIO_FLAG_IDLE == rf_get_transmit_flag());  // 等待硬件發(fā)送標(biāo)志位改變,確保發(fā)送動作完成
    rf_set_transmit_flag(RADIO_FLAG_IDLE);              // 手動將發(fā)送標(biāo)志位清零,準(zhǔn)備下次操作

    rf_sleep();                                         // 令射頻模塊進(jìn)入休眠狀態(tài)以省電
    rf_sleep_wakeup();                                  // 喚醒模塊,準(zhǔn)備切換到接收狀態(tài)
    rf_enter_single_timeout_rx(15000);                  // 開啟單次超時接收,設(shè)置超時時間為 15000 毫秒(15秒)
}
// 3. 主循環(huán)處理階段
while (1) {
    SysTick_Delay(5);                                   // 短暫延時,降低系統(tǒng)負(fù)擔(dān)

    // --- 情況 A:接收成功 ---
    if (rf_get_recv_flag() == RADIO_FLAG_RXDONE) {      // 判斷硬件標(biāo)志位是否為“接收完成”
        BSP_LED_Toggle();                               // 翻轉(zhuǎn) LED 燈狀態(tài),直觀顯示接收成功
        rf_set_recv_flag(RADIO_FLAG_IDLE);              // 清除接收標(biāo)志位

        // 打印信號質(zhì)量信息:信噪比 (SNR) 和 信號強度 (RSSI)
        DDL_Printf("Rx : SNR: %f ,RSSI: %f rn", RxDoneParams.Snr, RxDoneParams.Rssi);

        // 循環(huán)打印收到的原始十六進(jìn)制數(shù)據(jù)內(nèi)容
        for (i = 0; i < RxDoneParams.Size; i++) {
            DDL_Printf("0x%02x ", RxDoneParams.Payload[i]);
        }
        DDL_Printf("rn");

        rxcnt++;                                        // 接收成功計數(shù)加 1
        DDL_Printf("###Rx cnt %d##rn", rxcnt);

        rf_sleep();                                     // 接收任務(wù)完成,先進(jìn)入休眠
        rf_sleep_wakeup();                              // 喚醒,準(zhǔn)備下一次循環(huán)發(fā)送
        SysTick_Delay(3000);                            // 延時 3 秒后再進(jìn)行下一次動作

        // 成功接收后,再次發(fā)起數(shù)據(jù)發(fā)送(形成收發(fā)循環(huán))
        if (rf_single_tx_data(tx_test_buf, TX_LEN, &tx_time) != OK) {
            DDL_Printf("tx fail rn");
        } 
        else {
            txcnt++;
            DDL_Printf("Tx cnt %drn", txcnt);
            while (RADIO_FLAG_IDLE == rf_get_transmit_flag()); // 等待發(fā)送結(jié)束
            rf_set_transmit_flag(RADIO_FLAG_IDLE);
            rf_sleep();
            rf_sleep_wakeup();
            rf_enter_single_timeout_rx(15000);          // 再次進(jìn)入接收等待狀態(tài)
        }
    }
    // --- 情況 B:接收超時或出錯 ---
    if ((rf_get_recv_flag() == RADIO_FLAG_RXTIMEOUT) || (rf_get_recv_flag() == RADIO_FLAG_RXERR)) {
        rf_set_recv_flag(RADIO_FLAG_IDLE);              // 清除異常標(biāo)志位
        DDL_Printf("Rxerrrn");                        // 打印接收錯誤或超時提示

        rf_sleep();
        rf_sleep_wakeup();
        HAL_Delay(10000);                               // 出錯后延時 10 秒(避開干擾或重試間隔)

        // 即使失敗,也嘗試再次發(fā)送數(shù)據(jù)
        if (rf_single_tx_data(tx_test_buf, TX_LEN, &tx_time) != OK) {
            DDL_Printf("tx fail rn");
        } 
        else {
            txcnt++;
            DDL_Printf("Tx cnt %drn", txcnt);
            while (RADIO_FLAG_IDLE == rf_get_transmit_flag());
            rf_set_transmit_flag(RADIO_FLAG_IDLE);
            rf_sleep();
            rf_sleep_wakeup();
            rf_enter_single_timeout_rx(15000);          // 重新進(jìn)入接收等待
        }
    }
}

值得參考點

業(yè)務(wù)閉環(huán)完整: 涵蓋了“發(fā)送 -> 等待接收 -> 成功處理 -> 失敗/超時兜底”的完整通信全生命周期。
狀態(tài)切換規(guī)范: 在每次收發(fā)狀態(tài)切換前,都老老實實地調(diào)用了 rf_sleep() 和 rf_sleep_wakeup()。這種“先歸零再啟動”的做法能有效防止射頻芯片內(nèi)部狀態(tài)機卡死。
易讀性高: 純順序執(zhí)行邏輯,沒有復(fù)雜的結(jié)構(gòu)體指針嵌套,適合初學(xué)者順著流程往下讀。

缺點

1.代碼嚴(yán)重冗余:

rf_single_tx_data 及其后續(xù)的 while 等待、rf_sleep 等邏輯,在代碼中出現(xiàn)了三次:

初始化后第一次發(fā)送(第 14-26 行)。

接收成功后再次發(fā)送(第 52-64 行)。

接收失敗后再次發(fā)送(第 81-93 行)。

在工程中,如果一段邏輯在兩處以上被用到,必須封裝成函數(shù)。這不僅是為了美觀,更是為了方便維護(hù)。如果你想修改發(fā)送后的超時時間,在冗余代碼里你要改三次,漏改一個就是 Bug;在函數(shù)里你只需要改一次。
修改方式:

// 封裝成一個通用的“發(fā)送并處理”函數(shù)
void App_RF_Transmit_Flow(void) {
    if (rf_single_tx_data(tx_test_buf, TX_LEN, &tx_time) == OK) {
        txcnt++;
        // 等待發(fā)送完成(建議加入下文提到的超時機制)
        while (RADIO_FLAG_IDLE == rf_get_transmit_flag()); 
        rf_set_transmit_flag(RADIO_FLAG_IDLE);
        rf_sleep();
        rf_sleep_wakeup();
        rf_enter_single_timeout_rx(15000); // 開啟下一次接收窗口
    }
}

2. “死等”式阻塞:
程序中多次使用 while (RADIO_FLAG_IDLE == rf_get_transmit_flag());。 這段代碼的意思是:只要射頻芯片不回傳“我空閑了”的信號,單片機就永遠(yuǎn)停在這里。
實際應(yīng)用中的做法:絕對不允許出現(xiàn)無條件的死循環(huán)。 如果 SPI 線松了、無線模塊受靜電干擾掛了,或者由于強電磁干擾導(dǎo)致標(biāo)志位沒跳變,你的單片機就會直接“變磚”,不再響應(yīng)任何按鍵或采集任務(wù)。工業(yè)級代碼必須有超時退出或中斷驅(qū)動機制。
修改方式(增加安全計數(shù)器):

uint32_t timeout_cnt = 0x100000; // 設(shè)置一個足夠長的安全計數(shù)器
while (RADIO_FLAG_IDLE == rf_get_transmit_flag()) {
    if (--timeout_cnt == 0) {
        DDL_Printf("Hard Err: RF Hardware No Response!rn");
        // 這里可以執(zhí)行硬件復(fù)位或跳出循環(huán)
        break; 
    }
}
PAN3031 狀態(tài)圖

wKgZPGnLyIyAct1ZAABSwuu6peM554.jpg

wKgZO2nLyI2AIHpiAABSCGVY9Mw302.jpg

wKgZPGnLyI2AB_47AABKbEYo-Eg564.jpg

wKgZO2nLyI2Acg6sAAAU0Hh2ItE972.jpg

wKgZPGnLyI2AKmVkAADlfIbHgRA047.jpg

388937f71cc6fac3105b8b6d20a1aa99.png

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • SPI
    SPI
    +關(guān)注

    關(guān)注

    17

    文章

    1897

    瀏覽量

    101982
  • 無線射頻
    +關(guān)注

    關(guān)注

    4

    文章

    220

    瀏覽量

    28032
  • 智能水表
    +關(guān)注

    關(guān)注

    4

    文章

    217

    瀏覽量

    24389
  • CW32
    +關(guān)注

    關(guān)注

    1

    文章

    323

    瀏覽量

    1943
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    CW32移植Free-RTOS】CW32開發(fā)者扶持計劃

    CW32配置Free-RTOS全過程,CW32開發(fā)者扶持計劃
    的頭像 發(fā)表于 04-18 09:38 ?7527次閱讀
    【<b class='flag-5'>CW32</b>移植Free-RTOS】<b class='flag-5'>CW32</b>開發(fā)者扶持計劃

    CW32快速開發(fā)入門

    CW32快速開發(fā)入門
    的頭像 發(fā)表于 04-24 18:56 ?3789次閱讀
    <b class='flag-5'>CW32</b>快速開發(fā)入門

    CW32量產(chǎn)燒錄工具

    本節(jié)主要介紹CW32微控制器的燒錄器CW-Writer,以及與之配合的軟件CW-Programmer的使用方法。燒錄器CW-Writer通過ISP協(xié)議,可實現(xiàn)對
    的頭像 發(fā)表于 04-25 15:22 ?3017次閱讀
    <b class='flag-5'>CW32</b>量產(chǎn)燒錄工具

    項目展示】基于CW32的遙控循跡小車

    CW32循跡小車.zip_免費高速下載|百度網(wǎng)盤-分享無限制? 一、概述 CW32循跡、遙控小車具有循跡和遙控兩種功能,小車的硬件模塊由CW32F030C8T6小藍(lán)板、智能小車控制底板、BT04-E
    的頭像 發(fā)表于 05-31 17:33 ?2626次閱讀
    【<b class='flag-5'>項目</b>展示】基于<b class='flag-5'>CW32</b>的遙控循跡小車

    CW32無線表項目】W25Q+CW32程序示例

    /Armink/SFUD 一、程序分析 硬件總線映射(引腳與時鐘的“避坑點”) ? #define FLASH_SPIx CW_SPI2// 注意:CW32 中 SPI1 在 APB2 總線,而 SPI2 通常
    的頭像 發(fā)表于 03-31 21:29 ?4766次閱讀
    【<b class='flag-5'>CW32</b><b class='flag-5'>無線</b><b class='flag-5'>抄</b><b class='flag-5'>表項目</b>】W25Q+<b class='flag-5'>CW</b>32程序示例

    CW32開發(fā)者扶持計劃#CW32 #芯片

    CW32
    CW32生態(tài)社區(qū)
    發(fā)布于 :2023年05月24日 16:56:14

    cw32和stm32的區(qū)別

    cw32和stm32的區(qū)別 CW32和STM32是兩種常見的單片機,被廣泛應(yīng)用于各種電子設(shè)備中。在本文中,我們將深入探討CW32和STM32之間的區(qū)別和優(yōu)劣勢。 1. 硬件性能 硬件性能是衡量單片機
    的頭像 發(fā)表于 08-16 11:15 ?6518次閱讀

    cw32和gd32的區(qū)別

    cw32和gd32的區(qū)別 CW32和GD32是兩種不同的芯片系列,分別由WCH和GigaDevice公司推出,兩者有很多不同之處,下面我們來詳細(xì)介紹。 首先從CW32系列開始,CW32
    的頭像 發(fā)表于 08-16 11:15 ?3368次閱讀

    基于CW32的無刷水泵方案

    基于CW32的無刷水泵方案
    的頭像 發(fā)表于 11-03 17:28 ?2038次閱讀
    基于<b class='flag-5'>CW32</b>的無刷水泵方案

    基于CW32熱敏電阻采集溫度應(yīng)用

    基于CW32熱敏電阻采集溫度應(yīng)用
    的頭像 發(fā)表于 10-25 16:45 ?1414次閱讀
    基于<b class='flag-5'>CW32</b>熱敏電阻采集溫度應(yīng)用

    CW32的SPI單工模式主從通信介紹

    CW32的SPI單工模式主從通信介紹
    的頭像 發(fā)表于 10-24 15:50 ?2088次閱讀
    <b class='flag-5'>CW32</b>的SPI單工模式主從<b class='flag-5'>通信</b>介紹

    CW32 PWM輸出功能介紹

    CW32 PWM輸出功能介紹
    的頭像 發(fā)表于 09-27 16:12 ?2332次閱讀
    <b class='flag-5'>CW32</b> PWM輸出功能介紹

    CW32實時時鐘(RTC)介紹

    CW32實時時鐘(RTC)介紹
    的頭像 發(fā)表于 10-24 15:36 ?2356次閱讀
    <b class='flag-5'>CW32</b>實時時鐘(RTC)介紹

    基于CW32的RC522刷卡模塊的應(yīng)用

    基于CW32的RC522刷卡模塊的應(yīng)用
    的頭像 發(fā)表于 11-02 14:53 ?2722次閱讀
    基于<b class='flag-5'>CW32</b>的RC522刷卡模塊的應(yīng)用

    基于CW32的物聯(lián)網(wǎng)應(yīng)用

    CW32】基于CW32的物聯(lián)網(wǎng)應(yīng)用
    的頭像 發(fā)表于 11-02 15:55 ?2080次閱讀
    基于<b class='flag-5'>CW32</b>的物聯(lián)網(wǎng)應(yīng)用
    黄龙县| 方山县| 巴彦淖尔市| 任丘市| 平定县| 靖边县| 孟津县| 九龙城区| 那曲县| 祁门县| 同德县| 萍乡市| 囊谦县| 吴江市| 大方县| 大宁县| 永州市| 东乡族自治县| 会宁县| 三门县| 威远县| 怀来县| 仙居县| 宁远县| 察隅县| 武乡县| 磐石市| 秭归县| 金沙县| 渭南市| 武邑县| 东至县| 台前县| 清远市| 望谟县| 华池县| 邯郸市| 虎林市| 静安区| 池州市| 七台河市|