1. 本次實踐目標(biāo)
a. 完成外部 ADC 的采集, 連接引腳為 PC2
b. 完成 STM32 內(nèi)置溫度傳感器 ADC 的采集
c. ADC 的采集必須以 DMA 的方式工作,通過 FreeRTOS 系統(tǒng)中創(chuàng)建的一個進(jìn)程讀取采集結(jié)果,并打包通過網(wǎng)絡(luò)發(fā)送至上位機(jī)
2. 查看 datasheet
2.1 確認(rèn) STM32 內(nèi)部溫度傳感器 使用哪個 ADCx , 使用哪個 channel
經(jīng)確認(rèn),STM32 內(nèi)部溫度傳感器使用 ADC1 的 channel_16。
2.2 查看 PC2 引腳作為 ADC 輸入時,使用哪個 ADCx, 使用哪個 channel
經(jīng)確認(rèn),STM32 的 PC2 引腳可以使用 ADC[1,2,3] 的 channel_12。
2.5.4 ADC 配置
A.初始化基本參數(shù):
DMA_PeripheralBaseAddr = ADC1_DR_Address;
#define ADC1_DR_Address ((u32)0x40012400+0x4c)
#define ADC1_BUF_SIZE 2
#define TOTAL_CONVERT_CH_NUM 2
vu16 ADC_Buf[2];
其中 ADC1_DR_Address 可從數(shù)據(jù)手冊中查得
第一個參數(shù) DMA_PeripheralBaseAddr 用來設(shè)置 DMA 傳輸?shù)耐庠O(shè)基地址,比如要進(jìn)行ADC采集,那么外設(shè)基地址 ADC1 數(shù)據(jù)存儲器 ADC1->DR 的地址,表示方法為 (u32) & ADC1->DR,當(dāng)然也可以通過數(shù)據(jù)手冊直接算出外設(shè)的地址。
第二個參數(shù) DMA_MemoryBaseAddr 為內(nèi)存基地址,也就是我們存放DMA傳輸數(shù)據(jù)的內(nèi)存地址 = (u32)ADC_Buf。
第三個參數(shù) DMA_DIR 設(shè)置數(shù)據(jù)傳輸方向,決定是從外設(shè)讀取數(shù)據(jù)到內(nèi)存還送從內(nèi)存讀取數(shù)據(jù)發(fā)送到外設(shè),也就是外設(shè)是源地還是目的地,這里我們設(shè)置為從外設(shè)地址讀取數(shù)據(jù),所以外設(shè)是源地了,所以選擇值為DMA_DIR_PeripheralSRC。
第四個參數(shù) DMA_BufferSize 設(shè)置一次傳輸數(shù)據(jù)量的大小,我們需要采集兩個通道的數(shù)據(jù) 所以設(shè)置為ADC1_BUF_SIZE
第五個參數(shù) DMA_PeripheralInc 設(shè)置傳輸數(shù)據(jù)的時候外設(shè)地址是不變還是遞增。設(shè)置為DMA_PeripheralInc_Disable;
第六個參數(shù) DMA_MemoryInc 設(shè)置傳輸數(shù)據(jù)時候內(nèi)存地址是否遞增,由于我們是多通道采集,因此需要遞增
第七個參數(shù) DMA_PeripheralDataSize 用來設(shè)置外設(shè)的的數(shù)據(jù)長度是為字節(jié)傳輸(8bits),半字傳輸(16bits)還是字傳輸(32bits),這里我們是 16 位半字傳輸,所以值設(shè)置為 DMA_PeripheralDataSize_HalfWord
第八個參數(shù) DMA_MemoryDataSize 是用來設(shè)置內(nèi)存的數(shù)據(jù)長度,同樣設(shè)置為半字傳輸 DMA_PeripheralDataSize_HalfWord。
第九個參數(shù) DMA_Mode用來設(shè)置DMA模式是否循環(huán)采集。
第十個參數(shù)是設(shè)置 DMA 通道的優(yōu)先級,有低,中,高,超高三種模式,這里我們設(shè)置優(yōu)先級別為高級,所以值為DMA_Priority_High。因為開啟多個通道,這個值非常重要。
第十一個參數(shù) DMA_M2M 設(shè)置是否存儲到存儲器模式傳輸設(shè)置為 DMA_M2M_Disable。
工作模式:ADC_Mode =ADC_Mode_Independent;
總共有10種,主要都是針對雙ADC下使用。針對初學(xué)者這里不多描述,感興趣的朋友可以先自行研究一下各個模式的使用。
瀏覽模式:ADC_ScanConvMode = ENABLE;
主要是針對多條通道而言,也就是說你是否有多條通道。
多通道:ENABLE;
單通道:DISABLE;
轉(zhuǎn)換模式:ADC_ContinuousConvMode =ENABLE;
這里是配置是否需要連續(xù)轉(zhuǎn)換。
連續(xù)轉(zhuǎn)換ENABLE:也就是只需要啟動(觸發(fā))轉(zhuǎn)換一次,后面就不用再次啟動(觸發(fā))就可以連續(xù)工作了。
單次轉(zhuǎn)換DISABLE:也就是根據(jù)一次轉(zhuǎn)換完后需要再次啟動(觸發(fā))才能工作。
觸發(fā)方式:ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
觸發(fā)方式也就是使用什么方法觸發(fā)ADC轉(zhuǎn)換。喲定時器、外部觸發(fā)、軟件觸發(fā),一般常用軟件觸發(fā)。這里有很多種觸發(fā)方式,詳情可以參考其參數(shù)。
對其方式:ADC_DataAlign = ADC_DataAlign_Right;
右對齊:低12位數(shù)據(jù)為有效位(常用);
左對齊:高12為數(shù)據(jù)為有效位;
通道數(shù):ADC_NbrOfChannel =TOTAL_CONVERT_CH_NUM;
這個參數(shù)比較簡單,我們定義工作的通道數(shù)量。
B.設(shè)置規(guī)則組通道:
ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 1, ADC_SampleTime_55Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 2, ADC_SampleTime_239Cycles5);
我們定義通道12的轉(zhuǎn)換順序為第1、通道16的轉(zhuǎn)換順序為第2;
至于為什么ADC_Channel_16 的采集周期要設(shè)置為ADC_SampleTime_239Cycles5,是因為 STM32 的內(nèi)部溫度傳感器要求的,現(xiàn)在 ADC1 的時鐘源為 APB2 時鐘分枝 8 分頻,即 72MHz/8 = 9MHz。而要求采樣周期 ≥ 17.1us, 所以 17.1 * 9 = 153.9,而最接近的也就是ADC_SampleTime_239Cycles5
2.5.4 讀取采集結(jié)果
到此,本次實踐總結(jié)完畢。
其實,其它的 外設(shè) DMA 控制方式與些類似,本次總結(jié)比較詳細(xì),也算是一個筆記。