u16 ADC1_AveragValue(u16 ADC_Value[N][M]) { u16 ADC1_Value[N]; u8 i = 0; u8 j = 0; u16 temp = 0; u16 ADC1_Av = 0; for (i = 0;i < N;i++) { ADC1_Value[i] = ADC_Value[i][0]; } /*冒泡排序*/ for(i=0; i<N-1; i++) { //內循環選擇要進行比較的數 for(j=0; j<N-1-i; j++) { if(ADC1_Value[j]>ADC1_Value[j+1]) { temp=ADC1_Value[j]; ADC1_Value[j]=ADC1_Value[j+1]; ADC1_Value[j+1]=temp; } } } /*去掉最大值和最小值*/ for (i = 0; i<N-2;i++) { ADC1_Av += ADC1_Value[i+1]; } /*取平均值*/ ADC1_Av = ADC1_Av/4; return ADC1_Av; }
STM32的內部自帶12位ADC,其特點如下:
(1)12位分辨率,最短時鍾周期為14個,時鍾周期可調,分別可以調整為14、20、26、41、54、68、252,因此當時鍾為14MHz時候,最快轉換時間為1us;
(2)供電電壓為2.4V到3.6V,注意stm32的最低供電電壓可以是2V,但是使用ADC時候,必須達到2.4V以上;
(3)輸入電壓范圍:0<vin< VCC
(4)最小量化單位為:LSB=Vref+/4096mV;
(5)為逐次比較型AD;
處理AD轉換的方法有兩個:一個是常用的中斷,另一個是DMA,相對來說,DMA模式下的效率要高,所以這里研究DMA下的ADC。
3、實驗目標:通過ADC1的11通道采集外部電壓,然后又DMA傳送到緩存,然后通過串口發到到PC上。
4、實驗程序:
1. 配置ADC等資源
![]()
2. 配置時鍾
![]()
3. 參數配置
![]()
點“ADC1”?
![]()
Mode: 模式為獨立模式。
Dataalignment數據對齊:右對齊
ScanConversionMode:掃描轉換模式,如果使用了一個ADC下的多個采集通道,需要選擇Enable模式,否則只會轉換設置的第一個通道。
ContinuousConversMode連續轉換模式
DiscontinuousConversionMode:不連續轉換模式
![]()
NVIC部分開啟DMA中斷,關閉中斷模式的中斷使能。
![]()
Memory:勾選此項,轉換數據將存在Memory中,並且地址自加連續存放。此功能對某個通道連續多次采樣很好用,采樣數據會自動填滿一個數組,方便軟件濾波。
Mode:選循環模式,填滿數組后自動從頭刷新。
DataWidth數據長度:如果是12位AD轉換,此處選半字。
4.程序實現
在STM32CubeMX生成好的程序基礎上。
在main設置一個uhADCxConvertedValue2的全局變量數組。類型為Uint16_t。
在main函數的初始化區后,while(1)區前,添加:
if(HAL_ADC_Start_DMA(&hadc1,(uint32_t*)&uhADCxConvertedValue2,100)!=HAL_OK)Error_Handler();
ADC1啟動,並開始連續轉換,轉換結果會放在uhADCxConvertedValue2數組中,大小是100。因為是連續轉換,所以數組中存放的是最近100次轉換結果。
5軟件濾波
濾波子函數:可以計算100個點的濾波結果。
此函數為中值平均滑動濾波,當然,滑動是ADC的DMA自動實現的。
|