STM32學(xué)習(xí)筆記之ADC轉(zhuǎn)換
1. ADC簡(jiǎn)介
stm32f103最少有2個(gè)AD模數(shù)轉(zhuǎn)換器,每個(gè)ADC都有18個(gè)通道,可以測(cè)量16個(gè)外部和2個(gè)內(nèi)部模擬量。最大轉(zhuǎn)換頻率為1Mhz,也就是轉(zhuǎn)換時(shí)間為1us(在 ADCCLK = 14Mhz,采樣周期為1.5個(gè)時(shí)鐘周期時(shí))。最大時(shí)鐘超過14Mhz,將導(dǎo)致ADC轉(zhuǎn)換準(zhǔn)確度降低。stm32的ADC是12位精度的。
stm32的ADC轉(zhuǎn)換有兩種通道,規(guī)則通道和注入通道,注入通道可以搶占式地打斷規(guī)則通道的采樣,執(zhí)行注入通道采樣后,再執(zhí)行之前的規(guī)則通道采樣,和中斷類似。本例只使用規(guī)則通道實(shí)現(xiàn)獨(dú)立模式的中斷采樣,這里不再贅述兩種通道區(qū)別。
stm32的ADC可以由外部事件觸發(fā)(例如定時(shí)器捕獲,EXTI線)和軟件觸發(fā)(即在配置相關(guān)寄存器時(shí),直接開啟采樣)。
STM32的ADC在單次轉(zhuǎn)換模式下,只執(zhí)行一次轉(zhuǎn)換,該模式可以通過ADC_CR2 寄存器的ADON 位(只適用于規(guī)則通道)啟動(dòng),也可以通過外部觸發(fā)啟動(dòng)(適用于規(guī)則通道和注入通道),這是CONT 位為0 。 以規(guī)則通道為例,一旦所選擇的通道轉(zhuǎn)換完成,轉(zhuǎn)換結(jié)果將被存在ADC_DR 寄存器,EOC (轉(zhuǎn)換結(jié)束)標(biāo)志將被置位,如果設(shè)置了EOCIE ,則會(huì)產(chǎn)生中斷。然后ADC將停止,直到下次啟動(dòng)。
2. 寄存器簡(jiǎn)介2.1. ADC控制寄存器(ADC_CR1和ADC_CR2)ADC_CR1的SCAN 位,該位用于設(shè)置掃描模式,由軟件設(shè)置和清除,如果設(shè)置為1 ,則使用掃描模式,如果為 0,則關(guān)閉掃描模式。在掃描模式下,由 ADC_SQRx或ADC_JSQRx寄存器選中的通道被轉(zhuǎn)換。如果設(shè)置了 EOCIE 或JEOCIE,只在最后一個(gè)通道轉(zhuǎn)換完畢后才會(huì)產(chǎn)生EOC 或JEOC 中斷。
ADC_CR1[19:16]用于設(shè)置 ADC的操作模式
ADC_CR2
ADCON位用于開關(guān)AD轉(zhuǎn)換器。而CONT 位用于設(shè)置是否進(jìn)行連續(xù)轉(zhuǎn)換,我們使用單次轉(zhuǎn)換,所以CONT 位必須為0。CAL 和RSTCAL用于AD校準(zhǔn)。ALIGN用于設(shè)置數(shù)據(jù)對(duì)齊,我們使用右對(duì)齊,該位設(shè)置為0。
EXTSEL[2:0]用于選擇啟動(dòng)規(guī)則轉(zhuǎn)換組轉(zhuǎn)換的外部事件,詳細(xì)的設(shè)置關(guān)系如下:
這里使用的是軟件觸發(fā)(SWSTART ),所以設(shè)置這3 個(gè)位為111 。ADC_CR2 的SWSTART 位用于開始規(guī)則通道的轉(zhuǎn)換,我們每次轉(zhuǎn)換(單次轉(zhuǎn)換模式下)都需要向該位寫 1 。AWDEN 為用于使能溫度傳感器和Vrefint 。
2.2. ADC采樣事件寄存器(ADC_SMPR1 和ADC_SMPR2 )這兩個(gè)寄存器用于設(shè)置通道0~17的采樣時(shí)間,每個(gè)通道占用 3 個(gè)位。
ADC_SMPR2 的各位描述如下
對(duì)于每個(gè)要轉(zhuǎn)換的通道,采樣時(shí)間建議盡量長(zhǎng)一點(diǎn),以獲得較高的準(zhǔn)確度,但是這樣會(huì)降低ADC的轉(zhuǎn)換速率。ADC的轉(zhuǎn)換時(shí)間可以由下式計(jì)算:
Tcovn= 采樣時(shí)間+12.5 個(gè)周期
其中:Tcovn 為總轉(zhuǎn)換時(shí)間,采樣時(shí)間是根據(jù)每個(gè)通道的SMP位的設(shè)置來決定的。例如,當(dāng)ADCCLK=14Mhz 的時(shí)候,并設(shè)置 1.5個(gè)周期的采樣時(shí)間,則得到:Tcovn=1.5+12.5=14 個(gè)周期=1us 。
L[3:0] 用于存儲(chǔ)規(guī)則序列的長(zhǎng)度,我們這里只用了 1 個(gè),所以設(shè)置這幾個(gè)位的值為 0 。其他的SQ13~16 則存儲(chǔ)了規(guī)則序列中第13~16 個(gè)通道的編號(hào)(0~17)。另外兩個(gè)規(guī)則序列寄存器同ADC_SQR1大同小異,我們這里就不再介紹了,要說明一點(diǎn)的是:我們選擇的是單次轉(zhuǎn)換,所以只有一個(gè)通道在規(guī)則序列里面,這個(gè)序列就是SQ0 ,通過ADC_SQR3的最低5 位設(shè)置。
2.4. ADC規(guī)則數(shù)據(jù)寄存器(ADC_DR)這里要提醒一點(diǎn)的是,該寄存器的數(shù)據(jù)可以通過ADC_CR2 的ALIGN位設(shè)置左對(duì)齊還是右對(duì)齊。在讀取數(shù)據(jù)的時(shí)候要注意。
2.5. ADC狀態(tài)寄存器(ADC_SR )這里我們要用到的是EOC 位,我們通過判斷該位來決定是否此次規(guī)則通道的AD轉(zhuǎn)換已經(jīng)完成,如果完成我們就從ADC_DR 中讀取轉(zhuǎn)換結(jié)果,否則等待轉(zhuǎn)換完成。
3. 寄存器操作步驟1 、開啟PA口時(shí)鐘,設(shè)置PA0 為模擬輸入。
STM32F103RBT6的ADC通道0 在PA 0 上,所以,我們先要使能 PORTA的時(shí)鐘,然后設(shè)置PA 0 為模擬輸入。
2 、使能ADC1 時(shí)鐘,并設(shè)置分頻因子。
要使用ADC1,第一步就是要使能 ADC1 的時(shí)鐘,在使能完時(shí)鐘之后,進(jìn)行一次 ADC1 的復(fù)位。接著我們就可以通過RCC_CFGR設(shè)置ADC1 的分頻因子。分頻因子要確保 ADC1 的時(shí)鐘(ADCCLK)不要超過14Mhz 。
3 、設(shè)置ADC1 的工作模式。
在設(shè)置完分頻因子之后,我們就可以開始 ADC1 的模式配置了,設(shè)置單次轉(zhuǎn)換模式、觸發(fā)方式選擇、數(shù)據(jù)對(duì)齊方式等都在這一步實(shí)現(xiàn)。
4 、設(shè)置ADC1 規(guī)則序列的相關(guān)信息。
接下來我們要設(shè)置規(guī)則序列的相關(guān)信息,我們這里只有一個(gè)通道,并且是單次轉(zhuǎn)換的,所以設(shè)置規(guī)則序列中通道數(shù)為1 ,然后設(shè)置通道 0 的采樣周期。
5 、開啟AD轉(zhuǎn)換器,并校準(zhǔn)。
在設(shè)置完了以上信息后,我們就開啟AD轉(zhuǎn)換器,執(zhí)行復(fù)位校準(zhǔn)和AD校準(zhǔn),注意這兩步是必須的!不校準(zhǔn)將導(dǎo)致結(jié)果很不準(zhǔn)確。
6 )讀取ADC值。
在上面的校準(zhǔn)完成之后,ADC就算準(zhǔn)備好了。接下來我們要做的就是設(shè)置規(guī)則序列 0 里面的通道,然后啟動(dòng)ADC轉(zhuǎn)換。在轉(zhuǎn)換結(jié)束后,讀取ADC1_DR 里面的值就是了。
硬件設(shè)置:我們通過ADC1 的通道0 (PA 0 )來讀取外部電壓值。
注意:這里不能接到板上5V電源上去測(cè)試,這可能會(huì)燒壞 ADC!
ADC.C
#include
#include"adc.h"
//ADC驅(qū)動(dòng)代碼
//初始化ADC
//這里我們僅以規(guī)則通道為例
//我們默認(rèn)將開啟通道0~3
voidAdc_Init(void)
{
//先初始化IO口
RCC->APB2ENR|=1<<2;//使能PORTA口時(shí)鐘
GPIOA->CRL&=0XFFFF0000;//PA0123anolog輸入
//通道10/11設(shè)置
RCC->APB2ENR|=1<<9;//ADC1時(shí)鐘使能
RCC->APB2RSTR|=1<<9;//ADC1復(fù)位
RCC->APB2RSTR&=~(1<<9);//復(fù)位結(jié)束
RCC->CFGR&=~(3<<14);//分頻因子清零
//SYSCLK/DIV2=12MADC時(shí)鐘設(shè)置為12M,ADC最大時(shí)鐘不能超過14M!
//否則將導(dǎo)致ADC準(zhǔn)確度下降!
RCC->CFGR|=2<<14;
ADC1->CR1&=0XF0FFFF;//工作模式清零
ADC1->CR1|=0<<16;//獨(dú)立工作模式
ADC1->CR1&=~(1<<8);//非掃描模式
ADC1->CR2&=~(1<<1);//單次轉(zhuǎn)換模式
ADC1->CR2&=~(7<<17);
ADC1->CR2|=7<<17;//軟件控制轉(zhuǎn)換
ADC1->CR2|=1<<20;//使用用外部觸發(fā)(SWSTART)!!!必須使用一個(gè)事件來觸發(fā)
ADC1->CR2&=~(1<<11);//右對(duì)齊
ADC1->SQR1&=~(0XF<<20);
ADC1->SQR1&=0<<20;//1個(gè)轉(zhuǎn)換在規(guī)則序列中也就是只轉(zhuǎn)換規(guī)則序列1
//設(shè)置通道0~3的采樣時(shí)間
ADC1->SMPR2&=0XFFFFF000;//通道0,1,2,3采樣時(shí)間清空
ADC1->SMPR2|=7<<9;//通道3239.5周期,提高采樣時(shí)間可以提高精確度
ADC1->SMPR2|=7<<6;//通道2239.5周期,提高采樣時(shí)間可以提高精確度
ADC1->SMPR2|=7<<3;//通道1239.5周期,提高采樣時(shí)間可以提高精確度
ADC1->SMPR2|=7<<0;//通道0239.5周期,提高采樣時(shí)間可以提高精確度
ADC1->CR2|=1<<0;//開啟AD轉(zhuǎn)換器
AD