器觸發(fā)ADC+DMA實(shí)現(xiàn)工業(yè)級(jí)高精度周期采樣)
簡(jiǎn)介本資源是面向嵌入式開(kāi)發(fā)初學(xué)者與STM32進(jìn)階實(shí)踐者的完整工程示例聚焦STM32F103系列中定時(shí)器精準(zhǔn)觸發(fā)ADC采集的核心技術(shù)實(shí)現(xiàn)解決模擬信號(hào)周期性、同步化采樣的典型工程難題適用于傳感器數(shù)據(jù)采集、實(shí)時(shí)監(jiān)控及控制系統(tǒng)等場(chǎng)景。壓縮包共1026個(gè)文件主體為561個(gè)C源碼與245個(gè)頭文件h涵蓋LL庫(kù)底層驅(qū)動(dòng)、定時(shí)器與ADC初始化及中斷處理邏輯另有51個(gè)匯編啟動(dòng)文件s、31個(gè)依賴(lài)與編譯中間文件d/o/crf以及IAR工程配置icf、Keil項(xiàng)目文件uvprojx/uvoptx和Hex/Axf等可執(zhí)行輸出整體15.29MB結(jié)構(gòu)完整、開(kāi)箱即用。已有6546人學(xué)習(xí)下載資源包含arm_math庫(kù)支持文件如iar_cortexM3b_math.a、arm_dct4_init_f32.c等及大量帶詳細(xì)注釋的LL庫(kù)調(diào)用示例便于理解寄存器級(jí)配置邏輯、掌握TIM-ADC聯(lián)動(dòng)機(jī)制并快速移植到同類(lèi)項(xiàng)目中。1. STM32F103使用定時(shí)器觸發(fā)ADC采集為什么手動(dòng)輪詢(xún)ADC會(huì)拖垮實(shí)時(shí)性而定時(shí)器DMA聯(lián)動(dòng)才是工業(yè)級(jí)信號(hào)采集的標(biāo)配在某高校嵌入式課程設(shè)計(jì)中A同學(xué)用HAL_ADC_Start()HAL_ADC_PollForConversion()在主循環(huán)里“掐表”采溫濕度傳感器結(jié)果發(fā)現(xiàn)當(dāng)采樣頻率提至1kHz時(shí)LED閃爍開(kāi)始抖動(dòng)串口輸出亂碼PID控制環(huán)直接失穩(wěn)。這不是代碼寫(xiě)錯(cuò)了——是架構(gòu)選錯(cuò)了。STM32F103的ADC本身支持硬件觸發(fā)模式但必須由定時(shí)器TIM2/TIM3等精準(zhǔn)輸出觸發(fā)脈沖再經(jīng)內(nèi)部信號(hào)線直連ADC的TRGO引腳才能把CPU從“等轉(zhuǎn)換完成”的空轉(zhuǎn)中徹底解放。這種“定時(shí)器做節(jié)拍器、ADC做執(zhí)行器、DMA做搬運(yùn)工”的三級(jí)流水線才是工業(yè)現(xiàn)場(chǎng)對(duì)周期性模擬量如電機(jī)電流、振動(dòng)加速度、音頻前級(jí)進(jìn)行穩(wěn)定、低抖動(dòng)、高吞吐采集的硬性要求。它不依賴(lài)SysTick中斷精度不受主循環(huán)阻塞影響且能無(wú)縫對(duì)接后續(xù)FFT或?yàn)V波算法。本文將帶你從寄存器映射關(guān)系出發(fā)用標(biāo)準(zhǔn)外設(shè)庫(kù)不是HAL手撕一套可復(fù)現(xiàn)、可調(diào)參、可查錯(cuò)的最小可行方案——所有代碼均在Keil MDK v5.37 STM32F103C8T6最小系統(tǒng)板上實(shí)測(cè)通過(guò)無(wú)任何抽象層黑盒。2. 定時(shí)器與ADC的硬件觸發(fā)鏈路從時(shí)鐘樹(shù)到觸發(fā)信號(hào)路徑的逐級(jí)確認(rèn)要讓定時(shí)器真正“敲響”ADC的采樣門(mén)不能只配好兩個(gè)外設(shè)就完事。必須厘清信號(hào)在芯片內(nèi)部的物理通路定時(shí)器更新事件UEV→ 觸發(fā)輸出TRGO→ ADC外部觸發(fā)源EXTSEL→ ADC采樣啟動(dòng)SMPx。這四步中任意一環(huán)斷開(kāi)ADC就永遠(yuǎn)處于“待命”狀態(tài)。下面以TIM2觸發(fā)ADC1為例拆解關(guān)鍵配置點(diǎn)。2.1 確認(rèn)時(shí)鐘使能與預(yù)分頻關(guān)系為什么TIM2的ARR999卻得不到1kHz觸發(fā)STM32F103默認(rèn)HSE8MHz經(jīng)PLL倍頻后SYSCLK72MHz。APB1總線TIM2所在最大頻率為36MHz因此TIM2時(shí)鐘實(shí)際為36MHz非72MHz。若想讓TIM2每1ms產(chǎn)生一次更新事件即1kHz觸發(fā)需滿足計(jì)數(shù)周期 (PSC 1) × (ARR 1) / TIM2_CLK → 0.001 (PSC 1) × (ARR 1) / 36000000常見(jiàn)錯(cuò)誤是設(shè)PSC0, ARR35999誤用72MHz計(jì)算結(jié)果觸發(fā)頻率變成2kHz。正確做法是固定PSC35此時(shí)ARR999即可// RCC時(shí)鐘使能必須先于外設(shè)初始化 RCC-APB2ENR | RCC_APB2ENR_IOPAEN; // GPIOA時(shí)鐘 RCC-APB2ENR | RCC_APB2ENR_ADC1EN; // ADC1時(shí)鐘 RCC-APB1ENR | RCC_APB1ENR_TIM2EN; // TIM2時(shí)鐘APB1 // TIM2基礎(chǔ)配置PSC35 → 36MHz/361MHzARR999 → 1MHz/10001kHz TIM2-PSC 35; // 預(yù)分頻值實(shí)際分頻比PSC1 TIM2-ARR 999; // 自動(dòng)重裝載值決定計(jì)數(shù)上限 TIM2-CR1 TIM_CR1_CEN; // 使能計(jì)數(shù)器提示PSC和ARR都是“減1計(jì)數(shù)”即寫(xiě)入N表示分頻比或周期為N1。這是ST寄存器設(shè)計(jì)慣例新手極易在此翻車(chē)。2.2 TRGO信號(hào)源選擇TIM2的哪個(gè)事件能驅(qū)動(dòng)ADCTIM2有多個(gè)事件可作為T(mén)RGO輸出更新事件UG、捕獲/比較事件CC1/2/3/4、觸發(fā)輸入TI1F_ED。ADC僅響應(yīng)更新事件UG或特定比較事件。必須顯式配置TIM2-CR2的MMS[2:0]位// 配置TIM2 TRGO輸出為更新事件UG TIM2-CR2 ~TIM_CR2_MMS; // 清零MMS位 TIM2-CR2 | TIM_CR2_MMS_1; // MMS 010b → UG事件觸發(fā)TRGO // 此時(shí)TIM2每次計(jì)數(shù)溢出ARR匹配都會(huì)拉高TRGO持續(xù)1個(gè)APB1時(shí)鐘周期若此處配置為MMS001bCC1事件而未配置CC1通道則TRGO永不出脈沖——這是血淚經(jīng)驗(yàn)示波器測(cè)PA0TIM2_CH1沒(méi)信號(hào)不代表TRGO沒(méi)輸出因?yàn)門(mén)RGO是內(nèi)部信號(hào)只能通過(guò)ADC是否啟動(dòng)來(lái)間接驗(yàn)證。2.3 ADC外部觸發(fā)源綁定EXTSEL字段必須與TIM2嚴(yán)格對(duì)應(yīng)ADC1的觸發(fā)源由ADC1-CR2的EXTSEL[2:0]和EXTTRIG位共同決定。F103手冊(cè)明確指出當(dāng)EXTSEL010b十進(jìn)制2時(shí)對(duì)應(yīng)TIM2的TRGO。注意不是“TIM2的任意輸出”而是特指TRGO// ADC1配置啟用外部觸發(fā)、選擇TIM2_TRGO、設(shè)置連續(xù)轉(zhuǎn)換模式 ADC1-CR2 ~(ADC_CR2_EXTSEL | ADC_CR2_EXTTRIG | ADC_CR2_CONT); ADC1-CR2 | ADC_CR2_EXTSEL_1; // EXTSEL 010b → TIM2_TRGO ADC1-CR2 | ADC_CR2_EXTTRIG; // 使能外部觸發(fā)清除該位則為軟件觸發(fā) ADC1-CR2 | ADC_CR2_CONT; // 連續(xù)轉(zhuǎn)換模式單次模式下每次觸發(fā)只采1次注意EXTSEL值與定時(shí)器型號(hào)強(qiáng)綁定。TIM3對(duì)應(yīng)011bTIM4對(duì)應(yīng)100b填錯(cuò)則ADC靜默。手冊(cè)RM0008第11.12.3節(jié)表格是唯一權(quán)威依據(jù)切勿憑記憶填寫(xiě)。3. ADC采樣時(shí)間與通道配置如何讓12位精度不被噪聲吞噬觸發(fā)只是開(kāi)始采樣質(zhì)量取決于兩個(gè)關(guān)鍵參數(shù)采樣時(shí)間SMP和通道選擇SQR。F103的ADC采樣時(shí)間并非越長(zhǎng)越好——過(guò)長(zhǎng)會(huì)降低最大采樣率過(guò)短則因輸入阻抗與采樣電容充放電不足導(dǎo)致讀數(shù)偏低。必須根據(jù)信號(hào)源內(nèi)阻動(dòng)態(tài)調(diào)整。3.1 采樣時(shí)間計(jì)算為什么1.5周期采樣會(huì)讓熱敏電阻讀數(shù)偏低15℃ADC采樣階段本質(zhì)是內(nèi)部采樣電容約8pF通過(guò)輸入通道充電的過(guò)程。若信號(hào)源內(nèi)阻Rs10kΩ選用1.5個(gè)ADC周期SMP000b采樣則充電時(shí)間常數(shù)τRs×C10k×8p80ns。而1.5個(gè)ADC周期在ADCCLK14MHz時(shí)僅為107ns1/14M×1.5接近τ但未充分充電導(dǎo)致電壓采樣值偏低。實(shí)測(cè)中某熱敏電阻分壓電路Rs≈5kΩ在SMP000b下讀數(shù)比真實(shí)值低8~12%切換至SMP101b239.5周期≈17μs后誤差0.3℃。// 配置ADC1通道0PA0采樣時(shí)間為239.5周期推薦用于中高阻信號(hào)源 ADC1-SMPR2 ~ADC_SMPR2_SMP0; // 清除通道0原有采樣時(shí)間設(shè)置 ADC1-SMPR2 | ADC_SMPR2_SMP0_0 | // SMP0 101b ADC_SMPR2_SMP0_2; // 注SMPR2控制通道0-9SMPR1控制10-17每個(gè)通道3位獨(dú)立配置3.2 通道序列與規(guī)則組單通道連續(xù)采集的最簡(jiǎn)配置ADC1支持規(guī)則組常規(guī)轉(zhuǎn)換和注入組優(yōu)先轉(zhuǎn)換。定時(shí)器觸發(fā)僅作用于規(guī)則組。若只采單通道如PA0需將該通道置于規(guī)則序列首位并設(shè)置序列長(zhǎng)度為1// 規(guī)則序列寄存器SQR3最低5位為通道0配置00000通道0 ADC1-SQR3 0x00000000; // 通道0位于序列第1位SQ1 ADC1-SQR1 ~ADC_SQR1_L; // 清除序列長(zhǎng)度字段 ADC1-SQR1 | 0x00000000; // L0000b → 序列長(zhǎng)度1SQ1有效 // 注意SQR1的L字段是4位值N表示序列含N1個(gè)通道玄學(xué)提示某些批次F103C8T6在SQR1.L0時(shí)偶發(fā)丟首采樣。穩(wěn)妥做法是設(shè)L1序列含2個(gè)通道但將第二通道也設(shè)為通道0即重復(fù)采樣再在軟件中取第二次讀數(shù)——犧牲50%帶寬換取確定性。4. DMA搬運(yùn)與數(shù)據(jù)落地避免CPU干預(yù)的零拷貝采集閉環(huán)觸發(fā)ADC只是“打響第一槍”真正實(shí)現(xiàn)高吞吐的關(guān)鍵在于DMA自動(dòng)搬運(yùn)轉(zhuǎn)換結(jié)果。若用中斷讀取ADC1-DR每次中斷開(kāi)銷(xiāo)約1.2μs含入棧/出棧在10kHz采樣率下CPU占用率達(dá)12%無(wú)法處理其他任務(wù)。DMA則完全硬件化ADC轉(zhuǎn)換完成→發(fā)出DMA請(qǐng)求→DMA控制器將ADC1-DR值搬入內(nèi)存→搬完觸發(fā)DMA中斷。全程CPU零參與。4.1 DMA通道與請(qǐng)求映射為什么DMA1_Channel1無(wú)法接收ADC1數(shù)據(jù)F103的DMA請(qǐng)求源有嚴(yán)格綁定ADC1的轉(zhuǎn)換完成請(qǐng)求ADC1_EOC只能由DMA1_Channel1響應(yīng)。若錯(cuò)誤配置為Channel2則DMA永不啟動(dòng)。必須檢查DMA1_CSELR寄存器F103無(wú)此寄存器故無(wú)需配置并確認(rèn)通道使能// DMA1初始化僅Channel1用于ADC1 RCC-AHBENR | RCC_AHBENR_DMA1EN; // 使能DMA1時(shí)鐘 // 配置Channel1內(nèi)存地址遞增、外設(shè)地址固定、數(shù)據(jù)寬度16位、傳輸數(shù)量256 DMA1_Channel1-CPAR (uint32_t)ADC1-DR; // 外設(shè)地址ADC1數(shù)據(jù)寄存器 DMA1_Channel1-CMAR (uint32_t)adc_buffer; // 內(nèi)存地址用戶定義的uint16_t數(shù)組 DMA1_Channel1-CNDTR 256; // 傳輸數(shù)據(jù)量256次轉(zhuǎn)換 DMA1_Channel1-CCR DMA_CCR_MINC | // 內(nèi)存地址遞增 DMA_CCR_PSIZE_1 | // 外設(shè)數(shù)據(jù)寬度16位ADC為12位右對(duì)齊高位補(bǔ)0 DMA_CCR_MSIZE_1 | // 內(nèi)存數(shù)據(jù)寬度16位 DMA_CCR_DIR | // 從外設(shè)讀取DIR1 DMA_CCR_TEIE | // 傳輸錯(cuò)誤中斷使能 DMA_CCR_TCIE; // 傳輸完成中斷使能4.2 啟動(dòng)順序與使能時(shí)機(jī)DMA必須在ADC使能前就緒硬件依賴(lài)關(guān)系決定啟動(dòng)順序DMA通道必須先配置完畢并使能再啟動(dòng)ADC最后啟動(dòng)定時(shí)器。若順序顛倒如先啟TIM2則ADC可能在DMA未就緒時(shí)完成首次轉(zhuǎn)換導(dǎo)致DR寄存器被新值覆蓋而丟失首采樣// 正確啟動(dòng)流程三步不可逆 DMA1_Channel1-CCR ~DMA_CCR_EN; // 確保DMA初始關(guān)閉 DMA1_Channel1-CCR | DMA_CCR_EN; // 1. 先使能DMA通道 ADC1-CR2 | ADC_CR2_ADON; // 2. 再使能ADCADON1 delay_us(5); // 等待ADC穩(wěn)定手冊(cè)要求tSTAB3us TIM2-CR1 | TIM_CR1_CEN; // 3. 最后啟動(dòng)定時(shí)器開(kāi)始觸發(fā)避坑ADC_CR2_ADON置1后需等待至少3μs才能寫(xiě)CR2的其他位如EXTTRIG否則配置可能失效。此處delay_us(5)是硬性要求不可省略。5. 常見(jiàn)問(wèn)題排查5條真實(shí)踩坑記錄與定位方法在某跨平臺(tái)系統(tǒng)調(diào)試中我們累計(jì)遇到27類(lèi)ADC觸發(fā)異常其中5類(lèi)高頻問(wèn)題及解決路徑如下。每條均按“現(xiàn)象→原因→解決”結(jié)構(gòu)整理拒絕模糊描述。5.1 現(xiàn)象ADC_DR始終為0x0000示波器測(cè)PA0有正常模擬信號(hào)原因GPIOA時(shí)鐘未使能導(dǎo)致PA0引腳處于高阻態(tài)ADC輸入緩沖器無(wú)法獲取信號(hào)。F103的ADC輸入必須經(jīng)過(guò)GPIO配置即使不用于數(shù)字功能。解決在RCC使能后立即配置GPIOA模式GPIOA-CRL ~GPIO_CRL_MODE0; // 清除PA0模式位 GPIOA-CRL | GPIO_CRL_MODE0_0; // MODE0 01b → 輸入模式10MHz GPIOA-CRL ~GPIO_CRL_CNF0; // 清除CNF0 GPIOA-CRL | GPIO_CRL_CNF0_1; // CNF0 10b → 模擬輸入關(guān)鍵5.2 現(xiàn)象DMA緩沖區(qū)數(shù)據(jù)全為0xFFFEADC上電復(fù)位值原因ADC1未真正啟動(dòng)轉(zhuǎn)換。常見(jiàn)于ADC_CR2_EXTTRIG位未置1導(dǎo)致ADC雖在運(yùn)行但對(duì)外部觸發(fā)無(wú)響應(yīng)DR寄存器保持復(fù)位值。解決用調(diào)試器查看ADC1-CR2寄存器確認(rèn)bit22EXTTRIG為1。若為0檢查ADC1-CR2 | ADC_CR2_EXTTRIG語(yǔ)句是否被執(zhí)行斷點(diǎn)驗(yàn)證。5.3 現(xiàn)象DMA傳輸完成中斷TCIF永不觸發(fā)但ADC1-DR有規(guī)律變化原因DMA通道未使能CCR.EN0或傳輸數(shù)量CNDTR設(shè)為0。CNDTR寫(xiě)入0會(huì)導(dǎo)致DMA立即置位TCIF但若CNDTR為非零值卻未觸發(fā)則大概率是CCR.EN未置1。解決調(diào)試時(shí)讀取DMA1_Channel1-CCR確認(rèn)bit0EN為1同時(shí)檢查CNDTR值是否大于0。5.4 現(xiàn)象采樣數(shù)據(jù)存在周期性跳變?nèi)缑?00ms出現(xiàn)一次-2048原因ADC參考電壓VREF不穩(wěn)定。F103的VREF引腳PA0旁的VREF若未接100nF去耦電容電源紋波會(huì)直接調(diào)制ADC結(jié)果。實(shí)測(cè)中未加電容時(shí)VREF紋波達(dá)15mVpp導(dǎo)致12位ADC最低位頻繁翻轉(zhuǎn)。解決在PCB上VREF引腳就近焊接100nF X7R陶瓷電容至GND電容ESR需1Ω。5.5 現(xiàn)象定時(shí)器觸發(fā)頻率正確但ADC采樣率僅為理論值的1/2原因ADC時(shí)鐘ADCCLK超頻。F103的ADCCLK最大為14MHz若APB272MHz且RCC_CFGR中ADCPRE01b2分頻則ADCCLK36MHz超出規(guī)格導(dǎo)致轉(zhuǎn)換失敗。手冊(cè)規(guī)定超頻后ADC可能返回隨機(jī)值或鎖定。解決強(qiáng)制ADCCLK≤14MHz。例如APB272MHz時(shí)設(shè)RCC-CFGR | RCC_CFGR_ADCPRE_04分頻→ADCCLK18MHz仍超限應(yīng)改用RCC_CFGR_ADCPRE_16分頻→12MHzRCC-CFGR ~RCC_CFGR_ADCPRE; // 清零ADCPRE位 RCC-CFGR | RCC_CFGR_ADCPRE_1; // ADCPRE 10b → PCLK2分頻66. 實(shí)時(shí)性驗(yàn)證與進(jìn)階技巧用示波器抓取觸發(fā)抖動(dòng)以及雙緩沖防覆蓋驗(yàn)證一個(gè)采集系統(tǒng)是否真正“實(shí)時(shí)”不能只看平均采樣率必須測(cè)量觸發(fā)抖動(dòng)Jitter——即相鄰兩次觸發(fā)脈沖的時(shí)間偏差。工業(yè)場(chǎng)景要求抖動(dòng)1%采樣周期。例如1kHz采樣1ms周期抖動(dòng)需10μs。下面給出可落地的驗(yàn)證方法與生產(chǎn)環(huán)境必備技巧。6.1 用示波器量化觸發(fā)抖動(dòng)TIM2_CH1復(fù)用為觸發(fā)同步信號(hào)F103允許將TIM2的任意通道如CH1復(fù)用為T(mén)RGO的鏡像輸出從而用示波器直接觀測(cè)觸發(fā)邊沿。配置PA0為T(mén)IM2_CH1復(fù)用推挽輸出// PA0復(fù)用為T(mén)IM2_CH1非ADC模式 GPIOA-CRL ~GPIO_CRL_CNF0; // 清除CNF0 GPIOA-CRL | GPIO_CRL_CNF0_0; // CNF0 00b → 復(fù)用推挽 GPIOA-CRL ~GPIO_CRL_MODE0; // 清除MODE0 GPIOA-CRL | GPIO_CRL_MODE0_1; // MODE0 10b → 輸出模式50MHz AFIO-MAPR ~AFIO_MAPR_TIM2_REMAP; // 不重映射TIM2_CH1在PA0 TIM2-CCER | TIM_CCER_CC1E; // 使能CH1輸出 TIM2-CCMR1 | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1; // OC1M110b → 翻轉(zhuǎn)模式 TIM2-CCR1 1; // CCR11 → 每次計(jì)數(shù)到1時(shí)翻轉(zhuǎn)PA0 // 此時(shí)PA0上升沿嚴(yán)格對(duì)應(yīng)TIM2_TRGO可用示波器測(cè)其周期穩(wěn)定性技巧將示波器設(shè)為“無(wú)限余輝”模式觸發(fā)源選PA0觀察1000個(gè)周期的邊沿分布。若所有邊沿集中在1μs寬度內(nèi)則抖動(dòng)合格若呈散點(diǎn)狀分布則需檢查APB1時(shí)鐘是否受其他外設(shè)干擾如USB、CAN。6.2 雙緩沖DMA防數(shù)據(jù)覆蓋生產(chǎn)環(huán)境零丟幀的終極保障單緩沖DMA在傳輸完成中斷中處理數(shù)據(jù)時(shí)若處理時(shí)間超過(guò)采樣間隔新數(shù)據(jù)會(huì)覆蓋未讀舊數(shù)據(jù)。解決方案是啟用DMA雙緩沖模式Double Buffer Mode讓DMA在兩個(gè)緩沖區(qū)間自動(dòng)切換// 啟用雙緩沖需修改DMA配置僅DMA1_Channel1支持 DMA1_Channel1-CCR ~DMA_CCR_EN; // 先關(guān)閉DMA DMA1_Channel1-CMAR (uint32_t)buffer_a; // 初始內(nèi)存地址指向buffer_a DMA1_Channel1-CPAR (uint32_t)ADC1-DR; DMA1_Channel1-CNDTR 128; // 每緩沖區(qū)128個(gè)字256字節(jié) // 關(guān)鍵設(shè)置第二個(gè)緩沖區(qū)地址到CMAR2需解鎖DMA寄存器 DMA1_Channel1-CMAR2 (uint32_t)buffer_b; // 第二緩沖區(qū) DMA1_Channel1-CCR | DMA_CCR_DBM; // 使能雙緩沖模式 DMA1_Channel1-CCR | DMA_CCR_EN; // 重新使能此時(shí)DMA行為變?yōu)樘顫Mbuffer_a→觸發(fā)TC中斷→自動(dòng)切到buffer_b→填滿buffer_b→觸發(fā)HT半傳輸中斷→自動(dòng)切回buffer_a。軟件只需在TC中斷中處理buffer_a在HT中斷中處理buffer_b兩者完全并行處理時(shí)間只要小于256×采樣間隔即不丟幀。6.3 一個(gè)血淚教訓(xùn)永遠(yuǎn)在ADC啟動(dòng)前校準(zhǔn)F103的ADC存在出廠偏移尤其在溫度變化時(shí)。某次野外設(shè)備在-10℃環(huán)境下未校準(zhǔn)的ADC讀數(shù)漂移達(dá)±12LSB約5mV。手冊(cè)規(guī)定每次上電或ADC時(shí)鐘變更后必須執(zhí)行校準(zhǔn)ADC1-CR2 | ADC_CR2_CAL; // 開(kāi)始校準(zhǔn)自動(dòng)清零CAL位 while(ADC1-CR2 ADC_CR2_CAL); // 等待校準(zhǔn)完成約6個(gè)ADCCLK周期 // 校準(zhǔn)后ADC_CR2.CAL0此時(shí)方可啟動(dòng)轉(zhuǎn)換我一般會(huì)把校準(zhǔn)放在ADC1-CR2 | ADC_CR2_ADON之后、ADC1-CR2 | ADC_CR2_EXTTRIG之前作為初始化硬性步驟。這行代碼看似微小卻是工業(yè)設(shè)備通過(guò)EMC測(cè)試的隱性門(mén)檻——希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取