平台:STM32F103C8T6最小系統闆
STM32CUBEMX-V6.1.2-1.8.4版本的F1固件包+MDK5.31
目錄
單次轉換模式
連續轉換+DMA傳輸模式
遇到的問題
單次轉換模式
以配置ADC1的IN0,IN1這兩通道為例
1:勾選IN0,IN1
2:資料選擇右對齊 3:選擇是否使能規則轉換因為我們采用單次轉換模式,是以此選項可以先失能掉。
4:其它保持預設,完成時鐘等其它配置後,生成代碼
5:添加如下函數
6:通過調用上述函數傳入ADC采集通道,就可以擷取相應通道的ADC資料。/** * @brief 擷取指定通道的ADC采集值 * @param channel 要采集的ADC通道 * @retval 采集到的ADC資料 */ uint16_t adc_get(uint32_t channel) { ADC_ChannelConfTypeDef sConfig = {0}; sConfig.Channel = channel; sConfig.Rank = ADC_REGULAR_RANK_1; sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5; if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { Error_Handler(); } HAL_ADC_Start(&hadc1); HAL_ADC_PollForConversion(&hadc1,100); //等待規則組轉換完成 return (uint16_t)HAL_ADC_GetValue(&hadc1); }
連續轉換+DMA傳輸模式
以配置ADC1的IN0,IN1這兩通道為例,重複的步驟看前面
1:掃描模式和連續轉換模式都要使能
掃描模式在使能規則轉換且轉換數量大于1之後會自動使能
2:規則轉換的配置如下 3:在DAM_Setting中配置如下mode選擇Circular,這樣才會循環的去搬運資料
搬運到位址空間的Data Width設定為字,也就是32位。這樣友善後續的讀數。若設定為半字,那麼在後續讀數的時候,需要将DMA的目标緩沖區(32位的)進行拆分後再進行讀數。
4:生成代碼,在開始讀取資料之前加入如下代碼
其中,之是以要失能DMA中斷,是因為在CUBEMX配置DMA傳輸的時候會強制使能DMA Channel1 的全局中斷,如圖HAL_ADCEx_Calibration_Start(&hadc1); //執行ADC的自動校準 HAL_NVIC_DisableIRQ(DMA1_Channel1_IRQn); //失能DMA的中斷 HAL_ADC_Start_DMA(&hadc1,(uint32_t *)ad_buf,2); //設定資料緩沖區 /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ My_Pri_log_x(1,"ad_va1:%d ",ad_buf[0]); My_Pri_log_x(1,"ad_va2:%d\r\n",ad_buf[1]); HAL_Delay(500); }
但我并不需要,是以将其關閉。
資料緩沖區 ad_buf 是一個32位兩個元素的數組。
5:讀取DMA傳輸目的位址 ad_buf 的值,就可以獲得兩個ADC通道的資料。
遇到的問題
現象:
無論是單次轉換模式,還是連續轉換+DMA傳輸的模式,都會遇到一個問題,那就是通道之間會互相幹擾。即一個通道電壓的變化會微量的影響到其它通道電壓的變化。原因:
多個通道是通過模拟多路開關自動切換的,這就導緻,在切換的瞬間上一個通道的電壓值會幹擾到下一個通道,切換速度越快,影響越大,切換的時間間隔越久,影響越小解決辦法:
1:增大Sampling Time可以一定程度上減小影響
2:在單次轉換模式中,可以在轉換之間插入一定延時,也可以采用平均求值的方式
3:将通過1和通道2配置到ADC1和ADC2上面,徹底隔離,單次轉換中試過此方法,連續轉換+DMA中沒試過,有待驗證。
4:在AD通道管腳上并聯一個100nf左右的電容,沒試過,有待驗證。