戰(zhàn))
1. 從一顆芯片的缺貨說(shuō)起為什么替代這件事非做不可2020年下半年到2022年那段時(shí)間只要你在電子行業(yè)待過(guò)就一定經(jīng)歷過(guò)那種“看著B(niǎo)OM表發(fā)呆”的日子。STM32F103C8T6這顆芯片平時(shí)幾塊錢的東西一度被炒到上百塊交期從四周變成五十二周甚至有些貿(mào)易商直接告訴你“先打款什么時(shí)候有貨不知道”。我手上有個(gè)項(xiàng)目板子都畫(huà)好了樣機(jī)也驗(yàn)證通過(guò)了結(jié)果采購(gòu)跟我說(shuō)F103拿不到貨要么改設(shè)計(jì)要么項(xiàng)目停擺。那種感覺(jué)做過(guò)硬件的人應(yīng)該都懂。STM32F103這顆芯片在嵌入式圈子的地位不用多說(shuō)。它是很多人入門ARM Cortex-M3的第一顆芯片資料多、例程全、社區(qū)活躍標(biāo)準(zhǔn)庫(kù)和HAL庫(kù)兩套生態(tài)都很成熟。從最小系統(tǒng)板到工業(yè)控制板從串口通信到PWM電機(jī)驅(qū)動(dòng)從SPI讀取傳感器到USB虛擬串口幾乎你能想到的嵌入式入門場(chǎng)景都能找到基于F103的現(xiàn)成代碼。正因?yàn)槿绱水?dāng)它缺貨的時(shí)候整個(gè)行業(yè)都被迫開(kāi)始認(rèn)真思考一個(gè)問(wèn)題有沒(méi)有能替代它的國(guó)產(chǎn)MCU這個(gè)問(wèn)題在2021年之后變得尤為迫切。國(guó)產(chǎn)MCU廠商也抓住了這個(gè)窗口期GD32、APM32、CH32、AT32、HC32等品牌迅速進(jìn)入工程師的視野。但替代這件事遠(yuǎn)不是“管腳兼容就能直接換”那么簡(jiǎn)單。我見(jiàn)過(guò)太多人踩坑有人以為GD32和STM32可以直接pin-to-pin替換結(jié)果發(fā)現(xiàn)ADC精度和時(shí)鐘樹(shù)配置有差異有人把HAL庫(kù)直接搬到APM32上編譯過(guò)了但跑不起來(lái)還有人選了某款國(guó)產(chǎn)芯片結(jié)果發(fā)現(xiàn)開(kāi)發(fā)工具鏈極其難用社區(qū)資料幾乎為零一個(gè)簡(jiǎn)單的問(wèn)題卡了三天。這篇內(nèi)容就是把我這幾年在國(guó)產(chǎn)MCU替代和選型上踩過(guò)的坑、總結(jié)的經(jīng)驗(yàn)、以及實(shí)際項(xiàng)目中驗(yàn)證過(guò)的方案系統(tǒng)地梳理出來(lái)。不管你是正在為F103缺貨發(fā)愁的硬件工程師還是準(zhǔn)備在新項(xiàng)目里導(dǎo)入國(guó)產(chǎn)MCU的嵌入式開(kāi)發(fā)者或者只是想在方案里留一個(gè)備選路徑這些內(nèi)容都能直接拿來(lái)參考。我會(huì)從替代方案的整體思路講起然后逐個(gè)拆解主流國(guó)產(chǎn)MCU的選型要點(diǎn)再深入到移植過(guò)程中的具體技術(shù)細(xì)節(jié)最后分享一些實(shí)際項(xiàng)目中積累的避坑經(jīng)驗(yàn)。2. 替代方案的整體思路先搞清楚你到底需要什么2.1 替代不是簡(jiǎn)單的“換一顆芯片”很多人一聽(tīng)到替代第一反應(yīng)就是去找一顆管腳兼容、寄存器兼容的芯片然后把原來(lái)的固件燒進(jìn)去就完事了。這個(gè)思路在理想情況下是對(duì)的但實(shí)際操作中你需要考慮的東西遠(yuǎn)不止這些。首先要明確的是替代的層次是不一樣的。最淺層次的替代是“硬件管腳兼容”也就是PCB不用改或者只改少量外圍芯片焊上去就能用。再深一層是“寄存器級(jí)兼容”也就是原來(lái)的標(biāo)準(zhǔn)庫(kù)代碼基本不用改重新編譯就能跑。最深層次是“生態(tài)兼容”包括開(kāi)發(fā)工具、調(diào)試器、中間件、社區(qū)支持等一整套東西。你在做替代方案的時(shí)候必須先想清楚自己需要達(dá)到哪個(gè)層次。我一般會(huì)把替代需求分成三類場(chǎng)景。第一類是“緊急替代”就是原來(lái)用F103的板子已經(jīng)量產(chǎn)了突然缺貨需要快速找到能焊上去就跑的芯片這種情況下管腳兼容和寄存器兼容是剛需。第二類是“新項(xiàng)目選型”還沒(méi)有歷史包袱可以從頭評(píng)估哪顆芯片最合適這種情況下生態(tài)和長(zhǎng)期供貨能力比管腳兼容更重要。第三類是“降本替代”原來(lái)用F103覺(jué)得成本高了想換成更便宜的方案這種情況下需要綜合考慮性能和開(kāi)發(fā)成本。2.2 替代評(píng)估的核心維度不管你是哪種場(chǎng)景評(píng)估一顆替代芯片的時(shí)候我建議從下面這幾個(gè)維度去打分。這個(gè)框架是我自己在多個(gè)項(xiàng)目中總結(jié)出來(lái)的可以直接拿來(lái)用。評(píng)估維度具體內(nèi)容權(quán)重建議管腳兼容性封裝是否一致、引腳定義是否相同、外圍電路是否需要調(diào)整緊急替代場(chǎng)景權(quán)重最高寄存器兼容性外設(shè)寄存器地址和位定義是否一致、標(biāo)準(zhǔn)庫(kù)/HAL庫(kù)能否直接復(fù)用有大量存量代碼時(shí)權(quán)重高內(nèi)核與主頻Cortex-M3/M4/M0、最高主頻、Flash和RAM容量根據(jù)項(xiàng)目算力需求評(píng)估外設(shè)資源定時(shí)器數(shù)量、ADC通道數(shù)和精度、SPI/I2C/UART數(shù)量、USB/CAN支持根據(jù)具體應(yīng)用場(chǎng)景開(kāi)發(fā)工具鏈?zhǔn)欠裰С諯eil/IAR、是否有免費(fèi)IDE、調(diào)試器是否通用影響開(kāi)發(fā)效率生態(tài)與資料官方例程豐富度、社區(qū)活躍度、中文文檔質(zhì)量影響問(wèn)題排查速度供貨與價(jià)格長(zhǎng)期供貨承諾、代理商渠道、批量?jī)r(jià)格量產(chǎn)項(xiàng)目必須考慮可靠性工作溫度范圍、ESD等級(jí)、是否有車規(guī)/工業(yè)級(jí)認(rèn)證工業(yè)場(chǎng)景重點(diǎn)關(guān)注這個(gè)表格看起來(lái)簡(jiǎn)單但實(shí)際用起來(lái)的時(shí)候每一項(xiàng)都需要你花時(shí)間去驗(yàn)證。比如“寄存器兼容性”這一項(xiàng)你不能只看廠商宣傳的“兼容STM32”而是要實(shí)際拿代碼去編譯、去跑、去對(duì)比外設(shè)行為。我后面會(huì)詳細(xì)講怎么驗(yàn)證。2.3 國(guó)產(chǎn)MCU的幾條技術(shù)路線目前市面上的國(guó)產(chǎn)MCU從技術(shù)路線上大致可以分成三類。第一類是“兼容派”代表是GD32和APM32。這類芯片在設(shè)計(jì)上刻意向STM32靠攏管腳基本兼容寄存器映射也高度相似標(biāo)準(zhǔn)庫(kù)和HAL庫(kù)經(jīng)過(guò)少量修改就能跑。GD32早期的一些型號(hào)甚至可以直接燒STM32的二進(jìn)制文件當(dāng)然不推薦這么做。這類芯片的優(yōu)勢(shì)是遷移成本低適合緊急替代和存量項(xiàng)目改造。第二類是“自研派”代表是CH32和HC32。這類芯片有自己的架構(gòu)和外設(shè)設(shè)計(jì)雖然也是ARM Cortex-M內(nèi)核但寄存器映射和外設(shè)行為跟STM32差別較大代碼需要較多修改。優(yōu)勢(shì)是價(jià)格通常更有競(jìng)爭(zhēng)力某些外設(shè)比如CH32的USB有自己的特色。適合新項(xiàng)目選型不太適合緊急替代。第三類是“生態(tài)派”代表是AT32。這類芯片在兼容性上做了不少工作同時(shí)也在建自己的生態(tài)比如提供專門的遷移工具和文檔。AT32的管腳和STM32F103高度兼容官方還提供了從STM32遷移的詳細(xì)指南算是介于前兩類之間的一種路線。理解這幾條路線的區(qū)別很重要因?yàn)樗苯記Q定了你的遷移工作量和風(fēng)險(xiǎn)。如果你手上有一堆基于F103標(biāo)準(zhǔn)庫(kù)的項(xiàng)目選GD32或APM32會(huì)省很多事如果你是新項(xiàng)目對(duì)成本敏感CH32可能更合適如果你想要一個(gè)平衡的方案AT32值得認(rèn)真看看。3. 主流國(guó)產(chǎn)MCU逐個(gè)拆解GD32、APM32、CH32、AT32到底怎么選3.1 GD32最像STM32的那一個(gè)GD32是兆易創(chuàng)新的產(chǎn)品線也是國(guó)產(chǎn)MCU里最早打出“兼容STM32”旗號(hào)的品牌之一。我最早接觸GD32是在2019年當(dāng)時(shí)用GD32F103替換STM32F103做了一個(gè)串口服務(wù)器的項(xiàng)目整體遷移過(guò)程算是比較順利的。GD32F103系列和STM32F103系列在管腳上是pin-to-pin兼容的封裝從LQFP48到LQFP100都有對(duì)應(yīng)型號(hào)。這意味著你的PCB不需要做任何修改直接把STM32換成GD32就能焊上去。這一點(diǎn)在缺貨時(shí)期救了很多人的急。寄存器層面GD32F103的外設(shè)寄存器地址和STM32F103基本一致但有一些細(xì)節(jié)差異。比如GD32的Flash訪問(wèn)速度更快官方標(biāo)稱主頻可以跑到108MHzSTM32F103是72MHz但如果你直接跑108MHz需要調(diào)整Flash等待周期否則會(huì)出現(xiàn)取指錯(cuò)誤。我一般建議在替代初期先按72MHz跑驗(yàn)證功能正常后再嘗試超頻。標(biāo)準(zhǔn)庫(kù)的兼容性方面GD32提供了自己的固件庫(kù)但API接口和STM32標(biāo)準(zhǔn)庫(kù)非常相似。大部分情況下你只需要把啟動(dòng)文件、鏈接腳本和少量寄存器定義換掉原來(lái)的代碼就能編譯通過(guò)。不過(guò)有幾個(gè)地方需要特別注意GD32的ADC在采樣時(shí)間和校準(zhǔn)流程上和STM32有差異直接套用STM32的ADC配置可能會(huì)導(dǎo)致采樣值偏差GD32的USART在波特率配置上也有細(xì)微差別高波特率下需要重新計(jì)算分頻值。HAL庫(kù)方面GD32官方也提供了HAL庫(kù)支持但成熟度不如標(biāo)準(zhǔn)庫(kù)。如果你原來(lái)用的是STM32 HAL庫(kù)遷移到GD32 HAL庫(kù)需要做一些適配工作。我個(gè)人的經(jīng)驗(yàn)是如果項(xiàng)目對(duì)實(shí)時(shí)性要求不高用標(biāo)準(zhǔn)庫(kù)遷移更省事如果項(xiàng)目本來(lái)就基于HAL庫(kù)開(kāi)發(fā)那就用GD32的HAL庫(kù)但要做好調(diào)試準(zhǔn)備。實(shí)操心得GD32替換STM32時(shí)第一件事是把系統(tǒng)時(shí)鐘配置從72MHz改成108MHz之前先確認(rèn)Flash等待周期設(shè)置正確。我見(jiàn)過(guò)有人直接改PLL倍頻結(jié)果程序跑飛了查了半天才發(fā)現(xiàn)是Flash等待周期沒(méi)改。3.2 APM32工業(yè)場(chǎng)景下的穩(wěn)妥選擇APM32是極海半導(dǎo)體的產(chǎn)品也是主打STM32兼容路線。相比GD32APM32在工業(yè)控制和汽車電子領(lǐng)域的布局更深入一些部分型號(hào)有車規(guī)級(jí)認(rèn)證。我有個(gè)做工業(yè)網(wǎng)關(guān)的客戶2021年因?yàn)镕103缺貨把整條產(chǎn)品線切到了APM32F103到目前為止跑了兩年多現(xiàn)場(chǎng)故障率很低。APM32F103和STM32F103在管腳上也是兼容的封裝選項(xiàng)基本一致。寄存器層面APM32的兼容性做得比較徹底標(biāo)準(zhǔn)庫(kù)代碼遷移過(guò)來(lái)基本不需要改動(dòng)。我實(shí)測(cè)過(guò)用STM32標(biāo)準(zhǔn)庫(kù)寫(xiě)的UART DMA收發(fā)代碼直接在APM32上編譯燒錄功能完全正常。不過(guò)APM32有幾個(gè)地方需要留意。首先是ADC的參考電壓APM32F103的VREF引腳行為和STM32略有不同如果你的板子上VREF接了外部基準(zhǔn)需要確認(rèn)電壓范圍是否匹配。其次是APM32的Flash編程算法在Keil里需要單獨(dú)安裝支持包不能直接用STM32的算法。還有就是APM32的USB外設(shè)雖然標(biāo)稱兼容STM32的USB庫(kù)但在虛擬串口應(yīng)用中枚舉過(guò)程偶爾會(huì)出現(xiàn)不穩(wěn)定需要調(diào)整上拉電阻或增加延時(shí)。APM32的一個(gè)優(yōu)勢(shì)是官方提供了比較完善的遷移文檔里面詳細(xì)列出了和STM32的差異點(diǎn)。我建議在做遷移之前先把這份文檔過(guò)一遍把和自己項(xiàng)目相關(guān)的外設(shè)差異標(biāo)記出來(lái)逐個(gè)驗(yàn)證。3.3 CH32性價(jià)比路線但有遷移成本CH32是沁恒微電子的產(chǎn)品走的是自研路線。CH32F103在管腳上和STM32F103兼容但寄存器映射和外設(shè)行為差別較大不能直接復(fù)用STM32的代碼。不過(guò)CH32的價(jià)格通常比GD32和APM32更有優(yōu)勢(shì)而且沁恒在USB和以太網(wǎng)外設(shè)上有自己的技術(shù)積累。我用CH32做過(guò)一個(gè)USB HID設(shè)備的項(xiàng)目整體感受是如果你愿意花時(shí)間研究它的寄存器手冊(cè)和官方例程CH32是能用的而且某些外設(shè)比如USB用起來(lái)比STM32還方便。但如果你指望把STM32的代碼直接搬過(guò)來(lái)那會(huì)非常痛苦。CH32的官方例程是基于自己的一套庫(kù)函數(shù)寫(xiě)的風(fēng)格和STM32標(biāo)準(zhǔn)庫(kù)不太一樣。比如GPIO的配置方式、中斷向量表的定義、時(shí)鐘使能的流程都需要重新學(xué)習(xí)。我建議新項(xiàng)目用CH32的話直接從官方例程開(kāi)始搭建框架不要試圖從STM32代碼遷移。另外CH32的開(kāi)發(fā)工具鏈支持Keil和MounRiver Studio基于Eclipse的免費(fèi)IDE。MounRiver Studio用起來(lái)還不錯(cuò)但如果你習(xí)慣了Keil的調(diào)試體驗(yàn)可能需要適應(yīng)一段時(shí)間。調(diào)試器方面CH32支持WCH-Link價(jià)格便宜但兼容性不如ST-Link廣泛。3.4 AT32兼容與自研之間的平衡AT32是雅特力的產(chǎn)品在兼容性上做了不少工作同時(shí)也在建自己的生態(tài)。AT32F403A和STM32F103在管腳上兼容官方提供了從STM32遷移的工具和文檔遷移工作量介于GD32和CH32之間。AT32的一個(gè)特點(diǎn)是主頻可以跑到240MHzAT32F403A性能比STM32F103強(qiáng)不少。如果你的項(xiàng)目原來(lái)用F103覺(jué)得算力不夠AT32可以作為一個(gè)升級(jí)選項(xiàng)。不過(guò)高主頻帶來(lái)的功耗和EMC問(wèn)題需要額外關(guān)注PCB設(shè)計(jì)上要做好電源去耦和信號(hào)完整性。AT32的官方庫(kù)函數(shù)風(fēng)格和STM32標(biāo)準(zhǔn)庫(kù)比較接近但有一些命名和參數(shù)上的差異。官方提供了一個(gè)“STM32代碼遷移指南”里面列出了常見(jiàn)的修改點(diǎn)。我實(shí)測(cè)下來(lái)一個(gè)中等復(fù)雜度的F103項(xiàng)目遷移到AT32大概需要兩到三天的調(diào)試時(shí)間主要花在時(shí)鐘配置和外設(shè)初始化上。3.5 選型對(duì)比速查表為了讓你更直觀地對(duì)比這幾款芯片我把關(guān)鍵信息整理成了下面這個(gè)表格。需要說(shuō)明的是這里的評(píng)價(jià)是基于我個(gè)人的使用體驗(yàn)不同項(xiàng)目場(chǎng)景下感受可能不同。對(duì)比項(xiàng)GD32F103APM32F103CH32F103AT32F403A管腳兼容STM32是是是是寄存器兼容STM32高高低中標(biāo)準(zhǔn)庫(kù)遷移難度低低高中HAL庫(kù)遷移難度中中不支持中最高主頻108MHz96MHz72MHz240MHzUSB支持有有有特色有CAN支持有有部分型號(hào)有開(kāi)發(fā)工具Keil/IARKeil/IARKeil/MounRiverKeil/IAR調(diào)試器ST-Link兼容ST-Link兼容WCH-LinkAT-Link/ST-Link社區(qū)資料豐富度高中中中價(jià)格水平中中低中高這個(gè)表格只是一個(gè)快速參考實(shí)際選型的時(shí)候還需要結(jié)合你的具體需求。比如你的項(xiàng)目需要CAN總線那就要確認(rèn)所選型號(hào)是否支持如果你的代碼量很大那寄存器兼容性就比價(jià)格更重要。4. 從STM32F103遷移到國(guó)產(chǎn)MCU的實(shí)操細(xì)節(jié)4.1 遷移前的代碼盤點(diǎn)與風(fēng)險(xiǎn)評(píng)估在動(dòng)手遷移之前我強(qiáng)烈建議你先做一次代碼盤點(diǎn)。把項(xiàng)目里用到的所有外設(shè)、中斷、DMA通道、特殊功能都列出來(lái)然后逐個(gè)評(píng)估遷移難度。這個(gè)步驟看起來(lái)繁瑣但能幫你提前發(fā)現(xiàn)風(fēng)險(xiǎn)點(diǎn)避免做到一半才發(fā)現(xiàn)某個(gè)外設(shè)不支持。我一般會(huì)用一個(gè)簡(jiǎn)單的表格來(lái)做這件事外設(shè)/功能STM32F103使用情況遷移風(fēng)險(xiǎn)備注GPIO普通輸入輸出低基本無(wú)差異USART3路其中1路DMA收發(fā)中需驗(yàn)證DMA觸發(fā)源SPI2路1路硬件SPI接Flash中需驗(yàn)證時(shí)序參數(shù)I2C1路接溫度傳感器中需驗(yàn)證時(shí)序和上拉ADC4通道內(nèi)部溫度采集高精度和校準(zhǔn)差異定時(shí)器TIM2 PWM輸出TIM3編碼器中需驗(yàn)證PWM模式USB虛擬串口高枚舉穩(wěn)定性需驗(yàn)證中斷多個(gè)外部中斷低向量表需確認(rèn)這個(gè)表格做完之后你就知道哪些地方需要重點(diǎn)調(diào)試。比如ADC和USB被標(biāo)為高風(fēng)險(xiǎn)那遷移后的第一件事就是驗(yàn)證這兩個(gè)功能。4.2 時(shí)鐘樹(shù)配置的差異與調(diào)整時(shí)鐘配置是遷移過(guò)程中最容易出問(wèn)題的地方。STM32F103的標(biāo)準(zhǔn)時(shí)鐘配置是8MHz外部晶振經(jīng)過(guò)PLL倍頻到72MHz而GD32F103可以跑到108MHzAPM32F103通常是96MHz。如果你直接套用原來(lái)的時(shí)鐘配置可能能跑但性能沒(méi)有發(fā)揮出來(lái)如果直接改成最高主頻又可能因?yàn)镕lash等待周期不對(duì)導(dǎo)致跑飛。以GD32F103為例從72MHz切換到108MHz需要做兩件事一是修改PLL的倍頻系數(shù)二是調(diào)整Flash等待周期。GD32的Flash在108MHz下需要插入2個(gè)等待周期而STM32在72MHz下只需要1個(gè)。如果你只改了PLL沒(méi)改Flash等待周期程序在運(yùn)行復(fù)雜代碼時(shí)會(huì)出現(xiàn)取指錯(cuò)誤表現(xiàn)為隨機(jī)死機(jī)或數(shù)據(jù)異常。具體操作上在標(biāo)準(zhǔn)庫(kù)的system_gd32f10x.c文件里找到SystemInit函數(shù)修改PLL配置和Flash等待周期的宏定義。如果你用的是HAL庫(kù)則在SystemClock_Config函數(shù)里調(diào)整。改完之后用示波器或者M(jìn)CO引腳輸出時(shí)鐘信號(hào)確認(rèn)實(shí)際主頻是否正確。注意超頻到108MHz雖然能提升性能但功耗和發(fā)熱也會(huì)增加。如果項(xiàng)目對(duì)功耗敏感建議還是按72MHz跑或者根據(jù)實(shí)際負(fù)載動(dòng)態(tài)調(diào)整主頻。4.3 外設(shè)寄存器的兼容性驗(yàn)證方法驗(yàn)證外設(shè)兼容性最直接的方法就是寫(xiě)一個(gè)最小測(cè)試程序逐個(gè)外設(shè)跑一遍。我一般會(huì)按照下面的順序來(lái)驗(yàn)證第一步GPIO。配置一個(gè)引腳為推挽輸出翻轉(zhuǎn)電平用示波器看波形。這個(gè)最簡(jiǎn)單基本不會(huì)有問(wèn)題。第二步USART。配置串口發(fā)送數(shù)據(jù)用USB轉(zhuǎn)串口工具接收確認(rèn)波特率準(zhǔn)確、數(shù)據(jù)無(wú)誤。然后測(cè)試中斷接收和DMA接收確認(rèn)數(shù)據(jù)不丟包。這里有個(gè)坑STM32F103的串口中斷接收在某些國(guó)產(chǎn)芯片上會(huì)出現(xiàn)丟數(shù)據(jù)包的情況原因是中斷響應(yīng)速度或者FIFO深度不同。如果發(fā)現(xiàn)丟包可以嘗試降低波特率或者改用DMA接收。第三步SPI。配置硬件SPI連接一個(gè)已知的SPI設(shè)備比如Flash芯片讀寫(xiě)數(shù)據(jù)并校驗(yàn)。這里需要關(guān)注SPI的時(shí)鐘極性、相位、數(shù)據(jù)位寬等參數(shù)是否和從設(shè)備匹配。有些國(guó)產(chǎn)芯片的SPI在高速下時(shí)序裕量不足需要降低時(shí)鐘頻率。第四步I2C。連接一個(gè)I2C傳感器比如MLX90614溫度傳感器讀取數(shù)據(jù)并校驗(yàn)。I2C的坑主要在時(shí)序上國(guó)產(chǎn)芯片的上拉電阻需求和STM32可能不同如果通信失敗先檢查上拉電阻是否合適。第五步ADC。這是差異最大的外設(shè)。用已知電壓輸入到ADC通道讀取采樣值計(jì)算誤差。STM32F103的ADC是12位但實(shí)際有效位數(shù)可能只有10位左右。國(guó)產(chǎn)芯片的ADC精度和線性度可能不同需要根據(jù)項(xiàng)目要求評(píng)估是否可接受。如果項(xiàng)目對(duì)ADC精度要求高建議外置ADC芯片。第六步定時(shí)器。配置PWM輸出用示波器看頻率和占空比。然后測(cè)試輸入捕獲和編碼器模式。定時(shí)器的兼容性通常比較好但PWM的死區(qū)時(shí)間和剎車功能需要特別驗(yàn)證。第七步USB。這是最復(fù)雜的外設(shè)。配置USB虛擬串口連接電腦確認(rèn)枚舉成功、數(shù)據(jù)收發(fā)正常。如果枚舉失敗檢查上拉電阻、晶振精度和USB庫(kù)的配置。有些國(guó)產(chǎn)芯片的USB在枚舉過(guò)程中需要額外的延時(shí)可以在USB中斷里加一點(diǎn)等待。4.4 中斷向量表和啟動(dòng)文件的處理從STM32遷移到國(guó)產(chǎn)MCU時(shí)中斷向量表和啟動(dòng)文件是需要替換的。STM32的啟動(dòng)文件是startup_stm32f10x_md.s而GD32對(duì)應(yīng)的是startup_gd32f10x_md.sAPM32對(duì)應(yīng)的是startup_apm32f10x_md.s。這些啟動(dòng)文件里的中斷向量表定義不同不能混用。替換啟動(dòng)文件后還需要確認(rèn)中斷服務(wù)函數(shù)的名稱是否匹配。比如STM32的串口1中斷函數(shù)是USART1_IRQHandlerGD32也是這個(gè)名字但有些國(guó)產(chǎn)芯片可能加了前綴或者改了大小寫(xiě)。如果編譯時(shí)報(bào)“未定義的中斷處理函數(shù)”就是這個(gè)問(wèn)題。另外鏈接腳本里的Flash和RAM地址也需要確認(rèn)。STM32F103C8T6的Flash是64KBRAM是20KB。GD32F103C8T6的Flash也是64KB但RAM可能是20KB或32KB具體看型號(hào)。如果鏈接腳本里的RAM大小設(shè)置不對(duì)可能會(huì)導(dǎo)致變量分配失敗或者棧溢出。4.5 調(diào)試工具與燒錄方式的適配調(diào)試工具方面GD32和APM32都兼容ST-Link可以直接用ST-Link燒錄和調(diào)試。但需要注意有些國(guó)產(chǎn)芯片的調(diào)試接口在復(fù)位后的初始狀態(tài)和STM32不同如果ST-Link連接不上可以嘗試在Keil的調(diào)試設(shè)置里把“Connect under reset”打開(kāi)。CH32需要用WCH-LinkAT32可以用AT-Link或者ST-Link。WCH-Link的價(jià)格很便宜但驅(qū)動(dòng)安裝和Keil配置需要參考官方文檔。AT-Link的體驗(yàn)和ST-Link差不多但如果你手頭只有ST-Link也可以直接用。燒錄算法方面GD32和APM32需要在Keil里安裝對(duì)應(yīng)的Device Family PackDFP里面包含了Flash編程算法。如果你用的是Keil 5可以通過(guò)Pack Installer在線安裝。如果網(wǎng)絡(luò)環(huán)境不好也可以從官網(wǎng)下載離線包手動(dòng)安裝。5. 那些年我踩過(guò)的坑國(guó)產(chǎn)MCU替代中的真實(shí)問(wèn)題記錄5.1 GD32的ADC采樣值偏大問(wèn)題有一次我用GD32F103替換STM32F103做電池電壓監(jiān)測(cè)發(fā)現(xiàn)ADC采樣值比實(shí)際電壓高了大約5%。一開(kāi)始以為是分壓電阻的問(wèn)題換了電阻還是偏大。后來(lái)查GD32的手冊(cè)才發(fā)現(xiàn)GD32的ADC在默認(rèn)配置下采樣時(shí)間比STM32短導(dǎo)致采樣電容沒(méi)有充分充電讀數(shù)偏高。解決辦法是增加ADC的采樣時(shí)間。在標(biāo)準(zhǔn)庫(kù)的ADC配置里把ADC_SampleTime_55Cycles5改成ADC_SampleTime_239Cycles5采樣值就正常了。這個(gè)坑讓我明白國(guó)產(chǎn)芯片的ADC不能直接套用STM32的配置必須根據(jù)實(shí)際信號(hào)源阻抗調(diào)整采樣時(shí)間。5.2 APM32的USB虛擬串口枚舉不穩(wěn)定另一個(gè)項(xiàng)目用APM32F103做USB虛擬串口發(fā)現(xiàn)插上電腦后有時(shí)候能識(shí)別有時(shí)候識(shí)別不了。用USB分析儀抓包發(fā)現(xiàn)枚舉過(guò)程中設(shè)備描述符的響應(yīng)時(shí)間偶爾超時(shí)。后來(lái)在APM32的官方論壇找到答案APM32的USB外設(shè)在某些批次的芯片上上拉電阻需要從1.5k改成1.2k否則信號(hào)上升沿不夠陡導(dǎo)致主機(jī)識(shí)別失敗。換了電阻之后枚舉成功率明顯提升。這個(gè)問(wèn)題的教訓(xùn)是國(guó)產(chǎn)芯片的外圍電路不能完全照搬STM32的參考設(shè)計(jì)需要根據(jù)芯片的實(shí)際特性做調(diào)整。5.3 CH32的串口DMA接收丟數(shù)據(jù)用CH32F103做串口DMA接收時(shí)發(fā)現(xiàn)高速率下偶爾丟數(shù)據(jù)。查手冊(cè)發(fā)現(xiàn)CH32的DMA控制器在傳輸完成中斷的響應(yīng)速度上比STM32慢如果波特率太高DMA傳輸完成中斷還沒(méi)處理完下一包數(shù)據(jù)就來(lái)了導(dǎo)致覆蓋。解決辦法是改用雙緩沖DMA模式或者降低波特率。如果項(xiàng)目必須用高波特率建議用中斷接收代替DMA雖然CPU占用率高一些但不會(huì)丟數(shù)據(jù)。5.4 國(guó)產(chǎn)MCU的Flash編程次數(shù)限制還有一個(gè)容易被忽略的問(wèn)題國(guó)產(chǎn)MCU的Flash編程次數(shù)通常比STM32少。STM32F103的Flash擦寫(xiě)次數(shù)標(biāo)稱10萬(wàn)次而有些國(guó)產(chǎn)芯片只有1萬(wàn)次。如果你的項(xiàng)目需要在運(yùn)行時(shí)頻繁寫(xiě)入Flash比如保存參數(shù)需要特別注意這一點(diǎn)。建議用EEPROM或者外置Flash來(lái)保存頻繁寫(xiě)入的數(shù)據(jù)不要直接寫(xiě)內(nèi)部Flash。5.5 溫度范圍與可靠性差異工業(yè)場(chǎng)景下溫度范圍是一個(gè)硬指標(biāo)。STM32F103的工業(yè)級(jí)型號(hào)是-40到85度有些國(guó)產(chǎn)芯片的工業(yè)級(jí)型號(hào)也是這個(gè)范圍但實(shí)際測(cè)試中高溫下的穩(wěn)定性可能有差異。我建議在選型階段就做高低溫測(cè)試把板子放到溫箱里跑一遍確認(rèn)在溫度極限下功能正常。另外國(guó)產(chǎn)MCU的ESD等級(jí)也需要關(guān)注。有些芯片的HBM模式ESD只有2kV而STM32通常是4kV。如果你的產(chǎn)品需要在惡劣電磁環(huán)境下工作建議增加外部ESD保護(hù)器件。6. 新項(xiàng)目選型的決策框架與長(zhǎng)期供貨策略6.1 根據(jù)項(xiàng)目類型選擇替代路線新項(xiàng)目選型的時(shí)候我一般會(huì)先問(wèn)幾個(gè)問(wèn)題項(xiàng)目對(duì)成本有多敏感開(kāi)發(fā)周期有多長(zhǎng)團(tuán)隊(duì)對(duì)STM32的熟悉程度如何產(chǎn)品預(yù)計(jì)的生命周期是多久如果項(xiàng)目成本敏感、開(kāi)發(fā)周期充裕、團(tuán)隊(duì)愿意學(xué)習(xí)新東西CH32或HC32是不錯(cuò)的選擇價(jià)格有優(yōu)勢(shì)外設(shè)也有特色。如果項(xiàng)目開(kāi)發(fā)周期緊、團(tuán)隊(duì)對(duì)STM32生態(tài)依賴深GD32或APM32更穩(wěn)妥遷移成本低。如果項(xiàng)目對(duì)性能要求高AT32的高主頻型號(hào)值得考慮。6.2 雙供應(yīng)鏈策略的落地方法經(jīng)歷過(guò)缺貨之后我現(xiàn)在做新項(xiàng)目都會(huì)考慮雙供應(yīng)鏈策略。具體做法是在PCB設(shè)計(jì)階段就預(yù)留至少兩顆芯片的兼容性比如同時(shí)支持STM32F103和GD32F103的焊盤。固件層面用條件編譯來(lái)區(qū)分不同芯片的配置把芯片相關(guān)的代碼集中到一個(gè)文件里方便切換。這樣做的成本增加很少但能在缺貨時(shí)快速切換避免項(xiàng)目停擺。我有個(gè)客戶就是靠這個(gè)策略在2022年F103再次缺貨時(shí)一周內(nèi)完成了產(chǎn)線切換沒(méi)有影響交付。6.3 長(zhǎng)期供貨與代理商選擇國(guó)產(chǎn)MCU的供貨能力這幾年提升很快但不同品牌的渠道策略不一樣。GD32和APM32的代理商網(wǎng)絡(luò)比較成熟批量采購(gòu)可以通過(guò)正規(guī)代理商拿貨價(jià)格和交期相對(duì)穩(wěn)定。CH32和AT32的渠道也在完善中但有些型號(hào)可能需要通過(guò)原廠或者特定的方案商拿貨。我建議在選型階段就和原廠或代理商確認(rèn)長(zhǎng)期供貨計(jì)劃特別是對(duì)于生命周期超過(guò)三年的產(chǎn)品。有些國(guó)產(chǎn)芯片廠商會(huì)提供“長(zhǎng)期供貨承諾”但具體條款需要仔細(xì)看比如是否包含停產(chǎn)通知期、最后一次采購(gòu)機(jī)會(huì)等。6.4 國(guó)產(chǎn)MCU的生態(tài)建設(shè)現(xiàn)狀客觀地說(shuō)國(guó)產(chǎn)MCU的生態(tài)和STM32還有差距。STM32有十幾年的積累社區(qū)里幾乎任何問(wèn)題都能找到答案。國(guó)產(chǎn)MCU的社區(qū)還在建設(shè)中有些問(wèn)題可能需要直接聯(lián)系原廠FAE才能解決。不過(guò)這個(gè)差距在縮小。GD32和APM32的官方論壇活躍度不錯(cuò)AT32和CH32也在加強(qiáng)文檔和例程的建設(shè)。我個(gè)人的感受是只要你選的是主流型號(hào)大部分常見(jiàn)問(wèn)題都能找到資料。真正卡住人的往往是一些邊緣問(wèn)題比如某個(gè)外設(shè)在特定條件下的異常行為這種就需要靠FAE支持或者自己啃手冊(cè)了。7. 一些實(shí)用的遷移檢查清單與工具推薦7.1 遷移前檢查清單在開(kāi)始遷移之前對(duì)照下面這個(gè)清單逐項(xiàng)確認(rèn)能幫你避免大部分低級(jí)錯(cuò)誤確認(rèn)目標(biāo)芯片的封裝和管腳定義核對(duì)PCB是否需要修改確認(rèn)目標(biāo)芯片的Flash和RAM容量檢查鏈接腳本是否匹配確認(rèn)目標(biāo)芯片的啟動(dòng)文件替換為對(duì)應(yīng)型號(hào)的啟動(dòng)文件確認(rèn)中斷向量表檢查中斷服務(wù)函數(shù)名稱是否一致確認(rèn)時(shí)鐘樹(shù)配置調(diào)整PLL和Flash等待周期確認(rèn)外設(shè)寄存器定義替換為對(duì)應(yīng)芯片的頭文件確認(rèn)調(diào)試器和燒錄算法安裝對(duì)應(yīng)的DFP支持包確認(rèn)USB上拉電阻和晶振精度必要時(shí)調(diào)整外圍電路確認(rèn)ADC采樣時(shí)間和參考電壓根據(jù)實(shí)際信號(hào)調(diào)整確認(rèn)DMA通道映射檢查是否有沖突7.2 常用調(diào)試工具與技巧調(diào)試國(guó)產(chǎn)MCU的時(shí)候有幾個(gè)工具和技巧特別有用。首先是邏輯分析儀用來(lái)抓SPI、I2C、UART的時(shí)序比示波器更方便看協(xié)議層的數(shù)據(jù)。我常用的是Saleae Logic或者國(guó)產(chǎn)的LA系列價(jià)格不貴配合協(xié)議解碼軟件很好用。其次是USB分析儀調(diào)試USB虛擬串口的時(shí)候必備。如果沒(méi)有硬件分析儀可以用Wireshark配合USBPcap軟件抓包雖然不如硬件分析儀方便但能解決大部分問(wèn)題。還有就是用GPIO翻轉(zhuǎn)來(lái)測(cè)量代碼執(zhí)行時(shí)間。在關(guān)鍵代碼段的前后各翻轉(zhuǎn)一個(gè)GPIO用示波器看脈沖寬度就能知道這段代碼跑了多久。這個(gè)方法在優(yōu)化性能的時(shí)候特別有用。7.3 代碼組織建議為了讓遷移更容易我建議在寫(xiě)代碼的時(shí)候就做好分層。把芯片相關(guān)的代碼時(shí)鐘配置、外設(shè)初始化、中斷處理集中到一個(gè)或幾個(gè)文件里用宏定義來(lái)區(qū)分不同芯片。應(yīng)用層代碼不要直接操作寄存器而是通過(guò)統(tǒng)一的接口函數(shù)來(lái)調(diào)用。這樣做的另一個(gè)好處是以后如果還要換芯片只需要修改芯片相關(guān)的文件應(yīng)用層代碼基本不用動(dòng)。我有個(gè)項(xiàng)目從STM32遷到GD32再遷到APM32因?yàn)榇a分層做得好每次遷移都只花了一兩天。8. 寫(xiě)在最后替代不是終點(diǎn)而是新的起點(diǎn)回頭看這幾年國(guó)產(chǎn)MCU替代的經(jīng)歷最大的感受是替代這件事技術(shù)上的難度其實(shí)沒(méi)有想象中那么大真正難的是心態(tài)和習(xí)慣的轉(zhuǎn)變。我們習(xí)慣了STM32的生態(tài)習(xí)慣了遇到問(wèn)題就搜社區(qū)習(xí)慣了標(biāo)準(zhǔn)庫(kù)和HAL庫(kù)的寫(xiě)法。換到國(guó)產(chǎn)芯片之后這些習(xí)慣都需要調(diào)整。但這個(gè)過(guò)程也是有好處的。當(dāng)你被迫去讀寄存器手冊(cè)、去理解外設(shè)的底層行為、去和原廠FAE溝通的時(shí)候你對(duì)嵌入式系統(tǒng)的理解會(huì)更深。我以前用STM32的時(shí)候很多配置都是抄例程知其然不知其所以然。用了國(guó)產(chǎn)芯片之后因?yàn)槔滩粔蚨喾炊浦约喝タ词謨?cè)、去分析時(shí)序技術(shù)能力提升了不少。國(guó)產(chǎn)MCU這幾年的進(jìn)步是實(shí)實(shí)在在的。GD32、APM32、CH32、AT32這些品牌已經(jīng)能滿足大部分中低端應(yīng)用的需求。雖然在高端市場(chǎng)和生態(tài)建設(shè)上還有差距但對(duì)于大多數(shù)項(xiàng)目來(lái)說(shuō)替代方案已經(jīng)足夠成熟。如果你現(xiàn)在還在為F103缺貨發(fā)愁我的建議是先做代碼盤點(diǎn)評(píng)估遷移風(fēng)險(xiǎn)然后選一顆主流國(guó)產(chǎn)芯片按照我上面說(shuō)的步驟一步步驗(yàn)證。不要指望一次成功留出足夠的調(diào)試時(shí)間。遇到問(wèn)題的時(shí)候先查手冊(cè)再找FAE最后再考慮換方案。大部分問(wèn)題都是可以解決的。最后分享一個(gè)小技巧在做替代驗(yàn)證的時(shí)候準(zhǔn)備兩塊板子一塊焊原芯片一塊焊替代芯片用同樣的測(cè)試程序跑對(duì)比輸出結(jié)果。這樣能快速定位差異比單獨(dú)調(diào)試替代芯片效率高很多。這個(gè)方法是我在一個(gè)工業(yè)項(xiàng)目里總結(jié)出來(lái)的當(dāng)時(shí)用GD32替換STM32就是靠對(duì)比測(cè)試在兩天內(nèi)完成了全部外設(shè)的驗(yàn)證。