|
STM32ADC的工作原理
模/數(shù)轉(zhuǎn)換器
STM32F10x ADC特點(diǎn)
12位逐次逼近型的模擬數(shù)字轉(zhuǎn)換器。
最多帶3個(gè)ADC控制器
最多支持18個(gè)通道,可最多測量16個(gè)外部和2個(gè)內(nèi)部信號源。
支持單次和連續(xù)轉(zhuǎn)換模式
轉(zhuǎn)換結(jié)束,注入轉(zhuǎn)換結(jié)束,和發(fā)生模擬看門狗事件時(shí)產(chǎn)生中斷。
通道0到通道n的自動(dòng)掃描模式
自動(dòng)校準(zhǔn)
采樣間隔可以按通道編程
規(guī)則通道和注入通道均有外部觸發(fā)選項(xiàng)
轉(zhuǎn)換結(jié)果支持左對齊或右對齊方式存儲在16位數(shù)據(jù)寄存器
ADC轉(zhuǎn)換時(shí)間:最大轉(zhuǎn)換速率 1us。(最大轉(zhuǎn)換速度為1MHz,在ADCCLK=14M,采樣周期為1.5個(gè)ADC時(shí)鐘下得到。)
ADC供電要求:2.4V-3.6V
ADC輸入范圍:VREF- ≤ VIN ≤ VREF+
ADC引腳
☞STM32F10x系列芯片ADC通道和引腳對應(yīng)關(guān)系
由下圖可見ADC1的通道0~通道17都有功能,而ADC2的通道16和通道17沒有作用,ADC3的通道9、通道14~通道17也沒有作用。
STM32通道組
①規(guī)則通道組:相當(dāng)正常運(yùn)行的程序。最多16個(gè)通道。
規(guī)則通道和它的轉(zhuǎn)換順序在ADC_SQRx寄存器中選擇,規(guī)則
組轉(zhuǎn)換的總數(shù)應(yīng)寫入ADC_SQR1寄存器的L[3:0]中
② 注入通道組:相當(dāng)于中斷。最多4個(gè)通道。
注入組和它的轉(zhuǎn)換順序在ADC_JSQR寄存器中選擇。注入組
里轉(zhuǎn)化的總數(shù)應(yīng)寫入ADC_JSQR寄存器的L[1:0]中
STM32F1的ADC的各通道可以單次模式執(zhí)行,連續(xù)模式執(zhí)行,掃描或者間斷模式執(zhí)行。
規(guī)則通道組
含有注入通道的規(guī)則通道組
☞單次轉(zhuǎn)化
單次轉(zhuǎn)換模式下,ADC只執(zhí)行一次轉(zhuǎn)換。該模式既可通過設(shè)置ADC_CR2寄存器的ADON位(只
適用于規(guī)則通道)啟動(dòng)也可通過外部觸發(fā)啟動(dòng)(適用于規(guī)則通道或注入通道),這時(shí)CONT位為0。
一旦選擇通道的轉(zhuǎn)換完成:
● 如果一個(gè)規(guī)則通道被轉(zhuǎn)換:
─ 轉(zhuǎn)換數(shù)據(jù)被儲存在16位ADC_DR寄存器中
─ EOC(轉(zhuǎn)換結(jié)束)標(biāo)志被設(shè)置
─ 如果設(shè)置了EOCIE,則產(chǎn)生中斷。
● 如果一個(gè)注入通道被轉(zhuǎn)換:
─ 轉(zhuǎn)換數(shù)據(jù)被儲存在16位的ADC_DRJ1寄存器中
─ JEOC(注入轉(zhuǎn)換結(jié)束)標(biāo)志被設(shè)置
─ 如果設(shè)置了JEOCIE位,則產(chǎn)生中斷。
☞連續(xù)轉(zhuǎn)換模式
在連續(xù)轉(zhuǎn)換模式中,當(dāng)前面ADC轉(zhuǎn)換一結(jié)束馬上就啟動(dòng)另一次轉(zhuǎn)換。(連續(xù)轉(zhuǎn)換會(huì)自動(dòng)開啟下一次轉(zhuǎn)換)此模式可通過外部觸發(fā)啟
動(dòng)或通過設(shè)置ADC_CR2寄存器上的ADON位啟動(dòng),此時(shí)CONT位是1。
每個(gè)轉(zhuǎn)換后:
● 如果一個(gè)規(guī)則通道被轉(zhuǎn)換:
─ 轉(zhuǎn)換數(shù)據(jù)被儲存在16位的ADC_DR寄存器中
─ EOC(轉(zhuǎn)換結(jié)束)標(biāo)志被設(shè)置
─ 如果設(shè)置了EOCIE,則產(chǎn)生中斷。
● 如果一個(gè)注入通道被轉(zhuǎn)換:
─ 轉(zhuǎn)換數(shù)據(jù)被儲存在16位的ADC_DRJ1寄存器中
─ JEOC(注入轉(zhuǎn)換結(jié)束)標(biāo)志被設(shè)置
─ 如果設(shè)置了JEOCIE位,則產(chǎn)生中斷。
☞掃描模式
此模式用來掃描一組模擬通道。掃描模式可通過設(shè)置ADC_CR1寄存器的SCAN位來選擇。一旦這個(gè)位被設(shè)置,ADC掃描所有被ADC_SQRX寄存器(對規(guī)則通道)或ADC_JSQR(對注入通道)選中的所有通道。在每個(gè)組的每個(gè)通道上執(zhí)行單次轉(zhuǎn)換。在每個(gè)轉(zhuǎn)換結(jié)束時(shí),同一組的下一個(gè)通道被自動(dòng)轉(zhuǎn)換。如果設(shè)置了CONT位,轉(zhuǎn)換不會(huì)在選擇組的最后一個(gè)通道上停止,而是再次從選擇組的第一個(gè)通道繼續(xù)轉(zhuǎn)換。如果設(shè)置了DMA位,在每次EOC后,DMA控制器把規(guī)則組通道的轉(zhuǎn)換數(shù)據(jù)傳輸?shù)絊RAM中。而注入通道轉(zhuǎn)換的數(shù)據(jù)總是存儲在ADC_JDRx寄存器中。
ADC中斷
規(guī)則和注入組轉(zhuǎn)換結(jié)束時(shí)能產(chǎn)生中斷,當(dāng)模擬看門狗狀態(tài)位被設(shè)置時(shí)也能產(chǎn)生中斷。它們都有
獨(dú)立的中斷使能位。
注: ADC1 和 ADC2 的中斷映射在同一個(gè)中斷向量上,而 ADC3 的中斷有自己的中斷向量。
ADC_SR寄存器中有2個(gè)其他標(biāo)志,但是它們沒有相關(guān)聯(lián)的中斷:
● JSTRT(注入組通道轉(zhuǎn)換的啟動(dòng))
● STRT(規(guī)則組通道轉(zhuǎn)換的啟動(dòng))
ADC 時(shí)鐘
由時(shí)鐘控制器提供的ADCCLK時(shí)鐘和PCLK2(APB2時(shí)鐘)同步。RCC控制器為ADC時(shí)鐘提供一個(gè)
專用的可編程預(yù)分頻器.注:不要讓ADC時(shí)鐘超過14MHz,否則可能不準(zhǔn)。
可編程的通道采樣時(shí)間
ADC使用若干個(gè)ADC_CLK周期對輸入電壓采樣,采樣周期數(shù)目可以通過ADC_SMPR1和
ADC_SMPR2寄存器中的SMP[2:0]位更改。每個(gè)通道可以分別用不同的時(shí)間采樣。
總轉(zhuǎn)換時(shí)間如下計(jì)算:
T(CONV) = 采樣時(shí)間+ 12.5個(gè)周期
例如:
當(dāng)ADCCLK=14MHz,采樣時(shí)間為1.5周期
T(CONV) = 1.5 + 12.5 = 14周期 = 1μs
ADC_SMPR1寄存器和ADC_SMPR2寄存器用來設(shè)置通道0~17這18個(gè)通道
ADC采樣時(shí)間——可編程的采樣時(shí)間
ADC_SQR1/SQR2/SQR3規(guī)則序列寄存器
ADC_JSQR注入系列寄存器
ADC_SR狀態(tài)寄存器
常用庫函數(shù)
void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);ADC的初始化函數(shù)
void ADC_DeInit(ADC_TypeDef* ADCx);
void ADC_Cmd(ADC_TypeDef* ADCx, FunctionalState NewState);ADC使能函數(shù)
void ADC_ITConfig(ADC_TypeDef* ADCx, uint16_t ADC_IT, FunctionalState NewState);中斷配置函數(shù)
void ADC_SoftwareStartConvCmd(ADC_TypeDef* ADCx, FunctionalState NewState);軟件啟動(dòng)轉(zhuǎn)換函數(shù)
void ADC_RegularChannelConfig(ADC_TypeDef* ADCx, uint8_t ADC_Channel, uint8_t Rank, uint8_t ADC_SampleTime);配置規(guī)則通道
uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx);ADC獲取轉(zhuǎn)換結(jié)果函數(shù)
校準(zhǔn)函數(shù):
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_ResetCalibration(ADC1); //使能復(fù)位校準(zhǔn)
while(ADC_GetResetCalibrationStatus(ADC1)); //等待復(fù)位校準(zhǔn)結(jié)束
ADC_StartCalibration(ADC1); //開啟AD校準(zhǔn)
while(ADC_GetCalibrationStatus(ADC1)); //等待校準(zhǔn)結(jié)束
typedef struct
{
uint32_t ADC_Mode;//ADC模式:配置ADC_CR1寄存器的位[19:16] :DUALMODE[3:0]位
FunctionalState ADC_ScanConvMode; //是否使用掃描模式。ADC_CR1位8:SCAN位
FunctionalState ADC_ContinuousConvMode; //單次轉(zhuǎn)換OR連續(xù)轉(zhuǎn)換:ADC_CR2的位1:CONT uint32_t ADC_ExternalTrigConv; //觸發(fā)方式:ADC_CR2的位[19:17] :EXTSEL[2:0]
uint32_t ADC_DataAlign; //對齊方式:左對齊還是右對齊:ADC_CR2的位11:ALIGN
uint8_t ADC_NbrOfChannel;//規(guī)則通道序列長度:ADC_SQR1的位[23:20]: L[3:0]
}ADC_InitTypeDef;
例:
void ADC_Init(ADC_TypeDef*ADCx,ADC_InitTypeDef*ADC_InitStruct)
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //獨(dú)立模式
ADC_InitStructure.ADC_ScanConvMode = DISABLE; //不開啟掃描
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //單次轉(zhuǎn)換模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //觸發(fā)軟件
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC數(shù)據(jù)右對齊
ADC_InitStructure.ADC_NbrOfChannel = 1; //順序進(jìn)行規(guī)則轉(zhuǎn)換的ADC通道的數(shù)目
ADC使能函數(shù)ADC_Cmd()
例如:ADC_Cmd(ADC1,ENABLE);//使能指定的ADC1
ADC使能軟件轉(zhuǎn)換函數(shù)ADC void ADC_SoftwareStartConvCmd();
例如:ADC_SoftwareStartConvCmd(ADC1,ENABLE);//使能ADC1的軟件轉(zhuǎn)換啟動(dòng)
ADC規(guī)則通道配置函數(shù)voidADC_RegularChannelConfig()
例如:ADC_RegularChannelConfig(ADC1,ADC_Channel_1,1,ADC_SampleTime_239Cycles5);//在ADC1的通道1,規(guī)則序列中的第1個(gè)轉(zhuǎn)換,采樣時(shí)間。ADC_RegularChannelConfig(用哪個(gè)ADC,哪個(gè)通道, 通道在規(guī)則序列中的序號, 采樣時(shí)間);
ADC獲取轉(zhuǎn)換結(jié)果函數(shù)ADC_GetConversionValue();如ADC_GetConversionValue(ADC1);//獲取ADC1轉(zhuǎn)換結(jié)果
實(shí)驗(yàn)一:ADC1的通道1(PA1)進(jìn)行單次轉(zhuǎn)換
目的:使用庫函數(shù)的函數(shù)來設(shè)定使用ADC1的通道1進(jìn)行A/D轉(zhuǎn)換。
ADC的配置過程如下:
①開啟PA口時(shí)鐘和ADC1時(shí)鐘,設(shè)置PA1為模擬輸入。
GPIO_Init();
APB2PeriphClockCmd();
② 復(fù)位ADC1,同時(shí)設(shè)置ADC1分頻因子。
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
ADC_DeInit(ADC1);
③ 初始化ADC1參數(shù),設(shè)置ADC1的工作模式以及規(guī)則序列的相關(guān)信息。
void ADC_Init(ADC_TypeDef* ADCx, ADC_InitTypeDef* ADC_InitStruct);
④ 使能ADC并校準(zhǔn)。
ADC_Cmd(ADC1, ENABLE); //ADC使能函數(shù)
校準(zhǔn)使用校準(zhǔn)函數(shù)
⑤ 配置規(guī)則通道參數(shù):
ADC_RegularChannelConfig();
ADC1的通道1的配置方法:ADC_RegularChannelConfig(ADC1,ADC_Channel_1,1,ADC_SampleTime_239Cycles5)
⑥開啟軟件轉(zhuǎn)換:
ADC_SoftwareStartConvCmd(ADC1);
⑦等待轉(zhuǎn)換完成,讀取ADC值。
ADC_GetConversionValue(ADC1);//獲取ADC1的轉(zhuǎn)換結(jié)果
將上面七個(gè)步驟的功能代碼寫在兩個(gè)函數(shù)中即可實(shí)現(xiàn)功能,分別是函數(shù)void Adc_Init(void);和函數(shù)u16 Get_Adc(u8 ch);
將上面步驟一到步驟四的程序功能代碼寫在void Adc_Init(void);函數(shù)中。
獲取轉(zhuǎn)換結(jié)果即將實(shí)現(xiàn)步驟五到步驟七的功能代碼寫在u16 Get_Adc(u8 ch);函數(shù)中
多次調(diào)用u16 Get_Adc(u8 ch)函數(shù)讀取ADC1的轉(zhuǎn)換結(jié)果,再求平均值,將功能代碼寫在u16 Get_Adc_Average(u8 ch,u8 times)函數(shù)中
STM32實(shí)現(xiàn)對12V電壓的檢測
我們現(xiàn)在需要用STM32對12V電壓進(jìn)行檢測,判斷其是否正確上電。我打算利用STM32的ADC功能,但12V超過了STM32能承受的范圍,我們可以用電阻簡單分壓成3.3V,然后用STM32的ADC引腳直接采樣,判斷。不要讓ADC腳接到5V以上的的電壓,會(huì)燒壞引腳。
|
評分
-
查看全部評分
|