STM32_庫函式學習筆記_ADC_01
STM32庫函式ADC學習筆記
(學習材料為正點原子ALIENTEK TM32F1精英版光碟內容)
常用ADC庫函式
1、ADC初始化函式
包含兩個引數:ADCx、ADC_InitStruct
void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct)
ADCx 為目標ADC控制器編號:
#define IS_ADC_ALL_PERIPH(PERIPH) (((PERIPH) == ADC1) || \
((PERIPH) == ADC2) || \
((PERIPH) == ADC3))
ADC_InitStruct 為初始化結構體:
typedef struct
{
uint32_t ADC_Mode;
FunctionalState ADC_ScanConvMode;
FunctionalState ADC_ContinuousConvMode;
uint32_t ADC_ExternalTrigConv;
uint32_t ADC_DataAlign;
uint8_t ADC_NbrOfChannel;
}ADC_InitTypeDef;
ADC_Mode:ADC模式:配置ADC_CR1暫存器的位[19:16]:DUALMODE[3:0]位。
DUALMOD[3:0]:雙模式選擇 (Dual mode selection)
軟體使用這些位選擇操作模式。
0000:獨立模式(常用)
0001:混合的同步規則+注入同步模式
0010:混合的同步規則+交替觸發模式
0011:混合同步注入+快速交叉模式
0100:混合同步注入+慢速交叉模式
0101:注入同步模式
0110:規則同步模式
0111:快速交叉模式
1000:慢速交叉模式
1001:交替觸發模式
注: 在ADC2和ADC3中這些位為保留位
在雙模式中,改變通道的配置會產生一個重新開始的條件,這將導致同步丟失。建議在進行任
何配置改變前關閉雙模式。
ADC_ScanConvMode:是否使用掃描模式。ADC_CR1位8:SCAN位。
SCAN:掃描模式 (Scan mode)
該位由軟體設定和清除,用於開啟或關閉掃描模式。在掃描模式中,轉換由ADC_SQRx或
ADC_JSQRx暫存器選中的通道。
0:關閉掃描模式;
1:使用掃描模式。
注:如果分別設定了EOCIE或JEOCIE位,只在最後一個通道轉換完畢後才會產生EOC或
JEOC中斷。
ADC_ContinuousConvMode:單次轉換OR連續轉換:ADC_CR2的位1:CONT位。
CONT:連續轉換 (Continuous conversion)
該位由軟體設定和清除。如果設定了此位,則轉換將連續進行直到該位被清除。
0:單次轉換模式;
1:連續轉換模式。
ADC_ExternalTrigConv:觸發方式:ADC_CR2的位[19:17] :EXTSEL[2:0]位。
EXTSEL[2:0]:選擇啟動規則通道組轉換的外部事件 (External event select for regular group)
這些位選擇用於啟動規則通道組轉換的外部事件
ADC1和ADC2的觸發配置如下:
000:定時器1的CC1事件
100:定時器3的TRGO事件
001:定時器1的CC2事件
101:定時器4的CC4事件
110:EXTI線11/ TIM8_TRGO事件,僅大容量產
品具有TIM8_TRGO功能
010:定時器1的CC3事件
011:定時器2的CC2事件
111: SWSTART(軟體觸發)
ADC3的觸發配置如下:
000:定時器3的CC1事件
100:定時器8的TRGO事件
001:定時器2的CC3事件
101:定時器5的CC1事件
010:定時器1的CC3事件
110:定時器5的CC3事件
011:定時器8的CC1事件
111:SWSTART(軟體觸發)
ADC_DataAlign:對齊方式:左對齊還是右對齊:ADC_CR2的位11:ALIGN位。
ALIGN:資料對齊 (Data alignment)
該位由軟體設定和清除。
0:右對齊;
1:左對齊。
ADC_NbrOfChannel:規則通道序列長度:ADC_SQR1的位[23:20]: L[3:0]。
L[3:0]:規則通道序列長度 (Regular channel sequence length)
這些位由軟體定義在規則通道轉換序列中的通道數目。
0000: 1個轉換
0001: 2個轉換
……
1111: 16個轉換
2、ADC使能函式
void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState)
NewState取值:
#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE))
3、ADC使能軟體轉換函式
void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState)
4、ADC規則通道配置函式,包含三個引數:ADCx、ADC_Channel、Rank、ADC_SampleTime
void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime)
ADC_Channel為目標ADC通道編號:
#define IS_ADC_CHANNEL(CHANNEL) (((CHANNEL) == ADC_Channel_0) || ((CHANNEL) == ADC_Channel_1) || \
((CHANNEL) == ADC_Channel_2) || ((CHANNEL) == ADC_Channel_3) || \
((CHANNEL) == ADC_Channel_4) || ((CHANNEL) == ADC_Channel_5) || \
((CHANNEL) == ADC_Channel_6) || ((CHANNEL) == ADC_Channel_7) || \
((CHANNEL) == ADC_Channel_8) || ((CHANNEL) == ADC_Channel_9) || \
((CHANNEL) == ADC_Channel_10) || ((CHANNEL) == ADC_Channel_11) || \
((CHANNEL) == ADC_Channel_12) || ((CHANNEL) == ADC_Channel_13) || \
((CHANNEL) == ADC_Channel_14) || ((CHANNEL) == ADC_Channel_15) || \
((CHANNEL) == ADC_Channel_16) || ((CHANNEL) == ADC_Channel_17))
STM32F10x 最多支援18個ADC通道(外部16個+內部2個)。其中144角的晶片因為帶PF腳,所以支援21個外部通道。
ADC通道和引腳對應關係如圖:
Rank 為該通道在順序規則轉換的隊伍中的序號,最多16位:
#define IS_ADC_REGULAR_RANK(RANK) (((RANK) >= 0x1) && ((RANK) <= 0x10))
ADC_SampleTime 為可程式設計通道取樣時間
#define IS_ADC_SAMPLE_TIME(TIME) (((TIME) == ADC_SampleTime_1Cycles5) || \
((TIME) == ADC_SampleTime_7Cycles5) || \
((TIME) == ADC_SampleTime_13Cycles5) || \
((TIME) == ADC_SampleTime_28Cycles5) || \
((TIME) == ADC_SampleTime_41Cycles5) || \
((TIME) == ADC_SampleTime_55Cycles5) || \
((TIME) == ADC_SampleTime_71Cycles5) || \
((TIME) == ADC_SampleTime_239Cycles5))
ADC使用若干個ADC_CLK週期對輸入電壓取樣,取樣週期數目可以通過ADC取樣時間暫存器ADC_SMPR1和ADC_SMPR2中的SMPx[2:0]位更改。
SMPx[2:0]:選擇通道x的取樣時間 (Channel x Sample time selection)
這些位用於獨立地選擇每個通道的取樣時間。在取樣週期中通道選擇位必須保持不變。
000: 1.5週期
100: 41.5週期
001: 7.5週期
101: 55.5週期
010: 13.5週期
110: 71.5週期
011: 28.5週期
111: 239.5週期
注: ADC1的模擬輸入通道16和通道17在晶片內部分別連到了溫度感測器和VREFINT。
ADC2的模擬輸入通道16和通道17在晶片內部連到了Vss。
ADC3模擬輸入通道14、 15、 16、 17與Vss相連,ADC3模擬輸入通道9與Vss相連。
總轉換時間T_CONV = 取樣時間 + 12.5個週期
例如:
當ADC_CLK=14MHz,取樣時間為1.5週期
T_CONV = 1.5 + 12.5 = 14週期 = 1μs
5、ADC獲取轉換結果函式
uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx)
實驗:ADC1的通道1(PA1)進行單次轉化
1、開啟PA口時鐘和ADC1時鐘,設定PA1為模擬輸入
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1,ENABLE); //使能時鐘
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //設定模擬輸入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
2、復位ADC1,同時設定ADC1分頻因子
ADC_DeInit(ADC1); //復位
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //72M/6=12M,ADC最大采樣頻率不超過14M
3、初始化ADC1引數,設定ADC1的工作模式以及規則序列的相關資訊
ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //獨立模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //單通道模式
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //單次轉換模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //軟體觸發(非外部觸發)
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //資料右對齊
ADC_InitStructure.ADC_NbrOfChannel = 1; //順序進行規則轉換通道數為1
ADC_Init(ADC1, &ADC_InitStructure); //初始化
4、使能ADC並校準
ADC_Cmd(ADC1, ENABLE); //使能
ADC_ResetCalibration(ADC1); //使能復位校準
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1); //開啟AD校準
while(ADC_GetCalibrationStatus(ADC1));
原子編寫ADC初始化函式void Adc_Init(void)
完成步驟1-4。
5、配置規則通道引數
ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 ); //ADC1,通道數ch,序列1,取樣週期239.5週期
6、開啟軟體轉換,等待轉換完成
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));
7、讀取ADC值
return ADC_GetConversionValue(ADC1); //返回ADC結果
原子編寫函式u16 Get_Adc(u8 ch)
完成步驟5-7。
同時函式u16 Get_Adc_Average(u8 ch,u8 times)
可以取樣times
次,取平均值。
u16 Get_Adc_Average(u8 ch,u8 times)
{
u32 temp_val=0;
u8 t;
for(t=0;t<times;t++)
{
temp_val+=Get_Adc(ch);
delay_ms(5);
}
return temp_val/times;
}
8、換算電壓值
u16 adcx;
adcx=Get_Adc_Average(ADC_Channel_1,10);
temp=(float)adcx*(3.3/4096); //12位ADC,參考電壓3.3V
adcx=temp; //整數部分
temp-=adcx;
temp*=1000; //小數部分,用於LCD數顯