在我們的應用項目中需要采集一些模擬量,這些量使用MCU自帶的ADC就可以滿足要求。在NUCLEO-F412ZG實驗板上的STM32F412ZG有一個16通道的ADC,我們試驗用它采集幾個數據。
在NUCLEO-F412ZG實驗板上,ADC1的第10通道(PC0)和第13通道(PC3)分別引到了CN9-3和CN9-5上。如下圖紅框所示:
我們利用這兩個通道采集信號,一個定義為24VDC電源的檢測,一個定義為5VDC電源的檢測。同時采集MCU集成的內部溫度傳感器采集和內部參考電壓采集。具體通道選擇如下:
為了方便操作,我們在STM32CubeMX中進行ADC1的配置,打開“ADC1 Configuration”界面,選擇“GPIO Settings”標簽,配置對應的GPIO如下:
由於我們使用DMA來進行ADC1的采集,所以我們打開DMA標簽進行DMA配置:
配置完成后,我們生成項目源碼,發現配置文件如下:
/* ADC1 init function */
static void MX_ADC1_Init(void)
{
ADC_ChannelConfTypeDef sConfig;
/**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.ScanConvMode = DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1;
hadc1.Init.DMAContinuousRequests = DISABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = ADC_CHANNEL_10;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
}
在這段初始化代碼中,通過HAL_ADC_Init函數來初始化,在HAL_ADC_Init函數中有調用了HAL_ADC_MspInit函數。這個函數需要我們自己編寫,然后共系統回調。其內容主要是對通道10和通道13的GPIO引腳進行初始化配置。
配置完成后我們便寫數據處理相關的函數,比如數據平滑處理、量程轉化等。其實我們2個通道的采集信號是一樣的,都是采用5V的信號分要產生。由於在NUCLEO-F412ZG實驗板上ADC的參考電壓接到電源,也就是3.3VDC所以輸入信號不能超多3.3VDC。我們使用電阻分壓將信號轉為2.5VDC然后采集。完成后運行調試:
最后來看一看采集到的結果,我們將通道10的物理量程設為24,通道13的物理量程設為5,加上MCU內核溫度和內核參考電壓,共4個信號:
由上圖我們可以看到STM32F412ZG自帶的ADC采集精度還是非常高的,在大多數情況下已經足夠了。