:Zigbee 3.0開發(fā)環(huán)境搭建與組網(wǎng)避坑指南)
前幾天看到ST的官網(wǎng)更新STM32無線MCU的官方固件正式把Zigbee 3.0協(xié)議棧納入支持范圍。說句實話這個動作對做智能家居、傳感網(wǎng)絡(luò)、工業(yè)無線采集的人來說是個挺實在的好消息。以前想在STM32上跑Zigbee要么用外掛透傳模塊要么守著老舊的Zigbee協(xié)議棧自己折騰移植既占成本又費時間?,F(xiàn)在STM32WB系列這些自帶2.4GHz射頻的芯片終于能直接在官方工具鏈里把Zigbee 3.0拉起來用了。這篇文章不打算復(fù)述什么官方發(fā)布說明也沒必要去念release notes。我會從實際動手折騰過這塊板子的角度聊聊Zigbee 3.0到底能解決什么問題、開發(fā)環(huán)境怎么搭、一個最小網(wǎng)絡(luò)怎么跑通以及調(diào)試時你大概率會撞上的那些坑。如果你手上有NUCLEO-WB55RG這類開發(fā)板正想用它做Zigbee 3.0節(jié)點這篇內(nèi)容應(yīng)該能幫你少走不少彎路。1. Zigbee 3.0 和 STM32 無線 MCU 是怎么湊到一塊的1.1 Zigbee 3.0 到底是什么為什么開發(fā)者都在等它Zigbee 3.0本質(zhì)上不是一個新協(xié)議而是把過去分散的ZHAZigbee Home Automation、ZLLZigbee Light Link、ZBOZigbee Building Operations這些profile統(tǒng)一成了一套標(biāo)準(zhǔn)。你可以把它理解為以前的Zigbee世界像是幾家各自為戰(zhàn)的方言區(qū)雖然底層都是802.15.4但設(shè)備之間不一定能互通Zigbee 3.0則強制統(tǒng)一了應(yīng)用層的Cluster定義、設(shè)備描述、入網(wǎng)流程和安全機制?,F(xiàn)在一個Zigbee 3.0的燈泡理論上可以跟另一個廠商Zigbee 3.0的開關(guān)無縫配對不用再糾結(jié)是不是同一個生態(tài)。對開發(fā)者來說統(tǒng)一的最大好處是開發(fā)和測試成本下降。以前做Zigbee產(chǎn)品每個profile都要單獨適配測試矩陣鋪得很大?,F(xiàn)在只要基于ZCLZigbee Cluster Library標(biāo)準(zhǔn)Cluster開發(fā)設(shè)備天然具備了跨廠商互操作的基礎(chǔ)。另外Zigbee 3.0在安全上也做了加強默認(rèn)支持Secure Join、鏈路層加密、密鑰更新機制不像早期Zigbee那樣動不動就裸奔在2.4GHz頻段上。這也是為什么很多智能家居網(wǎng)關(guān)、傳感器網(wǎng)絡(luò)、智能照明項目在協(xié)議選型時會優(yōu)先考慮Zigbee 3.0而不是自組私有協(xié)議或Wi-Fi直連——它兼顧了低功耗、低帶寬、大規(guī)模組網(wǎng)和互操作性。1.2 STM32 無線 MCU 家族的硬件底子夠不夠格ST官方這次說的“STM32 Wireless MCUs”主要指STM32WB系列和更新的STM32WBA系列。STM32WB是目前最常用的雙核無線SoC內(nèi)置一個Cortex-M4F應(yīng)用內(nèi)核和一個Cortex-M0網(wǎng)絡(luò)協(xié)處理器同時集成了2.4GHz射頻收發(fā)器。它既能跑BLE 5.0也能跑Zigbee 3.0、OpenThread和802.15.4 MAC。具體型號從低端的STM32WB15、STM32WB10到全功能的STM32WB55Flash和SRAM容量差異挺大但射頻底子基本是同一套。STM32WB55最高主頻64MHz的M4F1MB Flash適合做網(wǎng)關(guān)或復(fù)雜節(jié)點STM32WB35中等容量適合做傳感器節(jié)點、燈控模塊STM32WB15低成本小封裝適合做單功能終端設(shè)備STM32WBA52更新的M33內(nèi)核平臺主頻更高安全特性更強在這幾個型號里選型主要看你要跑的應(yīng)用程序有多重。如果只是把Zigbee協(xié)議棧跑起來然后遙控個燈、讀個溫濕度STM32WB15就夠了。如果還要本地跑一些濾波算法、顯示界面、本地日志那得上WB55或者WBA52。芯片本身的Zigbee協(xié)議棧是預(yù)編譯好的庫運行在M0核心上不占用M4的資源這一點對應(yīng)用開發(fā)非常友好。1.3 雙核架構(gòu)協(xié)議棧和應(yīng)用是怎么分工的很多第一次接觸STM32WB的人會問為什么一顆MCU要搞雙核答案就是為了隔離和實時性。Zigbee協(xié)議棧對時間敏感信標(biāo)、ACK、重傳都有嚴(yán)格的時序要求。如果和應(yīng)用代碼擠在一個核上一旦應(yīng)用里出現(xiàn)大循環(huán)或阻塞操作協(xié)議棧分分鐘會丟包掉線。STM32WB把無線協(xié)議棧固化在M0核上M0跑協(xié)議棧和射頻調(diào)度M4跑用戶應(yīng)用兩者通過共享內(nèi)存和Mailbox通信。開發(fā)者在M4上寫的業(yè)務(wù)邏輯哪怕里面有個很耗時的浮點運算也不會直接影響射頻收發(fā)的時序。協(xié)議棧和應(yīng)用之間的API由ST封裝好了使用時主要就是初始化Zigbee協(xié)議棧、注冊Cluster、發(fā)送和接收ZCL命令。你不太需要關(guān)心底層802.15.4幀細(xì)節(jié)只需要理解Zigbee網(wǎng)絡(luò)層和應(yīng)用層的幾個概念設(shè)備類型Coordinator、Router、EndDevice、PAN ID、信道、Endpoint、Cluster。理解了這些后面跑通例程就不難。2. 開發(fā)環(huán)境準(zhǔn)備工具鏈和固件棧一個都不能少2.1 裝上這幾個工具基本就齊活了開發(fā)STM32WB的Zigbee 3.0應(yīng)用工具鏈比想象中要長一點但都是ST官方的東西用起來比較省心。我建議把這幾個都裝齊工具作用備注STM32CubeMX圖形化配置引腳、時鐘、中間件生成工程建議用較新版本兼容Zigbee 3.0STM32CubeIDE編譯、調(diào)試一體化IDE也可用Keil/IAR替代ST官方例程基本都是CubeIDE工程STM32CubeProgrammer燒錄FUS固件、無線協(xié)議棧、用戶程序燒Zigbee協(xié)議棧必須用它STM32CubeMonitor-RF802.15.4無線抓包分析排查Zigbee入網(wǎng)問題非常有用這些工具在ST官網(wǎng)都能下載。國內(nèi)下載速度有時候會比較感人建議挑個網(wǎng)絡(luò)空閑時段或者用官方提供的下載加速方式。還有一點要注意STM32CubeWB固件包通常很大里面包含了協(xié)議棧庫、例程、文檔下載后不要急著刪后面找例程和API文檔都要用。2.2 用 CubeMX 配置一個帶 Zigbee 3.0 的工程打開STM32CubeMX選擇芯片型號比如STM32WB55RGV6。在中間的軟件包管理里要確保下載了對應(yīng)版本的STM32CubeWB固件包。然后在“Middleware and Software Packs”里勾選“Zigbee 3.0”CubeMX會幫你把協(xié)議棧相關(guān)的組件加進(jìn)來。接下來要配置幾個關(guān)鍵參數(shù)設(shè)備類型Coordinator、Router還是EndDevice。協(xié)調(diào)器負(fù)責(zé)建網(wǎng)一個Zigbee網(wǎng)絡(luò)里有且只能有一個協(xié)調(diào)器。PAN ID網(wǎng)絡(luò)ID范圍是0x0000到0xFFFE0xFFFF會被解釋成廣播網(wǎng)絡(luò)ID不能用作實際PAN ID。信道2.4GHz下可選11到26信道。家庭環(huán)境中Wi-Fi用的是1、6、11等信道為避免同頻干擾通常建議選15、20、25附近。SecurityZigbee 3.0默認(rèn)開啟安全模式配置里一般保持默認(rèn)。這些參數(shù)在CubeMX里配置好之后直接生成代碼。生成的工程里會有一個類似MX_ZIGBEE_Init()的調(diào)用但實際上Zigbee的啟動邏輯比普通外設(shè)稍微復(fù)雜一點ST官方例程一般會單獨寫一個APP_Zigbee_Init()在main函數(shù)里初始化外設(shè)后再調(diào)用。我習(xí)慣把串口、LED、按鍵這些基礎(chǔ)外設(shè)也在CubeMX里一起配好這樣后面調(diào)試日志輸出和現(xiàn)象觀察都方便。2.3 FUS 升級與協(xié)議棧燒錄STM32WB的Flash布局比較特殊不像普通STM32那樣一個程序燒進(jìn)去就完事。它有三個分區(qū)用戶應(yīng)用區(qū)、無線協(xié)議棧區(qū)、FUS區(qū)。FUS全稱是Firmware Upgrade Services負(fù)責(zé)無線協(xié)議棧的安裝和升級相當(dāng)于一個系統(tǒng)引導(dǎo)服務(wù)。新買回來的芯片出廠時可能已經(jīng)帶了FUS但版本不一定滿足你的協(xié)議棧要求所以第一步通常是用STM32CubeProgrammer檢查FUS版本必要時先升級FUS。燒無線協(xié)議棧時要注意這不是用普通全片擦除方式燒錄而是用CubeProgrammer的“Firmware upgrade”功能。選擇STM32CubeWB固件包里的協(xié)議棧文件例如stm32wb5x_Zigbee_3_0_fw.bin工具會自動識別目標(biāo)地址。這里有幾個容易踩的坑不要用“Erase All”去擦除整個芯片否則FUS可能被抹掉后面協(xié)議棧就裝不上了。燒錄完成后再燒用戶應(yīng)用代碼。用戶代碼一般編譯成hex按正常方式下載到0x08000000起始的應(yīng)用區(qū)。如果燒錄過程中提示FUS操作失敗大概率是FUS版本太老先升級FUS再燒協(xié)議棧。我第一次接觸這個流程時直接把芯片擦了個干干凈凈然后又花了半天重新恢復(fù)FUS。后面我會在第五章詳細(xì)講這個坑。3. 實操兩臺開發(fā)板組一個最小的 Zigbee 3.0 網(wǎng)絡(luò)3.1 硬件準(zhǔn)備和板級連接要做最小驗證推薦準(zhǔn)備兩塊NUCLEO-WB55RG板子一塊做協(xié)調(diào)器一塊做路由器或者終端設(shè)備。如果沒有兩塊板子也可以用STM32WB55 USB Dongle配合一塊開發(fā)板Dongle做協(xié)調(diào)器開發(fā)板做終端效果類似。接線部分其實很簡單NUCLEO板載ST-LINK直接用USB線連電腦就行。串口輸出用板上的虛擬串口通過ST-LINK的VCP功能在設(shè)備管理器里能看到一個COM口。我習(xí)慣在CubeMX里把USART1配置成115200-8-N-1并在main函數(shù)里重定向printf到串口這樣Zigbee協(xié)議棧的日志、入網(wǎng)事件、命令收發(fā)信息都可以直接打出來看。3.2 協(xié)調(diào)器端配置與代碼修改協(xié)調(diào)器端的配置以STM32CubeWB官方例程Zigbee_OnOff_Coordinator為基礎(chǔ)。核心代碼在APP_Zigbee_Init()里真正啟動網(wǎng)絡(luò)的配置是一個ZbStartupConf_t結(jié)構(gòu)體static void APP_Zigbee_Init(void) { ZbStartupConf_t startupConfig {0}; /* 設(shè)備類型協(xié)調(diào)器 */ startupConfig.deviceType ZbCoordinator; /* PAN ID自己定義一個比如 0x1234 */ startupConfig.panId 0x1234; /* 選用信道 15盡量避免和家用Wi-Fi沖突 */ startupConfig.channel 15; /* Zigbee 3.0 安全模式默認(rèn)開啟 */ startupConfig.zigbeeSecurity ZbZigbeeSecurityStandard; /* 初始化協(xié)議棧 */ Zigbee_Init(startupConfig); }啟動之后協(xié)調(diào)器會創(chuàng)建一個網(wǎng)絡(luò)自己的短地址固定是0x0000。串口日志里會打印類似“Network started”的信息。接著協(xié)調(diào)器會等待其他設(shè)備入網(wǎng)一旦有設(shè)備加入事件回調(diào)里會觸發(fā)ZbZclEventDeviceJoin之類的事件這時可以在回調(diào)里把入網(wǎng)設(shè)備的短地址、IEEE地址打出來。需要注意的是Zigbee_Init()只會把協(xié)議棧初始化真正的事件處理需要你自己注冊一個回調(diào)函數(shù)。ST例程里這個回調(diào)叫APP_Zigbee_EventHandler里面根據(jù)事件類型做分支處理。比如收到On/Off命令時就控制板載LED翻轉(zhuǎn)。3.3 路由/終端設(shè)備端配置第二塊板子配置成Router或者EndDevice代碼改動的核心參數(shù)就兩個startupConfig.deviceType ZbRouter; /* 或 ZbEndDevice */如果配置成Router它會主動掃描周圍已有的Zigbee網(wǎng)絡(luò)找到PAN ID匹配或者開放加入的網(wǎng)絡(luò)后發(fā)送關(guān)聯(lián)請求。如果協(xié)調(diào)器的PAN ID是0x1234Router這邊最好也填0x1234或者在啟動配置里允許“加入任何網(wǎng)絡(luò)”否則可能出現(xiàn)找不到網(wǎng)絡(luò)的問題。入網(wǎng)成功后Router設(shè)備的串口日志會打印自己被分配到的短地址這個地址在Zigbee網(wǎng)絡(luò)里是唯一的。協(xié)調(diào)器那邊也會同時打印出該設(shè)備入網(wǎng)的事件??吹絻蛇吶罩径颊Uf明一個最小的Zigbee 3.0網(wǎng)絡(luò)已經(jīng)建起來了。這個過程中如果遇到“網(wǎng)絡(luò)掃描超時”或者“關(guān)聯(lián)失敗”大概率是信道不一致或者PAN ID不匹配后面第五章會詳細(xì)說排查方法。3.4 聯(lián)調(diào)入網(wǎng)、綁定、無線點燈網(wǎng)絡(luò)建好之后最經(jīng)典的驗證方式就是無線點燈。Zigbee 3.0標(biāo)準(zhǔn)化了On/Off ClusterCluster ID 0x0006它定義了兩個基本命令On0x01和Off0x00。協(xié)調(diào)器作為On/Off Client向Router上的On/Off Server發(fā)送命令Router收到后翻轉(zhuǎn)LED。在ST的例程里發(fā)送路由節(jié)點的On/Off命令大概是這樣/* 找到目標(biāo)端點上的 On/Off Client Cluster */ ZbZclCluster_t *clientCluster ZbZclOnOffClientFind(endpoint); /* 目標(biāo)地址路由節(jié)點的短地址入網(wǎng)時打印出來 */ ZbZclAddrInfo_t dstAddr; dstAddr.type ZB_ZCL_ADDR_TYPE_SHORT; dstAddr.shortAddr routerShortAddress; dstAddr.endpoint 1; /* 發(fā)送 On 命令 */ ZbZclOnOffClientSendCommand(clientCluster, dstAddr, ZCL_ONOFF_COMMAND_ON, TRUE);在Router端注冊O(shè)n/Off Server后收到On命令就會執(zhí)行回調(diào)?;卣{(diào)里寫一句HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET)燈的亮滅就跟著無線命令走了。這整套流程跑通之后你其實已經(jīng)掌握了大半個Zigbee 3.0開發(fā)套路。后面做傳感器上報、做群組控制、做場景聯(lián)動本質(zhì)上都是圍繞Cluster和Endpoint做文章。4. 結(jié)合真實項目擴展從點燈到傳感器上報和電機控制4.1 把 Zigbee 數(shù)據(jù)接到自己的業(yè)務(wù)邏輯里點燈驗證沒問題后很多人第一反應(yīng)是我能不能讓節(jié)點上報溫濕度、控制電機、讀取電量當(dāng)然可以而且Zigbee 3.0已經(jīng)把這些應(yīng)用場景標(biāo)準(zhǔn)化了。比如傳感器節(jié)點可以用Temperature Measurement ClusterCluster ID 0x0402周期上報溫度智能臺燈可以用Level Control ClusterCluster ID 0x0008調(diào)節(jié)明暗窗簾電機可以用Window Covering ClusterCluster ID 0x0102控制開合。使用標(biāo)準(zhǔn)Cluster的好處是你節(jié)點上報的數(shù)據(jù)別人家的Zigbee 3.0網(wǎng)關(guān)或面板也能直接解析。在實際項目里我通常會把Zigbee協(xié)議棧的處理和應(yīng)用邏輯拆開。Zigbee事件回調(diào)里只負(fù)責(zé)收數(shù)據(jù)、解析Cluster、設(shè)置標(biāo)志位真正控制執(zhí)行器、處理傳感器數(shù)據(jù)的主循環(huán)放在M4核的while(1)里。這樣分工清晰調(diào)試時也容易定位是無線鏈路的問題還是業(yè)務(wù)邏輯的問題。4.2 傳感器周期上報和低功耗設(shè)計如果你做的是電池供電的傳感器節(jié)點那么終端設(shè)備EndDevice模式比路由模式更合適。終端設(shè)備大部分時間處于休眠狀態(tài)只有采集和上報時喚醒功耗能壓得很低。STM32WB在休眠方面支持多種低功耗模式再配合Zigbee協(xié)議棧的休眠管理做溫濕度計、門窗傳感器、人體紅外檢測這一類產(chǎn)品是比較理想的。簡單的上報流程可以這樣設(shè)計終端設(shè)備定時喚醒例如用RTC或LPTIM喚醒后讀取傳感器數(shù)據(jù)重新加入網(wǎng)絡(luò)如果休眠期間掉線會自動重連通過ZCL的Report Attributes或自定義的Cluster上報數(shù)據(jù)上報完成后再次進(jìn)入休眠這里要注意終端設(shè)備不能隨意長時間休眠因為父節(jié)點通常是Router或Coordinator需要緩存發(fā)給它的數(shù)據(jù)。如果休眠時間太長、緩存溢出數(shù)據(jù)就會丟。Zigbee 3.0的終端設(shè)備一般會配置Polling輪詢周期和父節(jié)點保持心跳這個參數(shù)需要根據(jù)實際功耗和實時性需求去平衡。4.3 場景延伸485伺服、N20減速電機也能被 Zigbee 管起來很多做機電控制的朋友問Zigbee能不能用來遠(yuǎn)程控制伺服電機、直流減速電機這類執(zhí)行器。完全可以關(guān)鍵是看你對實時性的要求有多高。如果是開關(guān)型控制——比如N20減速電機驅(qū)動一個窗簾開合、一個門鎖動作用On/Off Cluster就夠了。收到On命令電機正轉(zhuǎn)收到Off命令反轉(zhuǎn)或者停止。這種場景對延遲不敏感可靠性和低功耗遠(yuǎn)比毫秒級實時性重要。如果是位置型控制比如帶編碼器的伺服電機要精確轉(zhuǎn)到某個角度那就需要在應(yīng)用層定義Position Cluster或者擴展Level Control Cluster用百分比或者線性數(shù)值代表目標(biāo)位置。如果伺服電機通過RS485總線控制那么STM32WB的M4核負(fù)責(zé)Zigbee協(xié)議棧命令解析然后把解析結(jié)果轉(zhuǎn)成Modbus RTU或者自定義485幀通過USARTRS485收發(fā)器發(fā)給伺服驅(qū)動器。這樣一來整個無線控制鏈路由應(yīng)用代碼自己定義Zigbee只負(fù)責(zé)無線傳輸非常靈活。我自己做過一個實驗Zigbee 3.0協(xié)調(diào)器發(fā)送“轉(zhuǎn)到30%”的命令終端設(shè)備收到后通過485發(fā)送0x01 0x06 0x00 0x00 0x1E 0x00這種Modbus寫寄存器幀給伺服實測無線命令的端到端延遲大概在幾十毫秒量級用于非高精度的工業(yè)控制場景完全夠用。5. 實戰(zhàn)避坑我踩過的幾個 Zigbee 調(diào)試問題5.1 協(xié)議棧版本跟 CubeMX 版本不匹配這是最容易遇到的坑。STM32CubeWB固件包更新頻率不低協(xié)議棧庫也在不斷迭代。如果CubeMX的版本太老生成的代碼可能調(diào)用了一些舊API跟新協(xié)議棧庫不兼容編譯就會報一堆找不到函數(shù)的錯誤。反過來CubeMX版本太新但固件包沒更新也可能出現(xiàn)中間件配置界面識別不到Zigbee 3.0的情況。我的建議是不要一味追求最新而是選擇一套經(jīng)過驗證的組合。比如先固定使用某個較新的STM32CubeWB固件包然后讓CubeMX自動匹配對應(yīng)的中間件版本。或者直接把官方例程作為起點在自己的代碼里增量開發(fā)而不是每次都用CubeMX重新生成這樣能大幅減少配置不一致帶來的麻煩。5.2 串口日志亂碼和 printf 重映射Zigbee協(xié)議棧自身的調(diào)試信息是通過底層接口輸出的如果你沒有正確重定向printf或者串口波特率設(shè)置不一致日志就會變成亂碼。我自己用過一種很簡單的排查方法先寫一個不帶Zigbee的裸機點燈工程單獨測試串口輸出確認(rèn)硬件鏈路沒問題再打開Zigbee工程調(diào)試。這樣能把問題域隔離開。另外STM32WB的CPU頻率是可以通過CubeMX配置的一般主頻選64MHzM4/32MHzM0。串口波特率計算要基于實際時鐘頻率如果時鐘配置改了但CubeMX里的波特率設(shè)置沒重新計算也會導(dǎo)致亂碼。解決方式是確認(rèn)HAL_RCC_ClockConfig返回正常值串口初始化用的波特率參數(shù)和實際時鐘匹配。5.3 抓包抓不到或抓包后串口失效Zigbee調(diào)試和BLE調(diào)試類似空中的問題很難靠猜抓包工具幾乎是必需品。ST官方推薦的是STM32CubeMonitor-RF配合STM32WB55 USB Dongle或者板載ST-LINK的Sniffer模式使用。這里有個大坑如果啟用Sniffer模式板載ST-LINK的虛擬串口功能會被禁用也就是說你無法同時用這塊板子的串口打印Zigbee日志。所以我的做法比較粗暴準(zhǔn)備兩塊板子一塊專門當(dāng)Sniffer另一塊跑協(xié)調(diào)器或路由器節(jié)點。抓包時先把Sniffer板切換到Sniffer模式再用STM32CubeMonitor-RF在對應(yīng)信道抓包觀察入網(wǎng)流程、信標(biāo)請求、關(guān)聯(lián)請求、數(shù)據(jù)確認(rèn)這些802.15.4幀。調(diào)試完再切回正常模式不然串口日志會一直出不來。5.4 入網(wǎng)失敗、網(wǎng)絡(luò)不穩(wěn)怎么定位設(shè)備入網(wǎng)失敗是Zigbee開發(fā)里最頭疼的問題原因往往不止一個。如果Router或EndDevice啟動后一直找不到網(wǎng)絡(luò)按優(yōu)先級排查這幾個點PAN ID是否匹配協(xié)調(diào)器的PAN ID和終端設(shè)備配置的PAN ID是否一致或者終端是否配置為允許加入任何網(wǎng)絡(luò)。信道是否一致協(xié)調(diào)器和終端必須在同一個信道上??梢杂肧niffer抓包確認(rèn)協(xié)調(diào)器是不是在設(shè)定的信道廣播信標(biāo)。安全密鑰是否一致Zigbee 3.0支持預(yù)配置鏈路密鑰如果兩邊密鑰不同關(guān)聯(lián)請求會失敗。射頻硬件是否正常有些STM32WB開發(fā)板需要正確連接天線或焊上匹配網(wǎng)絡(luò)否則射頻功率很低近距離都搜不到。給板子外接天線時要確保板載天線跳線帽選對了位置。網(wǎng)絡(luò)不穩(wěn)定、掉線頻繁的情況優(yōu)先懷疑射頻干擾。2.4GHz頻段被Wi-Fi、藍(lán)牙、微波爐這些設(shè)備擠得滿滿當(dāng)當(dāng)可以嘗試換一個干凈一點的信道。Zigbee 3.0的信道個數(shù)不多但選擇合適信道能顯著提升穩(wěn)定性。我在實驗室里調(diào)試時周圍Wi-Fi路由器很多最后鎖定信道25基本沒有再出現(xiàn)過批量掉線的問題。5.5 Flash 燒錄順序和地址的坑回到前面提到的FUS和協(xié)議棧燒錄問題這里必須再強調(diào)一遍STM32WB的燒錄順序不能亂。正確的流程是檢查FUS版本升級FUS燒無線協(xié)議棧固件最后燒用戶應(yīng)用代碼。特別是從官方例程環(huán)境克隆出來的新板子很多都是出廠固件狀態(tài)不一定帶最新的協(xié)議棧。用STM32CubeProgrammer燒協(xié)議棧時選擇“Firmware upgrade”模式后它會自動識別協(xié)議棧文件的類型和目標(biāo)地址。這里不要自作聰明去改地址否則協(xié)議棧會寫到錯誤的Flash區(qū)域M0核根本加載不了。燒完后可以在CubeProgrammer里檢查協(xié)議棧版本信息確保燒錄成功。如果燒錄中途斷電或者連接斷開協(xié)議棧區(qū)域可能處于半寫狀態(tài)這時候重新燒一次通常就能恢復(fù)不必太慌張。最后再分享一點個人體會STM32無線MCU對Zigbee 3.0的支持補齊了STM32生態(tài)在Mesh類和低功耗傳感網(wǎng)絡(luò)上的短板。實際用下來我的感受是協(xié)議棧穩(wěn)定性比預(yù)想的好ST封裝出來的API也比某些第三方SDK干凈不少但學(xué)習(xí)曲線還是有的尤其是FUS燒錄、雙核通信、ZCL規(guī)范這些概念第一次接觸會覺得信息量很大。我的建議是別急著直接上手自己項目先把官方協(xié)調(diào)器路由器的On/Off例程跑通把入網(wǎng)流程和串口日志看清楚再去動手改業(yè)務(wù)邏輯。一個能穩(wěn)定入網(wǎng)、能互相通信的最小閉環(huán)比什么都重要。等你把這個閉環(huán)跑通了后面無論是做智能臺燈、傳感器上報還是用485去控制伺服電機其實都在這個框架內(nèi)擴展而已。