0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

【GD32H757Z海棠派開發(fā)板使用手冊(cè)】第八講 ADC-規(guī)則組多通道采樣實(shí)驗(yàn)

聚沃科技 ? 2024-05-14 09:39 ? 次閱讀
wKgZomYgeJOAUiXJAB6mQrDJGEg027.png

8.1實(shí)驗(yàn)內(nèi)容

通過(guò)本實(shí)驗(yàn)主要學(xué)習(xí)以下內(nèi)容:

8.1.1ADC原理

我們知道,自然界中有非常多的模擬信號(hào),比如光照強(qiáng)度,還有其他的例如溫度、聲音等等,那么人們是怎么來(lái)衡量一個(gè)模擬信號(hào)的呢?

我們通常會(huì)說(shuō)今天光照度達(dá)到了3萬(wàn)Lux(照度單位),現(xiàn)在測(cè)量到的體溫是36.5℃,我們所處的環(huán)境是40分貝,沒錯(cuò),人們就是通過(guò)將這些模擬信號(hào)數(shù)字化,從而達(dá)到衡量這些模擬信號(hào)的目的。那對(duì)于MCU來(lái)說(shuō),如果要測(cè)量一個(gè)模擬量,可以通過(guò)自帶的ADC(Analog-to-Digital converters)模塊,即模-數(shù)轉(zhuǎn)換器將模擬量轉(zhuǎn)化為可以被MCU讀取到的數(shù)字量。

8.1.2GD32H757 ADC工作原理

GD32H757有3個(gè)逐次逼近型ADC(SAR ADC),其中ADC1最大有效位為14bit,有20個(gè)外部通道,一個(gè)內(nèi)部通道(DAC_OUT0通道);ADC1最大有效位為14bit,有18個(gè)外部通道,3個(gè)內(nèi)部通道(電池電壓(VBAT)通道、 參考電壓輸入通道(VREFINT) 和DAC_OUT1通道);ADC2最大有效位為12bit, 有17個(gè)外部通道,4個(gè)內(nèi)部通道(電池電壓(VBAT)通道、 參考電壓輸入通道(VREFINT)、內(nèi)部溫度傳感通道(VSENSE)和高精度溫度傳感器通道(VSENSE2))。

這三個(gè)ADC可以獨(dú)立工作,也可以讓ADC0和ADC1工作在同步模式下。有最多42個(gè)外部ADC引腳可用于將連接到這些引腳的電壓值轉(zhuǎn)換為數(shù)字量,這些引腳號(hào)可以通過(guò)Datasheet獲得。

wKgZomZCv0iAfAHMAADzdYRNXNk447.png

表中ADC012_INx的意思是:該IO口可以作為通道x用于ADC0、ADC1和ADC2。如ADC012_IN10,表示PC0可以用于ADC0的通道10使用,也可以作為ADC1和ADC2的通道10使用。但要注意:不能在同一個(gè)時(shí)刻讓不同的ADC去轉(zhuǎn)換同一個(gè)通道,否則會(huì)有無(wú)法預(yù)料的結(jié)果

以下總結(jié)了GD32H757 ADC的特性:

  • 高性能:

– ADC采樣分辨率:ADC0/1可配置14位、12位、10位或者8位分辨率,ADC2可配置12位、10位、8位或者6位分辨率;

– ADC0/1采樣率:14位分辨率為4 MSPs,12位分辨率為4.5 MSPs,10位分辨率為5.14 MSPs,8位分辨率為6 MSPs。分辨率越低,轉(zhuǎn)換越快;

– ADC2采樣率:12位分辨率為5.3 MSPs,10位分辨率為6.15 MSPs,8位分辨率為7.27 MSPs,6位分辨率為8.89 MSPs。分辨率越低,轉(zhuǎn)換越快;

–前置校準(zhǔn)時(shí)間:131個(gè)ADC時(shí)鐘周期;

–可編程采樣時(shí)間;

–數(shù)據(jù)存儲(chǔ)模式:最高有效位對(duì)齊和最低有效位對(duì)齊;

– DMA請(qǐng)求。

  • 模擬輸入通道:

– ADC0有20個(gè)外部模擬輸入通道,ADC1有18個(gè)外部模擬輸入通道,ADC2有17個(gè)外部模擬輸入通道;

– 1個(gè)內(nèi)部溫度傳感通道(VSENSE);

– 1個(gè)內(nèi)部參考電壓輸入通道(VREFINT);

– 1個(gè)外部監(jiān)測(cè)電池VBAT供電引腳輸入通道;

– 1個(gè)內(nèi)部高精度溫度傳感器通道(VSENSE2);

–與DAC內(nèi)部通道連接。

  • 轉(zhuǎn)換開始的發(fā)起:

–軟件;

– TRIGSEL觸發(fā)。

  • 運(yùn)行模式:

–轉(zhuǎn)換單個(gè)通道,或者掃描一序列的通道;

–單次運(yùn)行模式,每次觸發(fā)轉(zhuǎn)換一次選擇的輸入通道;

–連續(xù)運(yùn)行模式,連續(xù)轉(zhuǎn)換所選擇的輸入通道;

–間斷運(yùn)行模式;

–同步模式(適用于具有兩個(gè)或多個(gè)ADC的設(shè)備)。

  • 轉(zhuǎn)換結(jié)果閾值監(jiān)測(cè)器功能: 模擬看門狗。
  • 常規(guī)序列轉(zhuǎn)換結(jié)束、模擬看門狗事件和溢出事件都可以產(chǎn)生中斷。
  • 過(guò)采樣:

– ADC0/1為32位的數(shù)據(jù)寄存器,ADC2為16位數(shù)據(jù)寄存器;

– ADC0/1可調(diào)整的過(guò)采樣率,從2x到1024x,ADC2可調(diào)整的過(guò)采樣率,從2x到256x;

– ADC0/1高達(dá)11位的可編程數(shù)據(jù)移位,ADC2為8位的可編程數(shù)據(jù)移位,。

  • ADC0/1供電要求:1.8V到3.6V,一般電源電壓為3.3V,ADC2供電要求:1.71V到3.6V,一般電源電壓為3.3V;
  • 通道輸入范圍: VREF- ≤VIN ≤VREF+;
  • 數(shù)據(jù)可以路由到HPDF進(jìn)行后期處理。

下面介紹下GD32H757的ADC框圖:

wKgaomZCv2mAaYJWAAFu-TZOg6Q018.png

標(biāo)注1:輸入電壓和參考電壓

輸入電壓引腳定義如下表:

wKgaomZCv3aAeH_JAADfELZ_SOc089.png

GD32H757的ADC是14/12bit有效位的,14bit滿量程對(duì)應(yīng)的轉(zhuǎn)換值為16383,12bit為4095,以14bit為例,當(dāng)采樣引腳上的電壓等于ADC參考電壓時(shí),得到的轉(zhuǎn)換值即為16383。故理論采樣是指可通過(guò)以下公式得到:

采樣數(shù)值=實(shí)際電壓/參考電壓*16383

標(biāo)注2:輸入通道

前面提到,ADC0有20個(gè)外部模擬輸入通道,ADC1有18個(gè)外部模擬輸入通道,ADC2有17個(gè)外部模擬輸入通道。其中外部通道可以通過(guò)Datasheet進(jìn)行查詢。

標(biāo)注3:規(guī)則組

GD32H757的ADC轉(zhuǎn)換組稱為規(guī)則組,也叫常規(guī)序列。

規(guī)則組有三個(gè)重要的參數(shù),其一為轉(zhuǎn)換的個(gè)數(shù),其二為轉(zhuǎn)換的序列,其三為轉(zhuǎn)換周期,規(guī)定好這三個(gè)參數(shù)后,一旦開始規(guī)則組的轉(zhuǎn)換,則ADC就按照轉(zhuǎn)換序列一個(gè)一個(gè)的進(jìn)行模-數(shù)轉(zhuǎn)換,直到達(dá)到要求的轉(zhuǎn)換個(gè)數(shù)。

規(guī)則組的轉(zhuǎn)換個(gè)數(shù)由ADC_RSQ0寄存器的RL[3:0]位規(guī)定,轉(zhuǎn)換的總數(shù)目為RL[3:0]+1,轉(zhuǎn)換總數(shù)目最大為16個(gè);轉(zhuǎn)換序列和轉(zhuǎn)換周期由ADC_RSQ0~ADC_RSQ8共同決定,我們以RSQ8寄存器為例來(lái)看下:

ADC_RSQ0寄存器:

wKgZomZCv6yACeZmAAHky9jR6Ys883.pngwKgZomZCv7GAWrtQAADKmKsY0_U078.png

舉個(gè)例子,現(xiàn)需要按照CH3->CH2->CH1的順序進(jìn)行規(guī)則組轉(zhuǎn)換,則設(shè)定RL[3:0] = 2,然后設(shè)定RSQ0為2(CH3),RSQ1為1(CH2),RSQ2為0(CH1),則當(dāng)

開始規(guī)則組轉(zhuǎn)換時(shí),ADC首先進(jìn)行RSQ0規(guī)定的通道即CH3的轉(zhuǎn)換,再進(jìn)行RSQ1規(guī)定的通道即CH2的轉(zhuǎn)換,最后進(jìn)行RSQ2規(guī)定的通道即CH1轉(zhuǎn)換,當(dāng)這三個(gè)通道轉(zhuǎn)換完后,規(guī)則組轉(zhuǎn)換結(jié)束。

需要注意的是,每轉(zhuǎn)換一個(gè)規(guī)則組通道,轉(zhuǎn)換結(jié)果都會(huì)放在寄存器ADC_RDATA中,所以CPU一定要在下一個(gè)通道轉(zhuǎn)換完成前將上一個(gè)通道轉(zhuǎn)換結(jié)果讀走,否則會(huì)導(dǎo)致上一個(gè)通道數(shù)據(jù)被新的數(shù)據(jù)覆蓋。所以在多通道規(guī)則組轉(zhuǎn)換時(shí),為了保證能讀到所有通道的數(shù)據(jù),一定要使用DMA(直接存儲(chǔ)器訪問控制器),每個(gè)通道轉(zhuǎn)換結(jié)束后,都會(huì)給DMA發(fā)送請(qǐng)求,DMA就會(huì)將最新的ADC_RDATA中的數(shù)據(jù)搬走。關(guān)于ADC配合DMA的使用,后面會(huì)詳細(xì)介紹。

標(biāo)注4:觸發(fā)源

ADC的規(guī)則組需要選特定的觸發(fā)源用于觸發(fā)ADC轉(zhuǎn)換,注意,ADC的Enable(即ADC_CTL1寄存器的ADC_ON位置“1”)不會(huì)觸發(fā)ADC轉(zhuǎn)換,而是當(dāng)選定的觸發(fā)源來(lái)臨后ADC才開始轉(zhuǎn)換。

觸發(fā)源分為內(nèi)部觸發(fā)和外部觸發(fā),內(nèi)部觸發(fā)是指軟件觸發(fā);外部觸發(fā)源是除了內(nèi)部觸發(fā)源以外的觸發(fā)源,外部觸發(fā)源可以通過(guò)TRISEL選擇。TRIGSEL觸發(fā)相關(guān)內(nèi)容,請(qǐng)讀者參考GD32H7系列用戶手冊(cè)TRIGSEL章節(jié)。

wKgaomZCv8aAQwZKAACND7z1BGs830.png

標(biāo)注5:規(guī)則組數(shù)據(jù)寄存器

如標(biāo)注3規(guī)則組的表述,每個(gè)ADC的規(guī)則組只有一個(gè)數(shù)據(jù)寄存器ADC_RDATA,每轉(zhuǎn)換一個(gè)通道,轉(zhuǎn)換結(jié)果放在這個(gè)寄存器中,在下一通道轉(zhuǎn)換結(jié)束前必須要將上一個(gè)通道的轉(zhuǎn)換結(jié)果取走。

標(biāo)注6:ADC中斷及標(biāo)志位

ADC的中斷總共有兩種:規(guī)則組轉(zhuǎn)換結(jié)束中斷以及模擬看門狗,可以通過(guò)將ADC_CTL0中的EOCIE、WDE0IE、WDE2IE、WDE2IE置“1”來(lái)開啟相應(yīng)中斷。

ADC_STAT寄存器中的EOC和WDE0,1,2表示相應(yīng)事件發(fā)生,EOC置“1”表示規(guī)則組的轉(zhuǎn)換已經(jīng)結(jié)束。

8.1.3DMA原理

本實(shí)驗(yàn)中ADC通道有兩個(gè),分別為PC2_C和PC3_C,所以我們用規(guī)則組多通道采樣實(shí)現(xiàn)雙電壓讀取,從上一節(jié)內(nèi)容中可以知道,ADC規(guī)則組實(shí)現(xiàn)多通道轉(zhuǎn)換時(shí),必須要用到DMA。下面我們介紹下DMA原理。

DMA(直接存儲(chǔ)器訪問控制器)是一個(gè)非常好用的外設(shè),它提供了一種硬件的方式在外設(shè)和存儲(chǔ)器之間或者存儲(chǔ)器和存儲(chǔ)器之間傳輸數(shù)據(jù),而無(wú)需CPU的介入,從而使CPU可以專注在處理其他系統(tǒng)功能上。GD32H757有兩個(gè)DMA,其中DMA0有8個(gè)通道,DMA1也有8個(gè)通道。

GD32H757支持DMA的單一傳輸和多拍傳輸模式。這里只講解單一傳輸。DMA實(shí)現(xiàn)很簡(jiǎn)單,只要配置好以下幾要素即可。

  1. 源地址和目標(biāo)地址:DMA進(jìn)行數(shù)據(jù)搬運(yùn)過(guò)程為從源地址讀取到數(shù)據(jù),再搬運(yùn)到目標(biāo)地址。本實(shí)驗(yàn)中,需要把ADC轉(zhuǎn)換結(jié)果搬運(yùn)到自定義的buffer中,所以源地址就要設(shè)置為ADCx_RDATA寄存器地址,目標(biāo)地址為buffer地址。
  2. 源和目標(biāo)的地址增量方式:地址增量方式有固定模式和增量模式兩種,固定模式是指進(jìn)行一次DMA搬運(yùn)后,下次搬運(yùn)的源地址或目標(biāo)地址保持不變;增量模式指進(jìn)行一次DMA搬運(yùn)后,下次搬運(yùn)的源地址或目標(biāo)地址會(huì)加1。本實(shí)驗(yàn)中,源地址始終都應(yīng)該為ADCx_RDATA地址,所以源地址增量方式需要設(shè)置為固定模式,而目標(biāo)地址為自定義buffer,我們需要用buffer[0]存儲(chǔ)x軸數(shù)據(jù),buffer[1]存儲(chǔ)y軸數(shù)據(jù),所以目標(biāo)地址增量方式需要設(shè)置為增量模式。
  3. DMA傳輸方向:DMA傳輸方向有三種,分別為外設(shè)地址->存儲(chǔ)器地址、存儲(chǔ)器地址->外設(shè)地址以及存儲(chǔ)器->存儲(chǔ)器。本實(shí)驗(yàn)中源地址是外設(shè)地址,目標(biāo)地址為自定義buffer地址即存儲(chǔ)器地址,故傳輸方向需設(shè)置為外設(shè)地址->存儲(chǔ)器地址。
  4. 源和目標(biāo)數(shù)據(jù)位寬:源和目標(biāo)數(shù)據(jù)位寬表示每次搬運(yùn)的數(shù)據(jù)長(zhǎng)度,可以設(shè)置為8bit、16bit和32bit。本實(shí)驗(yàn)中ADC的數(shù)據(jù)只占用ADCx_RDATA寄存器的低半字即16bit,所以源和目標(biāo)位寬選擇16bit即可。
  5. DMA傳輸個(gè)數(shù)和循環(huán)模式:傳輸個(gè)數(shù)表示一輪DMA傳輸可以搬運(yùn)的次數(shù)。循環(huán)模式表示當(dāng)一輪DMA傳輸結(jié)束后,是否直接進(jìn)行下一輪搬運(yùn),當(dāng)開啟循環(huán)模式后,當(dāng)上一輪DMA傳輸結(jié)束后,源地址和目標(biāo)地址會(huì)恢復(fù)到最開始的狀態(tài)。本實(shí)驗(yàn)中,需要轉(zhuǎn)換2個(gè)通道ADC,故DMA傳輸個(gè)數(shù)設(shè)置為2,循環(huán)模式開啟。
  6. DMA通道優(yōu)先級(jí):DMA的每個(gè)通道都有一個(gè)軟件優(yōu)先級(jí),當(dāng)DMA控制器在同一時(shí)間接收到多個(gè)外設(shè)請(qǐng)求時(shí),仲裁器將根據(jù)外設(shè)請(qǐng)求的優(yōu)先級(jí)來(lái)決定響應(yīng)哪一個(gè)外設(shè)請(qǐng)求。優(yōu)先級(jí)包括軟件優(yōu)先級(jí)和硬件優(yōu)先級(jí),優(yōu)先級(jí)規(guī)則如下:
    軟件優(yōu)先級(jí):分為4級(jí),低,中,高和極高??梢酝ㄟ^(guò)寄存器DMA_CHxCTL的PRIO位域來(lái)配置。
    硬件優(yōu)先級(jí):當(dāng)通道具有相同的軟件優(yōu)先級(jí)時(shí),編號(hào)低的通道優(yōu)先級(jí)高。例:通道0和通道2配置為相同的軟件優(yōu)先級(jí)時(shí),通道0的優(yōu)先級(jí)高于通道2。

上面描述了DMA配置的一些要素,那么DMA是如何被觸發(fā)的呢,這里就要講到另外一個(gè)外設(shè):DMAMUX。

8.1.4DMAMUX原理

我們來(lái)看下DMA系統(tǒng)架構(gòu):

wKgaomZCv9aAFuGHAAEd1bh8xVo923.png

我們可以看到,DMA0/1的每個(gè)通道都有一個(gè)輸入源Peri_reqx,而這些輸入源則是由DMAMUX輸出。下圖為DMAMUX的框圖:

wKgZomZCv-mAHMuZAAE5_IlmLdc909.png

將以上兩個(gè)圖放在一起看就更好理解:

wKgaomZCv_yARO67AAKQ6dSUHC8278.png

可以看到DMAMUX的請(qǐng)求路由器總共有16個(gè)通道,其中通道0~7用于DMA0的通道0~7;通道8~15用于DMA1的通道0~7。

那么請(qǐng)求路由器的觸發(fā)源是什么呢?這個(gè)可以通過(guò)GD32H7用戶手冊(cè)DMAMUX章節(jié)中查出。比如本實(shí)驗(yàn)中使用PC2_C和PC3_C進(jìn)行ADC轉(zhuǎn)換,從datasheet中查出這兩個(gè)引腳分別對(duì)應(yīng)為ADC2_IN0和ADC2_IN1:

wKgaomZCwAqAUgP5AAA-p6T9IV8411.png

所以DMAMUX的請(qǐng)求路由器觸發(fā)源選擇ADC2即可,下圖為DMAMUX請(qǐng)求輸入源輸入信號(hào)表部分截圖:

wKgaomZCwBeATXshAADQSbrsUXc421.png

講到這里可能有的讀者,特別是用過(guò)GD前期產(chǎn)品(如GD32F3/F4系列)的讀者就會(huì)有疑問了,如果DMA用于ADC2,我需要選擇哪個(gè)DMA通道呢?答案就是:任意一個(gè)沒有被使用的通道即可!因?yàn)镚D32H7產(chǎn)品的DMA通道沒有綁定到特定外設(shè)上,所以只需要選擇任意一個(gè)沒有被使用的通道就可以了,這種設(shè)計(jì)方式,讓DMA的使用更加的靈活方便。

8.2硬件設(shè)計(jì)

本實(shí)驗(yàn)是使用PC2_C和PC3_C來(lái)進(jìn)行電壓采集,讀者可以采用飛線方式外接電壓到這兩個(gè)引腳進(jìn)行測(cè)試。

8.3代碼解析

本實(shí)驗(yàn)用到兩個(gè)ADC2通道,使用ADC2規(guī)則組搭配DMA1通道0進(jìn)行數(shù)據(jù)轉(zhuǎn)換和搬運(yùn),ADC2規(guī)則組和DMA1通道0都開啟循環(huán)模式,一旦開始ADC2規(guī)則組轉(zhuǎn)換,會(huì)持續(xù)PC2_C和PC3_C上的電壓進(jìn)行轉(zhuǎn)換和數(shù)據(jù)搬運(yùn)。

8.3.1DMA和ADC初始化

在driver_adc.c中定義driver_adc_regular_ch_dma_config函數(shù),該函數(shù)實(shí)現(xiàn)DMA和ADC的初始化。

C
void driver_adc_regular_ch_dma_config(typdef_adc_ch_general *ADC, typdef_adc_ch_parameter *ADC_CH,void *buffer)
{
dma_single_data_parameter_struct dma_single_data_parameter;
rcu_periph_clock_enable(ADC->dma_parameter.rcu_dma); /*DMA時(shí)鐘開啟*/
rcu_periph_clock_enable(RCU_DMAMUX);
dma_deinit(ADC->dma_parameter.dma_periph, ADC->dma_parameter.dma_channel); /*DMA通道參數(shù)復(fù)位*/
/*DMA源地址、目標(biāo)地址、增量方式、傳輸位寬、傳輸方向、傳輸個(gè)數(shù)、優(yōu)先級(jí)設(shè)置*/
dma_single_data_parameter.request = ADC->dma_parameter.request;
dma_single_data_parameter.periph_addr = (uint32_t)(&ADC_RDATA(ADC->adc_port));
dma_single_data_parameter.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
dma_single_data_parameter.memory0_addr = (uint32_t)(buffer);
dma_single_data_parameter.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
if(ADC->adc_mode == ADC_DAUL_REGULAL_PARALLEL)
{
dma_single_data_parameter.periph_memory_width = DMA_PERIPH_WIDTH_32BIT;
}
else
{
dma_single_data_parameter.periph_memory_width = DMA_PERIPH_WIDTH_16BIT;
}
dma_single_data_parameter.direction = DMA_PERIPH_TO_MEMORY;
dma_single_data_parameter.number = ADC->dma_parameter.dma_number;
dma_single_data_parameter.priority = ADC->dma_parameter.dma_priority;
dma_single_data_mode_init(ADC->dma_parameter.dma_periph, ADC->dma_parameter.dma_channel, &dma_single_data_parameter);
/*DMA循環(huán)模式設(shè)置*/
if(ADC->dma_parameter.dma_circulation_mode == ENABLE)
{
dma_circulation_enable(ADC->dma_parameter.dma_periph, ADC->dma_parameter.dma_channel);
}
else
{
dma_circulation_disable(ADC->dma_parameter.dma_periph, ADC->dma_parameter.dma_channel);
}
dma_channel_enable(ADC->dma_parameter.dma_periph, ADC->dma_parameter.dma_channel); /* 使能DMA */
driver_adc_config(ADC,ADC_CH); /* ADC初始化 */
}

ADC初始化函數(shù)定義如下:

C++
void driver_adc_config(typdef_adc_ch_general *ADC,typdef_adc_ch_parameter *ADC_CH)
{
uint8_t i;
adc_idx_enum idx_adc;
adc_deinit(ADC->adc_port);
/* ADC clock config */

if(ADC->adc_port==ADC0){
idx_adc=IDX_ADC0;
}else if(ADC->adc_port==ADC1){
idx_adc=IDX_ADC1;
}else{
idx_adc=IDX_ADC2;
}
rcu_adc_clock_config(idx_adc, RCU_ADCSRC_PER);

adc_clock_config(ADC->adc_port, ADC->adc_psc); /*配置ADC時(shí)鐘頻率*/
rcu_periph_clock_enable(ADC->rcu_adc); /*使能ADC時(shí)鐘*/

/*配置ADC相關(guān)IO口,先配置時(shí)鐘,再將IO口設(shè)置為模擬輸入*/
for(i=0 ;ich_count; i++)
{
if(ADC_CH[i].adc_channel < ADC_CHANNEL_17)
{
rcu_periph_clock_enable(ADC_CH[i].rcu_port);
gpio_mode_set(ADC_CH[i].port, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, ADC_CH[i].pin);
}
else
{
if(ADC->adc_port==ADC2)
{
if(ADC_CH[i].adc_channel == ADC_CHANNEL_17)
{
adc_internal_channel_config(ADC_CHANNEL_INTERNAL_VBAT, ENABLE);
}
else if(ADC_CH[i].adc_channel == ADC_CHANNEL_18)
{
adc_internal_channel_config(ADC_CHANNEL_INTERNAL_TEMPSENSOR, ENABLE);
}
else if(ADC_CH[i].adc_channel == ADC_CHANNEL_19)
{
adc_internal_channel_config(ADC_CHANNEL_INTERNAL_VREFINT, ENABLE);
}
else if(ADC_CH[i].adc_channel == ADC_CHANNEL_20)
{
adc_internal_channel_config(ADC_CHANNEL_INTERNAL_HP_TEMPSENSOR, ENABLE);
}
}
else
{
rcu_periph_clock_enable(ADC_CH[i].rcu_port);
gpio_mode_set(ADC_CH[i].port, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, ADC_CH[i].pin);
}
}

}
adc_sync_mode_config(ADC->adc_mode); /*配置ADC工作模式,如獨(dú)立模式,規(guī)則并行模式等*/
adc_special_function_config(ADC->adc_port, ADC_SCAN_MODE, ADC->adc_scan_function); /*配置規(guī)則組的掃描模式和連續(xù)轉(zhuǎn)換模式*/
if(ADC->adc_channel_group == ADC_REGULAR_CHANNEL)
{
adc_special_function_config(ADC->adc_port, ADC_CONTINUOUS_MODE, ADC->adc_continuous_function);
}
adc_data_alignment_config(ADC->adc_port, ADC_DATAALIGN_RIGHT); /*選擇數(shù)據(jù)右對(duì)齊*/
adc_channel_length_config(ADC->adc_port, ADC->adc_channel_group, ADC->ch_count); /*配置轉(zhuǎn)換通道數(shù)*/
if(ADC->adc_channel_group == ADC_REGULAR_CHANNEL) /*配置轉(zhuǎn)換順序*/
{
for(i = 0;i< ADC->ch_count;i++)
{
adc_regular_channel_config(ADC->adc_port, i, ADC_CH[i].adc_channel,ADC_CH[i].sample_time);
}
}
else if(ADC->adc_channel_group == ADC_INSERTED_CHANNEL)
{
for(i = 0;i< ADC->ch_count;i++)
{
adc_inserted_channel_config(ADC->adc_port, i, ADC_CH[i].adc_channel,ADC_CH[i].sample_time);
}
}
/*選擇觸發(fā)源及使能外部觸發(fā)模式*/
adc_external_trigger_config(ADC->adc_port, ADC->adc_channel_group, ADC->adc_external_trigger_mode);
/*選擇是否需要使用DMA*/
if(ADC->DMA_mode == ENABLE)
{
adc_dma_request_after_last_enable(ADC->adc_port);
adc_dma_mode_enable(ADC->adc_port);
}
/*ADC的使能和自校準(zhǔn),ADC使能后需要經(jīng)過(guò)一定的ADC_CLK后才能校準(zhǔn),本示例中直接使用1ms延時(shí)*/
adc_enable(ADC->adc_port);
delay_ms(1);
/* ADC calibration mode config */
adc_calibration_mode_config(ADC->adc_port, ADC_CALIBRATION_OFFSET_MISMATCH);
/* ADC calibration number config */
adc_calibration_number(ADC->adc_port, ADC_CALIBRATION_NUM32);
adc_calibration_enable(ADC->adc_port);
}

在driver_adc.h中聲明了ADC DMA的結(jié)構(gòu)體:

C
typedef struct __typdef_adc_dma_parameter
{
rcu_periph_enum rcu_dma; //DMA時(shí)鐘
uint32_t dma_periph; //DMA號(hào)
dma_channel_enum dma_channel;//DMA通道號(hào)
uint32_t request;//DMA請(qǐng)求
uint32_t dma_number; //DMA傳輸個(gè)數(shù)
uint32_t dma_priority; //DMA通道優(yōu)先級(jí)
EventStatus dma_circulation_mode;//循環(huán)模式
}typdef_adc_dma_parameter;

這段代碼比較簡(jiǎn)單,請(qǐng)讀者按照前面介紹的DMA原理進(jìn)行解析。

8.3.2BSP_ADC設(shè)置所需要的參數(shù)及IO口結(jié)構(gòu)體定義

在bsp_adc.c中,對(duì)BSP_ADC設(shè)置所需要的參數(shù)及IO擴(kuò)結(jié)構(gòu)體數(shù)組進(jìn)行了定義:

C
typdef_adc_ch_general BSP_ADC= {
.rcu_adc = RCU_ADC2, /* ADC2的時(shí)鐘 */
.adc_psc = ADC_CLK_SYNC_HCLK_DIV6, /* ADC2設(shè)置為HCLK 6分頻 */
.adc_port = ADC2, /* ADC口為ADC2 */
.adc_mode = ADC_SYNC_MODE_INDEPENDENT, /* ADC模式為獨(dú)立模式 */
.adc_channel_group = ADC_REGULAR_CHANNEL, /* 使用規(guī)則組 */
.adc_scan_function = ENABLE, /* 開啟掃描模式 */
.adc_continuous_function = ENABLE, /* 開啟循環(huán)模式 */
.ch_count = 2, /* 轉(zhuǎn)換長(zhǎng)度為2 */
.adc_external_trigger_mode = EXTERNAL_TRIGGER_DISABLE,
.dma_parameter =
{
.rcu_dma = RCU_DMA1, /* DMA1的時(shí)鐘 */
.dma_periph = DMA1, /* 使用DMA1 */
.dma_channel = DMA_CH0, /* 使用通道4 */
.dma_number = 2, /* DMA傳輸長(zhǎng)度為2 */
.request = DMA_REQUEST_ADC2,
.dma_priority = DMA_PRIORITY_HIGH, /* DMA通道優(yōu)先級(jí) */
.dma_circulation_mode = ENABLE /* DMA循環(huán)模式打開 */
},
.DMA_mode = ENABLE /* 使用DMA */
};

typdef_adc_ch_parameter BSP_ADC_ch[2] =
{
{
.rcu_port = RCU_GPIOC, /* GPIOC時(shí)鐘 */
.port = GPIOC, /* GPIO port */
.pin = GPIO_PIN_2, /* PC2 */
.gpio_speed = GPIO_OSPEED_12MHZ, /* PC2速度設(shè)置為12MHz */
.adc_channel = ADC_CHANNEL_0, /* PC2是ADC2的通道0 */
.sample_time = 240 /* 設(shè)置采樣周期為240 */
}
,
{
.rcu_port = RCU_GPIOC, /* GPIOC時(shí)鐘 */
.port = GPIOC, /* GPIO port */
.pin = GPIO_PIN_3, /* PC3 */
.gpio_speed = GPIO_OSPEED_12MHZ, /* PC3速度設(shè)置為12MHz */
.adc_channel = ADC_CHANNEL_1, /* PC3是ADC2的通道1 */
.sample_time = 240 /* 設(shè)置采樣周期為55.5 */
}
};/* ADC通道參數(shù)配置,包括IO口,和對(duì)應(yīng)通道以及采樣周期 */

8.3.3BSP_ ADC初始化和觸發(fā)ADC轉(zhuǎn)換的具體實(shí)現(xiàn)函數(shù)

在bsp_adc.c中定義了DMA和ADC初始化和觸發(fā)ADC轉(zhuǎn)換的函數(shù):

C
uint16_t BSP_ADC_data[2] ;
void bsp_ADC_config()
{
driver_adc_regular_ch_dma_config(&BSP_ADC,BSP_ADC_ch,(uint16_t*)BSP_ADC_data);
driver_adc_software_trigger_enable(&BSP_ADC);
}

8.3.4main函數(shù)實(shí)現(xiàn)

C
int main(void)
{
driver_init();//延時(shí)函數(shù)初始化
bsp_uart_init(&BOARD_UART);//BOARD_UART串口初始化
bsp_ADC_config();//bsp ADC配置
while (1)
{
delay_ms(100);//延時(shí)100ms
printf_log(" the BSP_ADC data is %d,%d \r\n", BSP_ADC_data[0],BSP_ADC_data[1]);//打印ADC數(shù)據(jù)
}
}

本例程main函數(shù)首先進(jìn)行了延時(shí)函數(shù)初始化,為了演示實(shí)驗(yàn)結(jié)果,這里初始化了BOARD_UART串口,關(guān)于串口的使用,請(qǐng)讀者參考串口章節(jié),然后是BSP_ADC配置。在主循環(huán)中,每100ms打印一次PC2_C和PC3_C的ADC轉(zhuǎn)換數(shù)據(jù)。

8.4實(shí)驗(yàn)結(jié)果

如上main函數(shù)實(shí)現(xiàn)說(shuō)明。

教程GD32 MCU方案商聚沃科技原創(chuàng)發(fā)布,了解更多GD32 MCU教程,關(guān)注聚沃科技官網(wǎng)

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • adc
    adc
    +關(guān)注

    關(guān)注

    97

    文章

    6296

    瀏覽量

    542402
  • GD32
    +關(guān)注

    關(guān)注

    7

    文章

    400

    瀏覽量

    23971
  • GD32開發(fā)板
    +關(guān)注

    關(guān)注

    0

    文章

    3

    瀏覽量

    1081
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    GD32H757Z海棠開發(fā)板使用手冊(cè)】第四 FMC-片內(nèi)Flash擦寫讀實(shí)驗(yàn)

    FMC即Flash控制器,其提供了片上Flash操作所需要的所有功能,在GD32H7XX系列MCU中,具有高達(dá)3840KB字節(jié)的片上閃存可用于存儲(chǔ)指令或數(shù)據(jù)。FMC也提供了扇區(qū)擦除和整片擦除操作以及
    的頭像 發(fā)表于 04-19 10:09 ?991次閱讀
    【<b class='flag-5'>GD32H757Z</b><b class='flag-5'>海棠</b><b class='flag-5'>派</b><b class='flag-5'>開發(fā)板</b><b class='flag-5'>使用手冊(cè)</b>】第四<b class='flag-5'>講</b> FMC-片內(nèi)Flash擦寫讀<b class='flag-5'>實(shí)驗(yàn)</b>

    GD32H757Z海棠開發(fā)板使用手冊(cè)】第十三講 SDIO-SD卡讀寫實(shí)驗(yàn)

    通過(guò)本實(shí)驗(yàn)主要學(xué)習(xí)以下內(nèi)容: ?USB協(xié)議基本原理 ?GD32H7xx USBHS的使用 ?虛擬鍵盤的協(xié)議原理及使用
    的頭像 發(fā)表于 06-06 11:26 ?1499次閱讀
    【<b class='flag-5'>GD32H757Z</b><b class='flag-5'>海棠</b><b class='flag-5'>派</b><b class='flag-5'>開發(fā)板</b><b class='flag-5'>使用手冊(cè)</b>】第十三講 SDIO-SD卡讀寫<b class='flag-5'>實(shí)驗(yàn)</b>

    YL-51開發(fā)板使用手冊(cè)

    YL-51開發(fā)板使用手冊(cè),YL-51開發(fā)板使用手冊(cè)YL-51開發(fā)板使用手冊(cè)YL-51
    發(fā)表于 05-10 16:31 ?21次下載

    51開發(fā)板使用手冊(cè)

    51開發(fā)板使用手冊(cè),感興趣的小伙伴們可以瞧一瞧。
    發(fā)表于 11-23 15:45 ?11次下載

    KC705開發(fā)板英文使用手冊(cè)

    KC705開發(fā)板英文使用手冊(cè)
    發(fā)表于 11-01 10:19 ?4次下載

    iTOP-3399開發(fā)板使用手冊(cè)大更新

    iTOP-3399開發(fā)板使用手冊(cè)大更新
    的頭像 發(fā)表于 12-10 15:46 ?1208次閱讀
    iTOP-3399<b class='flag-5'>開發(fā)板</b><b class='flag-5'>使用手冊(cè)</b>大更新

    GD32 ADC規(guī)則通道采樣,數(shù)據(jù)發(fā)生錯(cuò)位?

    我們知道,使用ADC規(guī)則(常規(guī)通道采樣時(shí),必
    的頭像 發(fā)表于 03-14 09:58 ?1737次閱讀
    <b class='flag-5'>GD</b>32 <b class='flag-5'>ADC</b><b class='flag-5'>規(guī)則</b><b class='flag-5'>組</b><b class='flag-5'>多</b><b class='flag-5'>通道</b><b class='flag-5'>采樣</b>,數(shù)據(jù)發(fā)生錯(cuò)位?

    GD32H757Z海棠開發(fā)板使用手冊(cè)】第二 GPIO-按鍵查詢檢測(cè)實(shí)驗(yàn)

    2.1實(shí)驗(yàn)內(nèi)容通過(guò)本實(shí)驗(yàn)主要學(xué)習(xí)以下內(nèi)容:GPIO輸入功能原理;按鍵查詢輸入檢測(cè)原理;2.2實(shí)驗(yàn)原理2.2.1GPIO輸入功能原理GD32H7XX系列MCUGPIO輸入配置結(jié)構(gòu)如下圖所
    的頭像 發(fā)表于 04-17 10:42 ?486次閱讀
    【<b class='flag-5'>GD32H757Z</b><b class='flag-5'>海棠</b><b class='flag-5'>派</b><b class='flag-5'>開發(fā)板</b><b class='flag-5'>使用手冊(cè)</b>】第二<b class='flag-5'>講</b> GPIO-按鍵查詢檢測(cè)<b class='flag-5'>實(shí)驗(yàn)</b>

    GD32H757Z海棠開發(fā)板使用手冊(cè)】第五 PMU-低功耗實(shí)驗(yàn)

    PMU即電源管理單元,其內(nèi)部結(jié)構(gòu)下圖所示,由該圖可知,GD32H7XX系列MCU具有三個(gè)電源域,包括VDD/VDDA電源域、0.9V電源域以及電池備份域,其中,VDD /VDDA域由電源直接供電
    的頭像 發(fā)表于 04-20 09:32 ?634次閱讀
    【<b class='flag-5'>GD32H757Z</b><b class='flag-5'>海棠</b><b class='flag-5'>派</b><b class='flag-5'>開發(fā)板</b><b class='flag-5'>使用手冊(cè)</b>】第五<b class='flag-5'>講</b> PMU-低功耗<b class='flag-5'>實(shí)驗(yàn)</b>

    GD32F470紫藤開發(fā)板使用手冊(cè)第八 ADC-規(guī)則通道采樣實(shí)驗(yàn)

    通過(guò)本實(shí)驗(yàn)主要學(xué)習(xí)以下內(nèi)容: ?ADC的簡(jiǎn)介 ?GD32F470 ADC工作原理 ?DMA原理 ?規(guī)則
    的頭像 發(fā)表于 05-12 10:00 ?514次閱讀
    【<b class='flag-5'>GD</b>32F470紫藤<b class='flag-5'>派</b><b class='flag-5'>開發(fā)板</b><b class='flag-5'>使用手冊(cè)</b>】<b class='flag-5'>第八</b><b class='flag-5'>講</b> <b class='flag-5'>ADC-</b><b class='flag-5'>規(guī)則</b><b class='flag-5'>組</b><b class='flag-5'>多</b><b class='flag-5'>通道</b><b class='flag-5'>采樣</b><b class='flag-5'>實(shí)驗(yàn)</b>

    GD32H757Z海棠開發(fā)板使用手冊(cè)】第九 USART-printf打印實(shí)驗(yàn)

    通過(guò)本實(shí)驗(yàn)主要學(xué)習(xí)以下內(nèi)容: ?串口簡(jiǎn)介 ?GD32H757串口工作原理 ?使用printf打印信息
    的頭像 發(fā)表于 05-15 11:39 ?430次閱讀
    【<b class='flag-5'>GD32H757Z</b><b class='flag-5'>海棠</b><b class='flag-5'>派</b><b class='flag-5'>開發(fā)板</b><b class='flag-5'>使用手冊(cè)</b>】第九<b class='flag-5'>講</b> USART-printf打印<b class='flag-5'>實(shí)驗(yàn)</b>

    GD32H757Z海棠開發(fā)板使用手冊(cè)】第十一講 SPI-SPI NOR FLASH讀寫實(shí)驗(yàn)

    通過(guò)本實(shí)驗(yàn)主要學(xué)習(xí)以下內(nèi)容: ?SPI簡(jiǎn)介 ?GD32H7 SPI簡(jiǎn)介 ?SPI NOR FLASH——GD25Q128ESIGR簡(jiǎn)介 ?使用GD32H7 SPI接口實(shí)現(xiàn)對(duì)
    的頭像 發(fā)表于 06-04 11:42 ?533次閱讀
    【<b class='flag-5'>GD32H757Z</b><b class='flag-5'>海棠</b><b class='flag-5'>派</b><b class='flag-5'>開發(fā)板</b><b class='flag-5'>使用手冊(cè)</b>】第十一講 SPI-SPI NOR FLASH讀寫<b class='flag-5'>實(shí)驗(yàn)</b>

    GD32F303紅楓開發(fā)板使用手冊(cè)】第十二 ADC-雙軸按鍵搖桿通道循環(huán)采樣實(shí)驗(yàn)

    實(shí)驗(yàn)是通過(guò)ADC規(guī)則通道循環(huán)采樣方式實(shí)現(xiàn)雙軸按
    的頭像 發(fā)表于 06-11 09:40 ?432次閱讀
    【<b class='flag-5'>GD</b>32F303紅楓<b class='flag-5'>派</b><b class='flag-5'>開發(fā)板</b><b class='flag-5'>使用手冊(cè)</b>】第十二<b class='flag-5'>講</b>   <b class='flag-5'>ADC-</b>雙軸按鍵搖桿<b class='flag-5'>多</b><b class='flag-5'>通道</b>循環(huán)<b class='flag-5'>采樣</b><b class='flag-5'>實(shí)驗(yàn)</b>

    GD32F303紅楓開發(fā)板使用手冊(cè)】第十三講 ADC-內(nèi)部溫度傳感器和參考電壓采樣實(shí)驗(yàn)

    實(shí)驗(yàn)是通過(guò)ADC注入采樣內(nèi)部溫度傳感器和參考電壓,通過(guò)本實(shí)驗(yàn)主要學(xué)習(xí)以下內(nèi)容: ?內(nèi)部溫度傳感器和參考電壓簡(jiǎn)介 ?
    的頭像 發(fā)表于 06-12 09:47 ?515次閱讀
    【<b class='flag-5'>GD</b>32F303紅楓<b class='flag-5'>派</b><b class='flag-5'>開發(fā)板</b><b class='flag-5'>使用手冊(cè)</b>】第十三講 <b class='flag-5'>ADC-</b>內(nèi)部溫度傳感器和參考電壓<b class='flag-5'>采樣</b><b class='flag-5'>實(shí)驗(yàn)</b>

    GD32F303紅楓開發(fā)板使用手冊(cè)】第二十 SPI-SPI NAND FLASH讀寫實(shí)驗(yàn)

    通過(guò)本實(shí)驗(yàn)主要學(xué)習(xí)以下內(nèi)容: ?SPI通信協(xié)議,參考19.2.1東方紅開發(fā)板使用手冊(cè) ?GD32F303 SPI操作方式,參考19.2.2東方紅
    的頭像 發(fā)表于 06-20 09:50 ?525次閱讀
    【<b class='flag-5'>GD</b>32F303紅楓<b class='flag-5'>派</b><b class='flag-5'>開發(fā)板</b><b class='flag-5'>使用手冊(cè)</b>】第二十<b class='flag-5'>講</b> SPI-SPI NAND FLASH讀寫<b class='flag-5'>實(shí)驗(yàn)</b>