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

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

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

ADC的工作原理 ADC數(shù)據(jù)采集時的DMA技術(shù)詳解

冬至子 ? 來源:舊巷聞書 ? 作者:駱駝聽海 ? 2023-07-27 17:05 ? 次閱讀

在實際的開發(fā)中需要使用各式各樣的傳感器,這些傳感器可以采集周圍的環(huán)境信息,比如溫度、濕度、氣壓、光照等,這些信息本質(zhì)上是物理的模擬信號,計算機處理信息時對數(shù)字信號比較敏感,因此把模擬信號轉(zhuǎn)換為數(shù)字信號是有必要的。ADC就起到了這樣的作用,本節(jié)將對ADC功能原理以及ADC數(shù)據(jù)采集時涉及到的DMA技術(shù)進行詳解。

  • ADC的概念:Analog-to-Digital Converter的縮寫。指模/數(shù)轉(zhuǎn)換器或者模擬/數(shù)字轉(zhuǎn)換器。是指將連續(xù)變量的模擬信號轉(zhuǎn)換為離散的數(shù)字信號的器件。
  • ADC的作用:采集傳感器的數(shù)據(jù),測量輸入電壓,檢查電池電量剩余,監(jiān)測溫濕度等。典型的模擬數(shù)字轉(zhuǎn)換器將模擬信號轉(zhuǎn)換為表示一定比例電壓值的數(shù)字信號。

圖片

  • ADC的性能指標:

量程:能測量的電壓范圍,一般來收量程越大越好

分辨率:ADC的分辨率通常以輸出二進制數(shù)的位數(shù)表示,位數(shù)越多,分辨率越高,精度越大,外部微小的變化都可以被顯示。一般來說分辨率越高,轉(zhuǎn)化時間越長。

轉(zhuǎn)化時間:模擬輸入電壓在允許的最大變化范圍內(nèi),從轉(zhuǎn)換開始到獲得穩(wěn)定的數(shù)字量輸出所需要的時間稱為轉(zhuǎn)換時間,希望時間越短越好。

STM32F40X有3個ADC,每個可配置 12 位、10 位、8 位或 6 位分辨率

每個ADC 有16個外部通道。另外還有兩個內(nèi)部 ADC源(直接測量內(nèi)部溫度和電壓信號) 和 V BAT 通道(測量電池的剩余電量)掛在 ADC1上

這些通道的 A/D 轉(zhuǎn)換可以單次、連續(xù)、掃描或間斷模式執(zhí)行。

ADC具有獨立模式(單個ADC工作)、雙重模式(兩個ADC配合工作完成采樣)和三重模式(三個ADC配合工作完成采樣),對于不同 AD轉(zhuǎn)換要求幾乎都有合適的模式可選

ADC 的結(jié)果可以左對齊或右對齊方式存儲在 16 位數(shù)據(jù)寄存器中。采集到的數(shù)據(jù)精度最大為12位,不夠16位,因此,需要選擇合適的存儲方式。

  • ADC功能框圖分析:

圖片

1、電壓輸入范圍:ADC 輸入范圍為:V REF- ≤ V IN ≤ V REF+ 。由 V REF- 、V REF+ 、V DDA 、V SSA 、這四個外部引腳決定。我們在設(shè)計原理圖的時候一般把 V SSA 和 V REF- 接地,把 V REF+ 和 V DDA 接 3.3V,得到ADC 的輸入電壓范圍為:03.3V。如果我們想讓輸入的電壓范圍變寬,去到可以測試負電壓或者更高的正電壓,我們可以在外部加一個電壓調(diào)理電路(線性的轉(zhuǎn)換關(guān)系,如根據(jù)一定的轉(zhuǎn)換關(guān)系將-10V10V轉(zhuǎn)換為03.3V),把需要轉(zhuǎn)換的電壓抬升或者降壓到 03.3V,這樣 ADC 就可以測量了

2、輸入通道:每個ADC 有16個外部通道。特別是ADC1還有兩個內(nèi)部 ADC 源 和 V BAT 通道掛在 ADC1上,V BAT 通道也屬于內(nèi)部通道,兩個內(nèi)部 ADC 源沒有對應外部管腳,直接測量內(nèi)部信息。一個連接內(nèi)部溫度傳感器,主要測量CPU以及芯片內(nèi)部的一些關(guān)鍵電路的溫度。另一個連接VREFINT,測量電源模塊的電壓值,V BAT 通道用來測量備用電池的電池容量。

圖片

3、轉(zhuǎn)換順序

a.規(guī)則通道組:顧名思意,規(guī)則通道就是很規(guī)矩的意思,我們平時一般使用的就是這個通道。相當于正常運行的程序,最多16個通道,在使用過程中按順序進行轉(zhuǎn)換,按順序采集完一個通道進行轉(zhuǎn)換后再采集下一個通道進行轉(zhuǎn)換。規(guī)則通道和它的轉(zhuǎn)換順序在ADC_SQRx寄存器中選擇,規(guī)則組轉(zhuǎn)換的總數(shù)應寫入ADC_SQR1寄存器的L[3:0]中。

圖片

圖片

圖片

ADC像這樣的規(guī)則序列寄存器有3個,每個規(guī)則序列寄存器都能設(shè)定第n次轉(zhuǎn)換的具體通道,共有16個外部通道,最多設(shè)置16次。如上圖,規(guī)則序列寄存器3(ADC_SQR3)可以設(shè)定第一次到第六次順序轉(zhuǎn)換的通道,規(guī)則序列寄存器2(ADC_SQR2)可以設(shè)定第七次到第十二次順序轉(zhuǎn)換的通道,規(guī)則序列寄存器1(ADC_SQR1)可以設(shè)定第十三次到第十六次順序轉(zhuǎn)換的通道,且ADC_SQR1寄存器的L[3:0]中(20位到23位)用來設(shè)定要順序轉(zhuǎn)換的通道個數(shù)。例:有如下轉(zhuǎn)換順序要求,有4個通道,第一次轉(zhuǎn)換通道2,第二次轉(zhuǎn)換通道3,第三次轉(zhuǎn)換通道4,第四次轉(zhuǎn)換通道1,則ADC_SQR1寄存器的L[3:0]的值位0100,ADC_SQR3中SQ1的值設(shè)為2,SQ2的值設(shè)為3,SQ3的值設(shè)為4,SQ4的值設(shè)為1。具體的操作在Cube MX中可以配置

b.注入通道組:注入,可以理解為插入,插隊的意思,是一種不安分的通道。相當于中斷。最多4個通道。把某一通道配置位注入通道時,它的優(yōu)先級就比規(guī)則通道高,暫停規(guī)則通道組的工作,優(yōu)先轉(zhuǎn)換注入通道組采集到的信號。注入組和它的轉(zhuǎn)換順序在ADC_JSQR寄存器中選擇。注入組里轉(zhuǎn)化的總數(shù)應寫入ADC_JSQR寄存器的L[1:0]中。該通道組的配置方法于規(guī)則通道組相同。

4、轉(zhuǎn)換時間:ADC 輸入時鐘 ADC_CLK 由 PCLK2 經(jīng)過分頻產(chǎn)生,最大值是 36MHz,即最大工作時鐘不能超過36MHz,典型值為30MHz。對于 STM32F407我們一般設(shè)置PCLK2=HCLK/2=84MHz,最少需要4分頻。所以程序一般使用 4分頻或者 6分頻。

圖片

ADC 的總轉(zhuǎn)換時間Tconv = 采樣時間 + 12個周期(轉(zhuǎn)換時間),采樣時間最少不小于3個ADC_CLK,轉(zhuǎn)換時間一般就是12個ADC_CLK,如果對時間沒有太過苛刻的要求,應當把采樣時間設(shè)置的稍長一些,這樣得到的結(jié)果才會更加準確。最小采樣時間: T =3 + 112= 15個周期=0.42us(ADC時鐘=36MHz下得到)。

圖片

5、數(shù)據(jù)寄存器:規(guī)則數(shù)據(jù)寄存器 ADC_DR

ADC_DR只有一個,是一個32 位的寄存器,只有低 16 位有效并且只是用于獨立模式存放轉(zhuǎn)換完成數(shù)據(jù)。因為 ADC 的最大精度是 12 位,ADC_DR 是16 位有效,這樣允許 ADC存放數(shù)據(jù)時候選擇左對齊或者右對齊,具體是以哪一種方式存放,由 ADC_CR2的 11 位 ALIGN 設(shè)置。對于規(guī)則通道組來說,所有的規(guī)則通道都使用這一個數(shù)據(jù)寄存器,實際采樣點時候,如果開啟了多個通道,每轉(zhuǎn)換完成一個通道要及時把數(shù)據(jù)從寄存器中取走。如果不及時取走,下一次轉(zhuǎn)換完成的數(shù)據(jù)就會覆蓋原數(shù)據(jù)。而對于注入通道組來說,每一個注入通道都對應一個數(shù)據(jù)寄存器。

圖片

使用 DMA:由于規(guī)則通道組只有一個數(shù)據(jù)寄存器,因此,對于多個規(guī)則通道的轉(zhuǎn)換,使用 DMA 非常有幫助。這樣可以避免丟失在下一次寫入之前還未被讀出的 ADC_DR 寄存器中的數(shù)據(jù)。在使能 DMA 模式的情況下(ADC_CR2 寄存器中的 DMA 位置 1),每完成規(guī)則通道組中的一個通道轉(zhuǎn)換后,都會生成一個 DMA 請求。

6、中斷

a.轉(zhuǎn)換結(jié)束中斷:規(guī)則通道和注入通道的數(shù)據(jù)轉(zhuǎn)換結(jié)束后,都可以產(chǎn)生中斷。通道轉(zhuǎn)換完成后,ADC 狀態(tài)寄存器 ADC_SR的EOC位會置1,可以不斷輪詢此位來判斷是否觸發(fā)中斷,也可以使能中斷,完成后就根據(jù)此位的狀態(tài)觸發(fā)中斷。此中斷的使用是最多的,可以在此中斷處理程序中獲取我們想要采集的數(shù)據(jù)。

b.模擬看門狗中斷:當被 ADC 轉(zhuǎn)換的模擬電壓低于低閾值或者高于高閾值時,就會產(chǎn)生中斷

c.溢出中斷:如果發(fā)生 DMA傳輸數(shù)據(jù)丟失,會置位 ADC 狀態(tài)寄存器 ADC_SR的 OVR位,如果同時使能了溢出中斷,那在轉(zhuǎn)換結(jié)束后會產(chǎn)生一個溢出中斷。

d.DMA 請求:規(guī)則和注入通道轉(zhuǎn)換結(jié)束后,除了產(chǎn)生中斷外,還可以產(chǎn)生 DMA請求,把轉(zhuǎn)換好的數(shù)據(jù)直接存儲在內(nèi)存里面。

圖片

7、觸發(fā)源

a.軟件觸發(fā):ADC轉(zhuǎn)換可以由ADC 控制寄存器 2: ADC_CR2的 ADON這個位來控制,寫 1的時候開始轉(zhuǎn)換,寫 0 的時候停止轉(zhuǎn)換。此方法使用最多

b.外部事件觸發(fā):觸發(fā)包括內(nèi)部定時器觸發(fā)和外部 IO觸發(fā)。觸發(fā)源有很多,具體選擇哪一種觸發(fā)源,由 ADC控制寄存器ADC_CR2的 EXTSEL[2:0]和 JEXTSEL[2:0]位來控制

  • ADC的工作模式

單次轉(zhuǎn)換模式:ADC每次工作只轉(zhuǎn)換一次,至于這一次轉(zhuǎn)換幾個通道并不關(guān)心,如果想要再次轉(zhuǎn)換,必須重新啟動ADC。

連續(xù)轉(zhuǎn)換模式:在連續(xù)轉(zhuǎn)換模式下,ADC結(jié)束一個轉(zhuǎn)換后立即啟動一個新的轉(zhuǎn)換,直到用戶想要停止為止。(僅適用于規(guī)則通道)。

掃描模式:該模式主要針對多個通道進行轉(zhuǎn)換。例如使用單次轉(zhuǎn)換模式又開啟掃描模式,從第1個通道開始掃描,掃描第n個通道結(jié)束后不再掃描;如果使用單次轉(zhuǎn)換模式而不開啟掃描模式,這多個通道很有可能只轉(zhuǎn)換第1個通道;使用連續(xù)轉(zhuǎn)換模式又開啟掃描模式,從第1個通道開始掃描,掃描第n個通道結(jié)束后再從第1個通道開始掃描,循環(huán)往復。

不連續(xù)采樣模式:有多個通道需要轉(zhuǎn)換,此模式下一次只轉(zhuǎn)換其中的幾個,這個值n需要用戶自己設(shè)定,假設(shè)有0、1、2、3、6、7、9、10這幾個通道需要轉(zhuǎn)換,n設(shè)置為3,則

圖片

  • STM32ADC單通道采集實例

實驗:利用ADC采集FSM4中電位器的數(shù)據(jù)

說明:電位器本質(zhì)上就是一個滑動變阻器,通過調(diào)節(jié)電阻就可以輸出不同的電壓值,電壓值通過PC3進入ADC的輸入通道。

圖片

步驟:

1.配置RCC,ADC依賴于時鐘APB2

2.配置PC3為ADC1的通道13

圖片

3.配置ADC1

圖片

圖片

4.使能中斷,轉(zhuǎn)換完成觸發(fā)中斷

圖片

5.編寫代碼

//main.c 


uint32_t  adc_value  = 0;//全局變量外部才可以使用 
int main(){    
    HAL_Init();    
    SystemClock_Config();    
    MX_GPIO_Init();    
    MX_ADC1_Init();//ADC1初始化配置,仍然采用結(jié)構(gòu)體元素賦值的形式    
    MX_USART1_UART_Init();        
    while(){        
        /***方法一:輪詢采集ADC的值,也就是輪詢判斷EOC是否置位***/        
        //置位說明轉(zhuǎn)換完成就可以讀值                

        //啟動ADC1,軟件觸發(fā)方式,將對應的啟動位置位        
        HAL_ADC_Start(&hadc1);        
        //HAL_ADC_PollForConversion(&hadc1, 100)該函數(shù)內(nèi)部循環(huán)判斷        
        //EOC是否置位,沒有置位就一直等待,直到超時        
        if( HAL_ADC_PollForConversion(&hadc1, 100) == HAL_OK ){            
            adc_value = HAL_ADC_GetValue(&hadc1);//讀取數(shù)據(jù)寄存器里的值    
            printf("adc_value = %dn",adc_value);                
        }        
        HAL_Delay(1000);//每過1s鐘重新啟動ADC                
        
        
        /***方法二:轉(zhuǎn)換完成后觸發(fā)中斷,在中斷中接收數(shù)值***/        
        HAL_ADC_Start_IT(&hadc1);//啟動ADC1并使能中斷        
        HAL_Delay(1000);//每過1s鐘重新啟動ADC              
    } 
}
//adc.c 
//重寫轉(zhuǎn)換結(jié)束中斷回調(diào)函數(shù),這里對應方法二 


extern uint32_t  adc_value;//全局變量 
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) { 
    if(hadc- >Instance == ADC1) {             
        adc_value = HAL_ADC_GetValue(&hadc1);//讀取數(shù)據(jù)寄存器里的值             
        printf("adc_value = %dn",adc_value); 
    } 
}
  • STM32 ADC多通道采集實例

實驗要求:利用ADC采集電位器及STM32內(nèi)部溫度傳感器的數(shù)據(jù)。

說明:采集內(nèi)部溫度傳感器使用的是內(nèi)部專用通道,選擇通道16或者通道18均可采集內(nèi)部溫度,需要注意的是,實際中多路通道的采集一般使用DMA來進行數(shù)據(jù)的搬移,因為規(guī)則通道的數(shù)據(jù)寄存器只有一個,如果不及時取走數(shù)據(jù),上一次采集的數(shù)據(jù)可能被覆蓋,DMA的知識將在后期進行講解,因此本節(jié)仍采用輪詢的方式查詢標志位,及時將數(shù)據(jù)取出。

圖片

步驟:

1.配置時鐘RCC

2.配置PC3位ADC1的通道13,配置內(nèi)部溫度傳感器通道.

圖片

3.配置ADC

圖片

圖片

4.編寫代碼

//mian.c 


int main(){    
    uint32_t adc_value = 0;    
    uint8_t i;        

    HAL_Init();    
    SystemClock_Config();    
    MX_GPIO_Init();    
    MX_ADC1_Init();    
    MX_USART1_UART_Init();        

    while(){                
        //啟動ADC1,軟件觸發(fā)方式,將對應的啟動位置位        
        HAL_ADC_Start(&hadc1);        
        for(i=0;i< 2;i++){    //使用了幾個通道就應該輪詢幾次            
            //首先采集外部通道電位器的數(shù)值,第二次采集內(nèi)部溫度傳感器的值            
            //HAL_ADC_PollForConversion(&hadc1, 100)該函數(shù)內(nèi)部循環(huán)判斷            
            //EOC是否置位,沒有置位就一直等待,直到超時            
            if( HAL_ADC_PollForConversion(&hadc1, 100) == HAL_OK ){                
                adc_value = HAL_ADC_GetValue(&hadc1);//讀取數(shù)據(jù)寄存器里的值        
                printf("adc_value = %dn",adc_value);                    
            }        
        }        
        HAL_Delay(1000);//每過1s鐘重新啟動ADC              
    }     
}
  • STM32數(shù)據(jù)搬運工DMA專題講解

DMA專門用于數(shù)據(jù)搬運,在開發(fā)中經(jīng)常會遇到外設(shè)與內(nèi)存、內(nèi)存與內(nèi)存進行大量的數(shù)據(jù)交互的情況,這些情況一般都是由CPU進行控制的,如果數(shù)據(jù)交互非常頻繁且數(shù)據(jù)量巨大,那么CPU就會被大量占用用于數(shù)據(jù)交互而無法完成其他工作,為了把CPU從這種單一繁瑣的工作中釋放出來,很多微控制器中都有專門用于數(shù)據(jù)交互的器件,就是DMA。

DMA,全稱為:Direct Memory Access,即直接存儲器訪問。DMA 傳輸方式無需 CPU 直接控制傳輸,也沒有中斷處理方式那樣保留現(xiàn)場和恢復現(xiàn)場的過程,通過硬件RAM 與 I/O 設(shè)備開辟一條直接傳送數(shù)據(jù)的通路,無需CPU的參與,CPU將這條通路的控制權(quán)釋放,轉(zhuǎn)交由DMA控制器控制,能使 CPU 的效率大為提高。DMA控制器只用于數(shù)據(jù)交互,無其他功能。

圖片

  • STM32F4-DMA功能框圖分析

圖片

①外設(shè)通道:STM32F4xx 系列資源豐富,具有兩個 DMA 控制器,同時外設(shè)繁多,為實現(xiàn)正常傳輸,DMA需要通道選擇控制。每個 DMA控制器具有 8個數(shù)據(jù)流,每個數(shù)據(jù)流對應 8個外設(shè)請求。

外設(shè)通道選擇要解決的主要問題是決定哪一個外設(shè)作為該數(shù)據(jù)流的源地址或者目標地址。宏觀上一個數(shù)據(jù)流的所有通道可以同時工作,微觀上通道異步前進進行工作,或者根據(jù)通道優(yōu)先級進行工作

DMA1外設(shè)通道表如下:

圖片

DMA2外設(shè)通道表如下:

圖片

每個數(shù)據(jù)流都與一個 DMA 請求相關(guān)聯(lián),此 DMA 請求可以從 8 個可能的通道請求中選出。此選擇由 DMA_SxCR 寄存器中的 CHSEL[2:0] 位控制,3位用來控制8個通道的選擇。

②數(shù)據(jù)流仲裁:一個 DMA控制器對應 8個數(shù)據(jù)流,數(shù)據(jù)流包含要傳輸數(shù)據(jù)的源地址、目標地址、數(shù)據(jù)長度等等信息。如果我們需要同時使用同一個DMA 控制器(DMA1 或 DMA2)多個外設(shè)請求時,那必然需要同時使用多個數(shù)據(jù)流,那究竟哪一個數(shù)據(jù)流具有優(yōu)先傳輸?shù)臋?quán)利呢?這就需要仲裁器來管理判斷

每個數(shù)據(jù)流的優(yōu)先級都可以通過配置 DMA_SxCR寄存器 PL[1:0]位,設(shè)置為非常高、高、中和低四個級別,由于8個數(shù)據(jù)流只有4個優(yōu)先級,如果兩個或以上數(shù)據(jù)流軟件設(shè)置優(yōu)先級一樣,則他們優(yōu)先級取決于數(shù)據(jù)流編號,編號越低越具有優(yōu)先權(quán)。

③數(shù)據(jù)FIFO:每個數(shù)據(jù)流都有一個獨立的 4 字 FIFO(先進先出存儲器緩沖區(qū)), DMA傳輸具有 FIFO模式和直接模式。

a.直接模式:每個 DMA 請求會立即啟動對存儲器的傳輸。當在直接模式(禁止 FIFO)下將 DMA請求配置為以存儲器到外設(shè)模式傳輸數(shù)據(jù)時,DMA 僅會將一個數(shù)據(jù)從存儲器預加載到內(nèi)部 FIFO,從而確保一旦外設(shè)觸發(fā) DMA 請求時則立即傳輸數(shù)據(jù)。

b.FIFO模式:可通過控制寄存器 DMA_SxFCR 的 FTH[1:0]位來設(shè)置FIFO 閾值級別為 FIFO 大小的 1/4、1/2 或 3/4。如果數(shù)據(jù)存儲量達到閾值級別時,F(xiàn)IFO 內(nèi)容將傳輸?shù)侥繕酥?。如果對傳輸速度要求不是很苛刻,建議使用此模式、直接模式傳輸效率太低,一次傳輸?shù)臄?shù)據(jù)量少而工作量大。

④存儲器端口:DMA 控制器提供兩個 AHB 主端口,分別為AHB 存儲器端口(用于連接存儲器)和 AHB 外設(shè)端口(用于連接外設(shè))。存儲器端口用來連接外部存儲器,實現(xiàn)內(nèi)存與外存的數(shù)據(jù)交互。

⑤外設(shè)端口:用于連接外設(shè),實現(xiàn)內(nèi)存與外設(shè)的數(shù)據(jù)交互.

注意:DMA1 控制器 AHB 外設(shè)端口與 DMA2 控制器的情況不同,DMA1 控制器 AHB 外設(shè)端口沒有連接到總線矩陣,因此,僅 DMA2 數(shù)據(jù)流能夠執(zhí)行存儲器到存儲器的傳輸,DMA1 不能實現(xiàn)存儲器到存儲器傳輸。

  • STM32F4-DMA傳輸

1.傳輸模式 :DMA1 只有外設(shè)到存儲器和存儲器到外設(shè)兩種模式,DMA2 除前面兩種傳輸模式外還支持存儲器到存儲器的傳輸模式。模式選擇可以通過 DMA_SxCR 寄存器的 DIR[1:0]位(方向選擇,規(guī)定誰是源,誰是目的)進行控制。

圖片

2.DMA傳輸模式的源、目的、長度:

a.DMA_SxPAR寄存器: 設(shè)置外設(shè)寄存器地址

b.DMA_SxM0AR寄存器:設(shè)置存儲器地址

c.DMA_SxCR 寄存器 :DIR[1:0]位配置數(shù)據(jù)的傳輸方向

d.DMA_CNDTRx 寄存器:寫入需要傳輸?shù)臄?shù)據(jù)量, (0 到 65535),注意是數(shù)據(jù)的一個量,單位并不是字節(jié)

e.DMA_SxCR 寄存器中的 PSIZE 和 MSIZE 位:設(shè)置源和目的的數(shù)據(jù)寬度,兩邊的位寬盡量保持一致,位寬只一次傳輸多大的位寬(如一次傳輸2字節(jié),位寬16位),如果不能保持位寬,很有可能造成數(shù)據(jù)丟失,應當開啟FIFO模式,保證數(shù)據(jù)不丟失。

3.DMA增量設(shè)置:

a.根據(jù)設(shè)置 DMA_SxCR 寄存器中 PINC 和 MINC 位的狀態(tài),外設(shè)和存儲器指針在每次傳輸后可以自動向后遞增或保持常量。

b.當設(shè)置為增量模式時,下一個要傳輸?shù)牡刂穼⑹乔耙粋€地址加上增量值,增量值取決與所選的數(shù)據(jù)寬度為1字節(jié)(8位) 、2 字節(jié)(16位)或 4字節(jié)(32位) 。如果不啟動,每一次取很有可能只取首地址對應數(shù)據(jù),而不會向后取值。

c.一般情況下外設(shè)并不需要遞增,每一次都是同一個地址,要不要配置外設(shè)的增量模式依具體情況而定。

圖片

4.DMA循環(huán)模式:

a.循環(huán)模式用于處理循環(huán)緩沖區(qū)和連續(xù)的數(shù)據(jù)傳輸 ( 如 ADC 的連續(xù)循環(huán)掃描模式 ) ??梢允褂?DMA_SxCR 寄存器中的 CIRC 位使能此特性。

b.當啟動了循環(huán)模式,一組的數(shù)據(jù)傳輸完成時,計數(shù)寄存器將會自動地被恢復成配置該通道時設(shè)置的初值, DMA 操作將會繼續(xù)進行。

5.DMA單次傳輸和突發(fā)傳輸:

a.DMA傳輸類型有單次(Single)傳輸和突發(fā)(Burst)傳輸。DMA 控制器可以產(chǎn)生單次傳輸或 4 個、8 個和 16 個節(jié)拍的增量突發(fā)傳輸。一個節(jié)拍對應著用戶配置的一個數(shù)據(jù)寬度,一般突發(fā)傳輸要配合FIFO來使用,突發(fā)傳輸?shù)臄?shù)據(jù)量不可能超過FIFO的大小

b.突發(fā)大小通過軟件針對兩個 AHB 端口獨立配置,配置時使用 DMA_SxCR 寄存器中的MBURST[1:0] 和 PBURST[1:0] 位。

c.為確保數(shù)據(jù)一致性,形成突發(fā)的每一組傳輸都不可分割:在突發(fā)傳輸序列期間,AHB 傳輸會鎖定,并且 AHB 總線矩陣的仲裁器不解除對 DMA 主總線的授權(quán)。

圖片

6.DMA中斷: 對于每個 DMA 數(shù)據(jù)流,可在達到半傳輸、傳輸完成、傳輸錯誤、FIFO 錯誤(上溢、下溢或 FIFO 級別錯誤)、直接模式錯誤時產(chǎn)生中斷。這些標志位都在中斷狀態(tài)寄存器DMA_xISR中設(shè)置。

圖片

  • ADC_DMA多路采集實例

實驗要求:利用ADC采集電位器以及芯片內(nèi)部溫度傳感器的數(shù)據(jù),在main函數(shù)中啟動ADC轉(zhuǎn)換以及DMA傳輸,最后在DMA完成中斷中打印采集到的數(shù)據(jù)。

說明:之前使用ADC采集兩路數(shù)據(jù)是使用輪詢的方式判斷采集,需要CPU一直去判斷,消耗CPU資源,顯然這并不是ADC多路采集最好的辦法,ADC多路采集一般使用DMA來進行傳輸,規(guī)則通道組采集數(shù)據(jù)時只有一個數(shù)據(jù)寄存器ADC_DR,讀取數(shù)據(jù)不及時很有可能發(fā)生數(shù)據(jù)覆蓋。

采用DMA傳輸,每當一路數(shù)據(jù)采集完成后都會產(chǎn)生一個DMA請求,及時把數(shù)據(jù)寄存器中的值搬移到內(nèi)存中相應的buffer中去

步驟:

1.配置RCC

2.配置PC3位ADC1的通道13,配置內(nèi)部溫度傳感器通道

圖片

3.配置DMA

圖片

4.配置ADC

圖片

圖片

5.配置中斷

圖片

5.編寫代碼

//main.c 


uint16_t adc_value[2] = {0};//定義一個全局的接受區(qū)域,以便外部調(diào)用   
int mian(){    
    HAL_Init();    
    SystemClock_Config();        
    MX_GPIO_Init();    
    MX_DMA_Init();    
    MX_USART1_UART_Init();    
    MX_ADC1_Init();        
    printf("this is adc dma testn");        
    while(1){        
        //此函數(shù)既啟動ADC,又使能DMA        
        HAL_ADC_Start_DMA(&hadc1, (uint32_t*) adc_value, 2);        
        //2表示傳輸了2個數(shù)據(jù)的量,一個量是我們設(shè)定的位寬        
        //內(nèi)部有一個專門的寄存器來記錄這個量,每傳輸完成一次,寄存器的值減1        
        //減到0就會觸發(fā)DMA的傳輸完成中斷        
        HAL_Delay(1000); //每過1s啟動一次      
    } 
}

關(guān)于DMA傳輸完成中斷處理函數(shù)是哪一個,先將函數(shù)HAL_ADC_Start_DMA(&hadc1, (uint32_t*) adc_value, 2);追進去可以看到一段代碼設(shè)置了DMA傳輸完成的回調(diào)函數(shù),將這個函數(shù)賦給了一個指針,這個指針是DMA_Handle下的一個指針,DMA可以用于很多的外設(shè),不同的外設(shè)的轉(zhuǎn)換完成函數(shù)是不一樣的,DMA沒有一個固定的處理函數(shù),這個函數(shù)需要在外設(shè)配置的時候自己去初始化,DMA只提供一個接口,一個傳輸轉(zhuǎn)換完成的函數(shù)指針,不同的外設(shè)對這個結(jié)構(gòu)賦不同的處理函數(shù)的指針,這里對ADC來說自己封裝了一個DMA傳輸完成處理中斷的函數(shù),當DMA傳輸完成中斷觸發(fā)的時候自己去調(diào)用這個接口下的對應的函數(shù)。ConvCplt的意思是ConverseComplete

圖片

將void DMA2_Stream0_IRQHandler(void)這個中斷處理函數(shù)入口追進去可以看到DMA有各種不同的中斷處理請求,我們在傳輸完成中斷***Transfer Complete Interrupt management***這一部分里可以看到hdma->XferCpltCallback(hdma);這樣一個指針函數(shù),但是用戶無法使用這個指針函數(shù),這個指針在HAL_ADC_Start_DMA(&hadc1, (uint32_t*) 這個函數(shù)中已經(jīng)賦值,實際上這個函數(shù)最終進入了HAL_ADC_ConvCpltCallback函數(shù),也就是ADC傳輸完成函數(shù)。

圖片

//adc.c 
extern uint16_t adc_value[2] ; 
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) {    
    //每一次采集完成后都會將數(shù)據(jù)傳輸?shù)剑觯幔欤酰逯?   
    if(hadc- >Instance == ADC1) { 
        printf("adc_value[0]=%d, adc_value[1]=%dn",adc_value[0],adc_value[1]);    
    } 
}
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • dma
    dma
    +關(guān)注

    關(guān)注

    3

    文章

    555

    瀏覽量

    100220
  • STM32F4
    +關(guān)注

    關(guān)注

    3

    文章

    194

    瀏覽量

    27950
  • 模擬數(shù)字轉(zhuǎn)換器

    關(guān)注

    1

    文章

    74

    瀏覽量

    12449
  • ADC采樣電壓
    +關(guān)注

    關(guān)注

    0

    文章

    4

    瀏覽量

    2806
  • 信號采集傳感器
    +關(guān)注

    關(guān)注

    0

    文章

    2

    瀏覽量

    1225
收藏 人收藏

    評論

    相關(guān)推薦

    DMA傳輸打印ADC采集數(shù)據(jù)ADC采集直接打印數(shù)據(jù)不同,為什么?如何排查?

    現(xiàn)在發(fā)現(xiàn)利用DMAADC采集數(shù)據(jù)傳入數(shù)組打印與直接將ADC采集
    發(fā)表于 03-19 07:39

    STM32單ADC,多通道及DMA傳輸?shù)亩嗦?b class='flag-5'>數(shù)據(jù)采集程序介紹

    STM32 單ADC,多通道,DMA傳輸?shù)亩嗦?b class='flag-5'>數(shù)據(jù)采集
    發(fā)表于 06-14 10:11

    利用ADC技術(shù)的MCU系統(tǒng)數(shù)據(jù)采集

    數(shù)據(jù)采集系統(tǒng)的捕獲階段。捕獲復雜的混合信號MCU必須能夠從模擬世界中捕獲某些有用信息,并且能夠把連續(xù)時間信號轉(zhuǎn)換成離散的數(shù)字形式。模數(shù)轉(zhuǎn)換器(ADC)是完成這項任務(wù)最重要的MCU外設(shè),因此ADC的性能往往
    發(fā)表于 07-05 06:21

    Stm32的ADCDMA功能

    時間進行ADC轉(zhuǎn)換,這樣每次都必須讀ADC數(shù)據(jù)寄存器,非常浪費時間! 2)把ADC設(shè)置成連續(xù)轉(zhuǎn)換模式,同時對應的DMA通道開啟循環(huán)模式,這
    發(fā)表于 08-19 07:02

    怎么實現(xiàn)多通道ADC通過DMA數(shù)據(jù)采集?

    怎么實現(xiàn)多通道ADC通過DMA數(shù)據(jù)采集?
    發(fā)表于 11-18 06:46

    ADC數(shù)據(jù)采集的應用

    摘要本文章基于國信長天M4開發(fā)板,講述了ADC數(shù)據(jù)采集的應用,祝各位學生藍橋杯比賽取得好成績!M4開發(fā)板 ADC部分原理圖又上圖可以看出,開發(fā)板上有兩個可調(diào)電阻R37, R38,分別連接到PB15
    發(fā)表于 01-06 06:12

    雙通道ADC采集的相關(guān)資料分享

    一、準備工作[PA4->AO1]、[PA5->AO2] 轉(zhuǎn)動RP5、RP6可觀察到測得AD值變化二、原理圖關(guān)于ADC采集詳解,參考“STM32-AD
    發(fā)表于 01-11 08:01

    ADC工作原理與選型

    目錄1,淺談常用ADC工作原理與選型!2,ADC的選型(技術(shù)指標)3 轉(zhuǎn)換速率(Conversion Rate):1,淺談常用ADC
    發(fā)表于 01-13 06:36

    lvds 接口的ADC數(shù)據(jù)采集

    這是ADC的lvds時序圖,目前遇到的問題時,我用一片Artix-7系列fpga同時采集4篇上述的ADC值,單片adc數(shù)據(jù)采集是正常的,多篇
    發(fā)表于 04-17 15:28

    ADC—單通道(DMA

    程序簡介 -工程名稱:ADC單通道(DMA) -實驗平臺: 秉火STM32 F429 開發(fā)板 -MDK版本:5.16 -ST固件庫版本:1.5.1 【 !】功能簡介: 使用ADC采集
    發(fā)表于 12-13 15:25 ?8次下載
    <b class='flag-5'>ADC</b>—單通道(<b class='flag-5'>DMA</b>)

    ADC—單通道(NO DMA

    程序簡介 -工程名稱:ADC單通道(NO DMA) -實驗平臺: 秉火STM32 F429 開發(fā)板 -MDK版本:5.16 -ST固件庫版本:1.5.1 【 !】功能簡介: 使用ADC采集
    發(fā)表于 12-13 15:28 ?10次下載
    <b class='flag-5'>ADC</b>—單通道(NO <b class='flag-5'>DMA</b>)

    ADC—多通道(DMA

    程序簡介 -工程名稱:ADC多通道(DMA) -實驗平臺: 秉火STM32 F429 開發(fā)板 -MDK版本:5.16 -ST固件庫版本:1.5.1 【 !】功能簡介: 使用ADC采集
    發(fā)表于 12-13 15:31 ?33次下載
    <b class='flag-5'>ADC</b>—多通道(<b class='flag-5'>DMA</b>)

    STM32F030 ADC DMA亂序問題

    問題描述通過 uint16_t ConvData[8]保存DMA搬運的ADC轉(zhuǎn)換數(shù)值,但是這個數(shù)組數(shù)值的順序總是和ADC不是順序?qū)摹1热缬?個通道的ADC,當設(shè)置
    發(fā)表于 06-09 15:18 ?1457次閱讀

    基于STM32單片機ADC連續(xù)采集DMA循環(huán)轉(zhuǎn)換

    描述:用ADC連續(xù)采集11路模擬信號,并由DMA傳輸?shù)絻?nèi)存。ADC配置為掃描并且連續(xù)轉(zhuǎn)換模式,ADC的時鐘配置為12MHZ。在每次轉(zhuǎn)換結(jié)束后
    發(fā)表于 10-22 15:28 ?1.9w次閱讀

    stm32g030多路adc DMA采集程序

    stm32g030_多路adc_DMA采集程序
    發(fā)表于 06-19 09:43 ?28次下載