
1. 項目概述深入解讀CH32F20x系列MCU的模擬外設最近在做一個需要高精度溫度采集和模擬信號調理的項目選型時把目光投向了國產的CH32F20x系列MCU。這個系列尤其是CH32F205/207/203這幾款以其高性價比和豐富的外設資源在圈內口碑不錯。但說實話剛開始看數據手冊時關于其內置溫度傳感器、DAC數模轉換器和OPA運算放大器這部分總覺得有些細節沒說透比如溫度傳感器的精度到底受什么影響、DAC輸出如何穩定、OPA怎么配置才能發揮最佳性能。網上的資料要么太零散要么就是直接照著手冊念對于實際開發中可能遇到的坑提得很少。我花了不少時間結合數據手冊、勘誤文檔以及自己的實測把這幾個模擬外設的特性、工作原理、配置方法和避坑要點都梳理了一遍。這篇文章就是這些經驗的總結目標很明確讓你在用到CH32F20x的模擬功能時能快速上手少走彎路。無論你是正在評估這顆芯片還是已經用上了但在調試中遇到了問題相信下面的內容都能給你提供直接的幫助。2. 核心外設深度解析與設計考量CH32F20x系列作為一款主打高性能和集成度的MCU其模擬外設的設計意圖是讓用戶在單芯片上完成信號采集、處理和輸出的閉環減少外部元件降低系統成本和PCB面積。理解每個外設的設計邏輯是正確使用它們的前提。2.1 溫度傳感器不僅僅是“有”這個功能很多MCU都宣稱內置溫度傳感器但CH32F20x的這顆需要你特別關注其“測量方法”而非“絕對精度”。數據手冊會給出一個典型值比如±1.5°C但這個精度是在特定條件下例如特定的VREF、特定的采樣時間、特定的環境校準出來的。它的核心價值在于測量芯片結溫的相對變化而不是提供一個實驗室級別的絕對溫度值。它的工作原理是利用半導體PN結的正向壓降與溫度的線性關系。在芯片內部一個特殊的PN結被用作傳感元件其電壓V_BE會隨溫度變化。內部電路將這個電壓通過一個模擬開關連接到ADC的輸入通道通常是ADC_IN16或ADC_IN17具體需查對應型號的數據手冊。因此溫度測量本質上是一次ADC轉換。這意味著測量結果的質量直接受到ADC參考電壓穩定性、采樣時間、電源噪聲乃至軟件濾波算法的影響。在設計上它最適合的應用場景包括系統過熱保護監控MCU自身溫度在結溫超過安全閾值如85°C或105°C時觸發降頻、關閉外設或報警。環境溫度趨勢監測在設備內部如果MCU與環境熱耦合較好可以用它來近似反映環境溫度的變化趨勢用于風扇調速等。校準其他傳感器作為輔助參考對其他溫度傳感器如熱敏電阻的讀數進行粗略的補償。注意切勿將其用于需要高精度絕對溫度測量的場合如恒溫控制、醫療測溫等。它的主要誤差來源包括出廠校準偏差、ADC的積分非線性INL、差分非線性DNL誤差以及電源電壓波動對VREF的影響。2.2 DAC雙通道的靈活輸出引擎CH32F20x集成了兩個12位分辨率的DAC通道這算是中高端MCU的標配。但它的亮點在于輸出模式的靈活性和與內部其他模塊的聯動能力。每個DAC通道都可以獨立配置為多種工作模式理解這些模式的區別是高效使用的關鍵。輸出模式解析正常模式DAC輸出由寫入數據保持寄存器DHRx的值直接決定。這是最常用的模式用于產生靜態電壓或由軟件緩慢更新的電壓信號。噪聲生成模式DAC輸出由一個偽隨機數生成器線性反饋移位寄存器LFSR控制。你可以設置LFSR的掩碼來改變噪聲的頻譜特性。這個模式常用于測試系統的噪聲抑制能力或者生成特定的白噪聲信號。三角波生成模式DAC輸出會在用戶定義幅值通過設置MAMPx位內自動遞增/遞減生成三角波。這個模式完全由硬件完成不占用CPU資源非常適合生成周期性的掃描信號例如用于傳感器特性曲線掃描。關鍵設計考量參考電壓選擇DAC的輸出范圍取決于其參考電壓VREF。CH32F20x的DAC通常與ADC共享VREF引腳。你可以選擇內部參考電壓如果芯片提供通常精度一般或者連接一個高精度、低溫漂的外部基準源如REF3025。這是決定DAC輸出絕對精度的最關鍵因素。輸出緩沖器DAC輸出端集成了可開關的輸出緩沖放大器。開啟緩沖器后DAC具有更強的帶負載能力可驅動容性負載但會引入一定的偏移誤差和非線性。關閉緩沖器則能獲得更好的直流精度和線性度但驅動能力很弱只能接高阻抗負載如運放的同相輸入端。我的經驗是如果后級是運放電路通常關閉緩沖器如果直接驅動負載則必須開啟。與DMA、定時器的聯動DAC支持通過DMA自動更新輸出數據。你可以將一段波形數據如正弦波表存放在內存中由定時器觸發DMA傳輸到DAC從而高效地生成任意復雜波形。這是實現高質量信號發生器的核心。2.3 OPA片內信號調理的瑞士軍刀集成OPA是CH32F20x系列一個非常實用的特性。它把信號調理電路從外部搬到了芯片內部不僅節省了空間和成本還減少了因PCB布局和外部元件離散性引入的噪聲和誤差。這個片內OPA通常被設計為通用運算放大器支持多種經典電路配置電壓跟隨器用于阻抗匹配將高阻抗信號源轉換為低阻抗輸出。同相/反相放大器對模擬信號進行固定增益的放大或衰減。差分放大器配合內部多路復用器可以用于測量差分信號抑制共模噪聲。濾波器通過外部連接電阻和電容可以構成有源低通、高通或帶通濾波器。在實際項目中的應用優勢直接連接傳感器例如可以直接將熱電偶、橋式壓力傳感器的微小差分輸出連接到OPA的輸入端進行第一級放大再送入ADC極大地簡化了前端電路。DAC輸出緩沖與調理雖然DAC自帶緩沖器但有時需要額外的增益或電平移位。可以用OPA來緩沖和調理DAC的輸出信號形成完整的可編程模擬輸出通道。降低系統噪聲由于OPA在芯片內部其與ADC、DAC之間的信號路徑極短受外部電磁干擾EMI的影響遠小于使用外部運放。實操心得片內OPA的性能參數如增益帶寬積、壓擺率、輸入失調電壓通常不如頂級的外部獨立運放。數據手冊會給出典型值。在設計中務必根據你的信號頻率、精度要求來評估其是否滿足需求。對于直流或低頻高精度應用需要注意其輸入失調電壓和溫漂對于高速信號則需要關注其壓擺率和帶寬。3. 外設配置與協同工作實戰理解了單個外設的特性后如何讓它們協同工作完成一個具體的任務才是工程實現的關鍵。下面我們以一個典型的應用場景為例“使用內部溫度傳感器監測芯片溫度并通過DAC輸出一個與溫度成比例的電壓同時用OPA對這個電壓進行緩沖放大”。3.1 硬件連接與初始化順序假設我們使用CH32F207并選擇內部VREF作為ADC和DAC的參考電壓。電源與參考電壓確保VREF引腳連接了足夠的去耦電容通常是一個10uF的鉭電容并聯一個100nF的陶瓷電容并且電源穩定。這是所有模擬電路精度的基礎。ADC初始化用于溫度傳感器使能ADC和GPIO時鐘溫度傳感器通道對應的GPIO雖然信號在內部但相關ADC模塊時鐘需開啟。配置ADC為獨立模式設置分辨率12位、數據對齊方式右對齊。設置采樣時間。對于溫度傳感器這類高內阻信號源必須延長采樣時間建議設置為ADC采樣周期中允許的最大值例如239.5個周期讓采樣電容充分充電這是提高測量穩定性的最重要一步。校準ADC先執行上電校準如果有的話。選擇溫度傳感器對應的ADC輸入通道如ADC_IN16。DAC初始化使能DAC和對應GPIO端口時鐘DAC_OUT1/2對應的PA4/PA5。配置GPIO為模擬模式非常重要避免數字信號干擾。配置DAC通道例如通道1。選擇觸發源如果使用軟件觸發則選擇“軟件觸發”。設置輸出緩沖器狀態根據負載決定開或關。使能DAC通道。如果需要使能DAC的DMA功能并配置DMA通道。OPA初始化使能OPA時鐘。配置OPA的工作模式。例如配置為跟隨器模式或同相放大器模式。這通常通過配置OPA的控制寄存器完成包括選擇同相輸入源來自內部多路選擇器或外部引腳、反相輸入連接方式內部反饋或外部引腳等。連接外部反饋網絡如果需要。對于同相放大器需要在OPA輸出引腳和反相輸入引腳之間連接電阻同時在反相輸入和地之間連接另一個電阻。這些電阻需要焊接在PCB上。使能OPA。初始化順序建議先初始化ADC和DAC最后初始化OPA。因為OPA可能依賴于前級信號如DAC輸出已經穩定。3.2 溫度讀取與DAC輸出聯動代碼示例以下是基于HAL庫或類似固件庫的核心代碼邏輯框架// 1. 讀取溫度傳感器ADC值 uint16_t Read_TemperatureSensor(void) { ADC_ChannelConfTypeDef sConfig {0}; uint16_t raw_adc_value 0; // 選擇溫度傳感器通道 sConfig.Channel ADC_CHANNEL_16; // 根據實際型號調整 sConfig.Rank 1; sConfig.SamplingTime ADC_SAMPLETIME_239CYCLES_5; // 使用長采樣時間 if (HAL_ADC_ConfigChannel(hadc1, sConfig) ! HAL_OK) { Error_Handler(); } HAL_ADC_Start(hadc1); if (HAL_ADC_PollForConversion(hadc1, 10) HAL_OK) { raw_adc_value HAL_ADC_GetValue(hadc1); } HAL_ADC_Stop(hadc1); return raw_adc_value; } // 2. 將ADC值轉換為溫度近似計算需根據手冊公式校準 float Convert_ADC_to_Temperature(uint16_t adc_value, float vref_mv) { // 公式參考數據手冊Vsense (ADC_VALUE * VREF) / 4095 // 溫度 T (Vsense - V25) / Avg_Slope 25 // 其中 V25 是25°C時的傳感器電壓Avg_Slope是平均斜率mV/°C // 這些參數在數據手冊的電氣特性章節可以找到典型值例如 // V25 1.43V, Avg_Slope 4.3 mV/°C 這些值必須用你手中的芯片實測校準 const float V25 1.43f; const float Avg_Slope 0.0043f; // 單位 V/°C float vsense (adc_value * vref_mv / 1000.0f) / 4095.0f; float temperature (vsense - V25) / Avg_Slope 25.0f; return temperature; } // 3. 根據溫度設置DAC輸出例如溫度每升高1°CDAC輸出增加10mV void Set_DAC_By_Temperature(float temperature) { // 設計輸出關系Vout (Temperature - 20.0) * 0.01 1.0 (V) // 假設VREF 3.3V DAC為12位 float target_voltage (temperature - 20.0f) * 0.01f 1.0f; // 限制電壓在0-VREF之間 if (target_voltage 0) target_voltage 0; if (target_voltage 3.3f) target_voltage 3.3f; // 計算DAC數值 uint16_t dac_value (uint16_t)((target_voltage / 3.3f) * 4095.0f); // 寫入DAC數據保持寄存器 HAL_DAC_SetValue(hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R, dac_value); // 如果需要軟件觸發更新如果配置為軟件觸發模式 // HAL_DAC_Start(hdac, DAC_CHANNEL_1); } // 主循環中的調用示例 float vref_internal 3.3f; // 假設使用內部3.3V參考實際需測量或使用更準的基準 while (1) { uint16_t adc_val Read_TemperatureSensor(); float temp Convert_ADC_to_Temperature(adc_val, vref_internal); Set_DAC_By_Temperature(temp); HAL_Delay(1000); // 每秒更新一次 }3.3 OPA作為DAC緩沖器的配置要點在上面的例子中DAC的輸出可能驅動能力不足或需要隔離。我們可以配置片內OPA為電壓跟隨器連接在DAC輸出和最終負載之間。硬件連接在PCB設計時將DAC的輸出引腳如PA4連接到OPA的同相輸入端引腳OPAx_INP將OPA的輸出引腳OPAx_OUT連接到負載。同時將OPA的輸出引腳通過一根短線連接到其反相輸入端引腳OPAx_INN這樣就構成了電壓跟隨器。軟件配置// 配置OPA為跟隨器模式 OPA_HandleTypeDef hopa; hopa.Instance OPA1; // 使用OPA1實例 hopa.Init.Mode OPA_MODE_FOLLOWER; // 跟隨器模式 hopa.Init.PowerSupplyRange OPA_POWERSUPPLY_LOW; // 根據電源選擇 hopa.Init.PowerMode OPA_POWERMODE_NORMAL; // ... 其他參數 if (HAL_OPA_Init(hopa) ! HAL_OK) { Error_Handler(); } HAL_OPA_Start(hopa); // 啟動OPA效果此時OPA的輸出電壓將緊緊跟隨DAC的輸出電壓但提供了極低的輸出阻抗可以驅動更大的容性負載或電阻負載而不會影響DAC本身的精度。4. 精度提升技巧與常見問題排查即使按照手冊配置在實際電路中也可能無法達到理想的性能。下面分享一些提升精度和穩定性的實戰技巧以及常見問題的排查思路。4.1 溫度傳感器讀數跳變大怎么辦這是最常見的問題。現象是連續讀取的溫度ADC值波動很大換算后的溫度上下跳動好幾度。排查步驟1檢查電源和地。用示波器探頭設置為交流耦合觀察MCU的VDD和VSS引腳看是否有高頻噪聲。模擬電路的精度直接依賴于電源的純凈度。確保電源電路有足夠的濾波電容并且PCB布局上模擬電源部分采用了星型接地或單點接地遠離數字電源的噪聲源。排查步驟2優化ADC采樣時間。如3.1節所述務必增加采樣時間。溫度傳感器內部等效電阻較大采樣電容充電慢。將采樣時間設置為最大值能顯著改善。排查步驟3軟件濾波。硬件穩定后在軟件端實施濾波算法。最簡單的就是滑動平均濾波。連續采樣N次比如16次或32次然后取平均值。更高級的可以用一階低通數字濾波器。#define FILTER_LEN 16 uint16_t adc_filter_buffer[FILTER_LEN] {0}; uint8_t filter_index 0; uint32_t adc_sum 0; // 在讀取ADC的函數中 raw_adc_value HAL_ADC_GetValue(hadc1); adc_sum - adc_filter_buffer[filter_index]; // 減去最舊的值 adc_filter_buffer[filter_index] raw_adc_value; // 存入新值 adc_sum raw_adc_value; filter_index (filter_index 1) % FILTER_LEN; uint16_t filtered_adc_value adc_sum / FILTER_LEN; // 計算平均值排查步驟4參考電壓穩定性。如果使用VDDA作為VREF其噪聲會直接引入測量誤差。考慮使用獨立、安靜的外部基準源如REF3033為VREF引腳供電。4.2 DAC輸出有毛刺或噪聲DAC輸出在代碼更新數值時出現尖峰或者本應穩定的直流輸出上有高頻噪聲。毛刺問題這通常發生在DAC數據更新時刻稱為“更新毛刺Update Glitch”。解決方案是啟用DAC的輸出緩沖器。緩沖器內部的放大器可以抑制這種毛刺。如果緩沖器已經開啟但仍有毛刺可以在DAC輸出端對地加一個小電容如100pF進行濾波但注意電容過大會影響響應速度。高頻噪聲問題檢查電源同樣用示波器看VREF和VDDA的噪聲。檢查PCB布局DAC輸出走線是否過長是否靠近時鐘線、高速數據線等噪聲源理想情況下DAC輸出應使用短的走線直接連接到負載或OPA輸入端并用地線包圍進行屏蔽。使用OPA緩沖如3.3節所述使用片內OPA作為跟隨器可以有效隔離后端負載變化對DAC芯片內部的影響。硬件濾波在DAC輸出端添加一個RC低通濾波器。例如一個1kΩ電阻串聯在輸出通路上后接一個100nF電容到地。這能濾除高頻噪聲但會降低帶寬。4.3 OPA輸出異常飽和、振蕩或精度差輸出飽和始終為高電平或低電平檢查供電確認OPA的供電電壓是否正常且滿足信號擺幅要求。輸入信號電壓是否在OPA的共模輸入電壓范圍之內輸出信號是否超出了電源軌檢查反饋網絡如果是放大器配置檢查連接在OPA輸出和反相輸入端之間的反饋電阻是否焊接良好阻值是否正確。開路的反饋會導致運放開環增益極大極易飽和。輸出振蕩高頻自激這是運放電路的典型問題。片內OPA的相位裕度可能不高當驅動容性負載時容易振蕩。解決方案在OPA輸出端串聯一個小的電阻如10-100Ω再連接到容性負載。這個電阻與負載電容構成了一個極點有助于穩定系統。檢查PCB布局反饋走線是否過長應盡可能短而直。直流精度差輸出有固定偏差輸入失調電壓Vos這是集成運放的固有缺陷。對于直流放大應用這個誤差會被放大。數據手冊會給出最大失調電壓。如果誤差超出可接受范圍有幾種辦法一是在軟件中進行校準測量零點輸出并減去二是如果芯片支持查找是否有內部失調電壓校準寄存器部分MCU的OPA提供此功能三是對于要求極高的應用可能需要考慮使用外部低失調運放。4.4 校準讓數據更可信對于精度要求稍高的應用軟件校準是必不可少的步驟。溫度傳感器校準單點校準在已知的、穩定的環境溫度T_known例如25°C的恒溫箱下讀取此時的ADC值ADC_known。則溫度計算公式可修正為T (ADC_raw - ADC_known) / Slope T_known。其中Slope可以使用手冊典型值或通過兩點校準求得。兩點校準在溫度T1和T2下T1和T2相差盡量大分別讀取ADC1和ADC2。計算斜率Slope (T2 - T1) / (ADC2 - ADC1)。然后將斜率和其中一個點代入公式。兩點校準能同時修正斜率和偏移誤差效果更好。DAC輸出校準使用一個高精度的數字萬用表測量DAC在幾個關鍵代碼值如0 2048 4095下的實際輸出電壓。記錄測量值與理論值比較。可以在軟件中建立一個查找表LUT或擬合一個線性/多項式校正函數在輸出前對DAC代碼進行補償。系統級校準如果DACOPA作為一個模擬輸出通道可以將最終輸出連接回ADC的另一個輸入通道構成一個自校準環路。MCU控制DAC輸出一個已知電壓然后用ADC讀回來計算出整個鏈路的增益和偏移誤差并在軟件中補償。這種方法可以實現閉環校準精度最高。5. 進階應用與性能壓測當你掌握了基礎功能后可以嘗試一些更復雜的應用并測試這些模擬外設的性能邊界。5.1 構建一個簡易的波形發生器利用DAC的DMA定時器觸發模式可以輕松實現波形發生器。生成波形表在PC上或用MCU計算一個周期的波形數據如正弦波、三角波、方波存入數組。對于12位DAC數組元素為uint16_t類型。#define WAVE_TABLE_SIZE 256 uint16_t sine_wave[WAVE_TABLE_SIZE]; for (int i 0; i WAVE_TABLE_SIZE; i) { sine_wave[i] (uint16_t)(2048 * (1.0 sin(2 * PI * i / WAVE_TABLE_SIZE))); // 輸出范圍 0-3.3V }配置DMA將DMA配置為從內存波形數組到外設DAC數據寄存器的循環傳輸模式。配置定時器選擇一個定時器如TIM6作為觸發源。定時器的更新頻率決定了波形輸出的頻率。輸出頻率 定時器觸發頻率 / 波形表長度。配置DAC將DAC觸發源設置為該定時器。使能DAC的DMA請求。啟動啟動DMA啟動定時器。此時DAC就會以設定的頻率自動、循環地輸出波形表中的數據CPU完全被解放。性能考量輸出波形的最高頻率受限于DAC的建立時間、DMA傳輸速度和定時器頻率。對于CH32F20x在72MHz系統時鐘下輸出幾十kHz的正弦波是可行的。要輸出更高頻率需要減少波形表點數但這會降低波形質量。5.2 使用OPA和ADC實現高精度差分測量假設要測量一個橋式傳感器的差分輸出mV級。配置OPA為差分放大器將傳感器的正端接OPA同相輸入OPAx_INP負端接OPA反相輸入OPAx_INN。通過外部電阻網絡設置OPA的增益。例如選擇Rf100kΩ Rg10kΩ則增益G 1 Rf/Rg 11。在軟件中配置OPA為外部反饋模式并選擇正確的輸入通道。連接ADC將OPA的輸出連接到ADC的一個輸入通道。軟件處理首先在傳感器無負載或已知負載時讀取一個ADC值作為“零位”基準。然后在測量時讀取新的ADC值減去零位基準再根據ADC參考電壓和OPA的增益換算成實際的傳感器電壓差。注意必須考慮OPA的輸入失調電壓和溫漂。對于高精度測量需要進行系統校準在差分輸入端施加幾個已知的精確電壓如0V 1mV 2mV記錄ADC輸出建立校準曲線。5.3 極限性能測試與數據手冊參數驗證你可以設計一些簡單的測試來驗證芯片是否達到數據手冊標稱的性能DAC的INL/DNL測試編寫一個程序讓DAC從0到4095步進輸出每一個碼值。用一個高精度至少16位的ADC板卡或另一臺高精度萬用表測量每個碼值對應的實際電壓。將測量數據導入電腦用軟件計算積分非線性INL和差分非線性DNL。這能直觀地看到DAC的線性度。OPA的增益帶寬積測試將OPA配置為固定增益如10倍的同相放大器。輸入一個固定幅度如100mVpp的正弦小信號用信號發生器和示波器配合逐漸增加輸入信號頻率觀察輸出信號幅度下降到-3dB即幅度變為原來的0.707倍時的頻率。這個頻率點大約就是該增益下的帶寬。可以驗證其是否與手冊中的增益帶寬積參數相符GBW 增益 * 帶寬。溫度傳感器的長期穩定性測試將芯片置于恒溫環境中如25°C恒溫箱連續讀取溫度傳感器ADC值數小時甚至數天觀察其波動范圍。這可以評估傳感器和ADC的噪聲水平。通過這些深入的測試和應用你不僅能更好地使用CH32F20x的模擬外設還能對其真實性能有更準確的把握從而在未來的產品設計中做出更可靠的決策。記住數據手冊給出的是典型值或最大值實際性能因芯片個體、供電、PCB布局和溫度而異動手測試永遠是工程師最可靠的工具。