stm32學習筆記 F1系列ADC
ADC:Analog-to-Digital Converter的縮寫。指模/數轉換器或者模擬/數字轉換器。是指將連續變數的模擬訊號轉換為離散的數字訊號的器件。
典型的模擬數字轉換器將模擬訊號轉換為表示一定比例電壓值的數字訊號。
12位逐次逼近型的模擬數字轉換器。
最多帶3個ADC控制器
最多支援18個通道,可最多測量16個外部和2個內部訊號源。
支援單次和連續轉換模式
轉換結束,注入轉換結束,和發生模擬看門狗事件時產生中斷。
通道0到通道n的自動掃描模式
自動校準
取樣間隔可以按通道程式設計
規則通道和注入通道均有外部觸發選項
轉換結果支援左對齊或右對齊方式儲存在16位資料暫存器
ADC轉換時間:最大轉換速率 1us。(最大轉換速度為1MHz,在ADCCLK=14M,取樣週期為1.5個ADC時鐘下得到。)
ADC供電要求:2.4V-3.6V
ADC輸入範圍:VREF- ≤ VIN ≤ VREF+
STM32通道組
①規則通道組:相當正常執行的程式。最多16個通道。
規則通道和它的轉換順序在ADC_SQRx暫存器中選擇,規則
組轉換的總數應寫入ADC_SQR1暫存器的L[3:0]中
② 注入通道組:相當於中斷。最多4個通道。
注入組和它的轉換順序在ADC_JSQR暫存器中選擇。注入組
裡轉化的總數應寫入ADC_JSQR暫存器的L[1:0]中
STM32F1的ADC的各通道可以單次,連續,掃描或者間斷模式執行。
1>單次轉換模式
單次轉換模式下,ADC只執行一次轉換。該模式既可通過設定ADC_CR2暫存器的ADON位(只
適用於規則通道)啟動也可通過外部觸發啟動(適用於規則通道或注入通道),這時CONT位為0。
一旦選擇通道的轉換完成:
● 如果一個規則通道被轉換:
─ 轉換資料被儲存在16位ADC_DR暫存器中
─ EOC(轉換結束)標誌被設定
─ 如果設定了EOCIE,則產生中斷。
● 如果一個注入通道被轉換:
─ 轉換資料被儲存在16位的ADC_DRJ1暫存器中
─ JEOC(注入轉換結束)標誌被設定
─ 如果設定了JEOCIE位,則產生中斷。
2>連續轉換模式
在連續轉換模式中,當前面ADC轉換一結束馬上就啟動另一次轉換。此模式可通過外部觸發啟
動或通過設定ADC_CR2暫存器上的ADON位啟動,此時CONT位是1。
每個轉換後:
● 如果一個規則通道被轉換:
─ 轉換資料被儲存在16位的ADC_DR暫存器中
─ EOC(轉換結束)標誌被設定
─ 如果設定了EOCIE,則產生中斷。
● 如果一個注入通道被轉換:
─ 轉換資料被儲存在16位的ADC_DRJ1暫存器中
─ JEOC(注入轉換結束)標誌被設定
─ 如果設定了JEOCIE位,則產生中斷。
3>掃描模式
此模式用來掃描一組模擬通道。
掃描模式可通過設定ADC_CR1暫存器的SCAN位來選擇。一旦這個位被設定,ADC掃描所有被
ADC_SQRX暫存器(對規則通道)或ADC_JSQR(對注入通道)選中的所有通道。在每個組的每個
通道上執行單次轉換。在每個轉換結束時,同一組的下一個通道被自動轉換。如果設定了CONT
位,轉換不會在選擇組的最後一個通道上停止,而是再次從選擇組的第一個通道繼續轉換。
如果設定了DMA位,在每次EOC後,DMA控制器把規則組通道的轉換資料傳輸到SRAM中。而
注入通道轉換的資料總是儲存在ADC_JDRx暫存器中。
ADC 中斷
規則和注入組轉換結束時能產生中斷,當模擬看門狗狀態位被設定時也能產生中斷。它們都有
獨立的中斷使能位。
注: ADC1 和 ADC2 的中斷對映在同一個中斷向量上,而 ADC3 的中斷有自己的中斷向量。
ADC_SR暫存器中有2個其他標誌,但是它們沒有相關聯的中斷:
● JSTRT(注入組通道轉換的啟動)
● STRT(規則組通道轉換的啟動)
ADC 時鐘
由時鐘控制器提供的ADCCLK時鐘和PCLK2(APB2時鐘)同步。RCC控制器為ADC時鐘提供一個
專用的可程式設計預分頻器.注:不要讓ADC時鐘超過14MHz,否則可能不準。
可程式設計的通道取樣時間
ADC使用若干個ADC_CLK週期對輸入電壓取樣,取樣週期數目可以通過ADC_SMPR1和
ADC_SMPR2暫存器中的SMP[2:0]位更改。每個通道可以分別用不同的時間取樣。
總轉換時間如下計算:
T(CONV) = 取樣時間+ 12.5個週期
例如:
當ADCCLK=14MHz,取樣時間為1.5週期
T(CONV) = 1.5 + 12.5 = 14週期 = 1μs
常用庫函式
void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);
void ADC_DeInit(ADC_TypeDef* ADCx)
void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState);
void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);
void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);
uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx);
void ADC_ResetCalibration(ADC_TypeDef* ADCx);
FlagStatus ADC_GetResetCalibrationStatus(ADC_TypeDef* ADCx);
void ADC_StartCalibration(ADC_TypeDef* ADCx);
FlagStatus ADC_GetCalibrationStatus(ADC_TypeDef* ADCx);
ADC初始化函式ADC_Init
void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);
typedef struct
{
uint32_t ADC_Mode;//ADC模式:配置ADC_CR1暫存器的位[19:16] :DUALMODE[3:0]位
FunctionalState ADC_ScanConvMode;//是否使用掃描模式。ADC_CR1位8:SCAN位
FunctionalState ADC_ContinuousConvMode; //單次轉換OR連續轉換:ADC_CR2的位1:CONT
uint32_t ADC_ExternalTrigConv; //觸發方式:ADC_CR2的位[19:17] :EXTSEL[2:0]
uint32_t ADC_DataAlign; //對齊方式:左對齊還是右對齊:ADC_CR2的位11:ALIGN
uint8_t ADC_NbrOfChannel;//規則通道序列長度:ADC_SQR1的位[23:20]: L[3:0]
}ADC_InitTypeDef;
例:
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資料右對齊
ADC_InitStructure.ADC_NbrOfChannel = 1;//順序進行規則轉換的ADC通道的數目
ADC_Init(ADC1, &ADC_InitStructure);
ADC使能函式 ADC_Cmd();
void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);
例:
ADC_Cmd(ADC1, ENABLE);//使能指定的ADC1
ADC使能軟體轉換函式 ADC_SoftwareStartConvCmd
void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx,FunctionalState NewState)
例:
ADC_SoftwareStartConvCmd(ADC1, ENABLE);//使能ADC1的軟體轉換啟動
ADC 規則通道配置函式ADC_RegularChannelConfig
void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);
例:
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5 );
ADC 獲取轉換結果函式ADC_GetConversionValue
uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx);
例:
ADC_GetConversionValue(ADC1);//獲取ADC1轉換結果
ADC 配置過程:
①開啟PA口時鐘和ADC1時鐘,設定PA1為模擬輸入。
GPIO_Init();
APB2PeriphClockCmd();
② 復位ADC1,同時設定ADC1分頻因子。
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
ADC_DeInit(ADC1);
③ 初始化ADC1引數,設定ADC1的工作模式以及規則序列的相關資訊。
void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);
④ 使能ADC並校準。
ADC_Cmd(ADC1, ENABLE);
⑤ 配置規則通道引數:
ADC_RegularChannelConfig();
⑥開啟軟體轉換:ADC_SoftwareStartConvCmd(ADC1);
⑦等待轉換完成,讀取ADC值。
ADC_GetConversionValue(ADC1);