極海APM32E030系列是工業級基礎拓展型MCU,在APM32F030性能基礎上,實現了更高主頻、更低功耗、以及更先進的模擬與通信接口。同時配置豐富的片上資源,可滿足多行業的應用升級需求,特別是成本敏感型應用??蓮V泛應用于工業控制、智能家居、儀器儀表、可穿戴設備、醫療及手持設備、小家電、照明燈等領域。
該篇文章主要介紹APM32E030系列ADC使用的一些小心得——從單通道阻塞采樣到多通道DMA掃描
APM32E030的硬件資源
APM32E030片內集成1路12-bit ADC,最高1 Msps,支持16個外部通道+2個內部通道(溫度傳感器、V<sub>),模擬輸入范圍0~V<sub>(典型3.3 V)。ADC時鐘最高14 MHz,由PCLK2分頻而來。
典型應用場景
單通道電壓監測(阻塞方式)
多通道輪詢掃描+DMA,減輕CPU負擔
片內溫度傳感器/參考電壓測量,實現溫度補償和電壓校準
寄存器/庫函數對照
整套官方SDK提供兩套接口:
寄存器版apm32e030_adc.h
LL(Low-layer)/HAL版apm32e0xx_ll_adc.h
下文示例以寄存器版為主,關鍵函數名稱與HAL版一一對應,方便遷移。
最小系統單通道阻塞采樣
目標:ADC1通道2(PA2)采可調電阻,串口每秒打印一次電壓值。
1.GPIO復用
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_ADC1 | RCM_APB2_PERIPH_GPIOA);
GPIO_Config_T t = {
.pin = GPIO_PIN_2,
.mode = GPIO_MODE_AN,
.pupd = GPIO_PUPD_NO,
.speed = GPIO_SPEED_50MHz
};
GPIO_Config(GPIOA, &t);
2.ADC時鐘與分辨率
RCM_ConfigADCCLK(RCM_ADCCLK_PCLK2_DIV6); // 72 MHz / 6 = 12 MHz
ADC_Reset();
ADC_Config_T adc = {
.resolution = ADC_RESOLUTION_12B,
.convMode = ADC_CONVERSION_SINGLE,
.dataAlign = ADC_DATA_ALIGN_RIGHT,
.scanDir = ADC_SCAN_DIR_UPWARD,
.extTrigConv = ADC_EXT_TRIG_CONV_T0,
.extTrigEdge = ADC_EXT_TRIG_EDGE_NONE
};
ADC_Config(&adc);
3.通道與采樣時間
ADC_ConfigChannel(ADC_CHANNEL_2, ADC_SAMPLE_TIME_239_5); // 最長采樣提高精度
4.校準&啟動
ADC_ReadCalibrationFactor(); // 加載出廠校準值
ADC_Enable();
while(!ADC_ReadStatusFlag(ADC_FLAG_ADRDY));
5.阻塞讀取封裝
uint16_t ADC_GetSingle(void)
{
ADC_StartConversion();
while(!ADC_ReadStatusFlag(ADC_FLAG_CC));
return ADC_ReadConversionValue();
}
6.主循環
float v = ADC_GetSingle() * 3.3f / 4096;
printf("V=%.3f\r\n", v);
至此,單通道阻塞采樣完成
五、中斷方式避免阻塞
使能轉換完成中斷,采樣完成后在ISR中讀取結果。
ADC_EnableInterrupt(ADC_INT_CC);
NVIC_EnableIRQRequest(ADC1_IRQn, 2);
ISR:
void ADC1_IRQHandler(void)
{
if (ADC_ReadIntFlag(ADC_INT_CC))
{
adcValue = ADC_ReadConversionValue();
ADC_ClearIntFlag(ADC_INT_CC);
}
}
主循環無需死等,可并行處理其他任務
六、多通道+DMA掃描
目標:一次啟動,ADC連續掃描CH0~CH5,DMA將結果寫入RAM數組。
1.定義緩沖區
#define ADC_CH_SIZE 6
uint16_t adcBuf[ADC_CH_SIZE];
2.DMA配置
RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_DMA);
DMA_Config_T dma = {
.peripheralBase = (uint32_t)&ADC->DATA,
.memoryBase = (uint32_t)adcBuf,
.direction = DMA_DIRECTION_PERIPH_TO_MEMORY,
.bufferSize = ADC_CH_SIZE,
.peripheralInc = DMA_PERIPHERAL_INC_DISABLE,
.memoryInc = DMA_MEMORY_INC_ENABLE,
.peripheralDataSize = DMA_PERIPHERAL_DATA_SIZE_HALFWORD,
.memoryDataSize = DMA_MEMORY_DATA_SIZE_HALFWORD,
.mode = DMA_MODE_CIRCULAR,
.priority = DMA_PRIORITY_HIGH
};
DMA_Config(DMA1_Channel1, &dma);
DMA_Enable(DMA1_Channel1);
3.ADC連續掃描模式
adc.convMode = ADC_CONVERSION_CONTINUOUS;
adc.scanDir = ADC_SCAN_DIR_UPWARD;
ADC_Config(&adc);
/* 分別配置 6 個通道,順序必須與硬件布線對應 */
ADC_ConfigChannel(ADC_CHANNEL_0, ADC_SAMPLE_TIME_71_5);
...
ADC_ConfigChannel(ADC_CHANNEL_5, ADC_SAMPLE_TIME_71_5);
4.啟動
ADC_EnableDMA();
ADC_ReadCalibrationFactor();
ADC_Enable();
ADC_StartConversion();
DMA以循環模式自動搬運數據,CPU僅需讀取adcBuf[]。
七、內部溫度傳感器&<sub>使用技巧
通道號:溫度=CH16,V&<sub>=CH17
采樣時間≥239.5 cycles,確保穩定
溫度計算公式(典型):
T=((V25-VTS)/Avg_Slope)+25
V25≈1.34 V,Avg_Slope≈4.3 mV/°C(以數據手冊為準)
實測發現V&<sub>讀數約1.2 V,若出現偏大/偏小,可通過校準寄存器VREFINT_CAL進行修正
