版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第13章
直接存儲(chǔ)器訪問(wèn)作者:黃克亞2025年5月本章概要CONTENTS直接存儲(chǔ)器訪問(wèn)的基本概念STM32F103的DMA相關(guān)庫(kù)函數(shù)STM32F103的DMA工作原理ADC+DMA+USART項(xiàng)目實(shí)施13.1DMA的基本概念直接存儲(chǔ)器訪問(wèn)(DirectMemoryAccess,DMA)是計(jì)算機(jī)系統(tǒng)中用于快速、大量數(shù)據(jù)交換的重要技術(shù)。13.1DMA的基本概念13.1.1DMA由來(lái)一個(gè)完整的微控制器就像一臺(tái)集成在一塊芯片上的計(jì)算機(jī)系統(tǒng),通常包括CPU、存儲(chǔ)器和外部設(shè)備等部件。這些相互獨(dú)立的各個(gè)部件在CPU的協(xié)調(diào)和交互下協(xié)同工作。作為微控制器的大腦,CPU的相當(dāng)一部分工作被數(shù)據(jù)傳輸占據(jù)了。所以我們希望,CPU能從簡(jiǎn)單頻繁的“數(shù)據(jù)搬運(yùn)”工作中擺脫出來(lái),去處理那些更重要(運(yùn)算控制)、更緊急(實(shí)時(shí)響應(yīng))的事情,而把“數(shù)據(jù)搬運(yùn)”交給專門的部件去完成,就像第9章中講述的,CPU把“計(jì)數(shù)”操作交給定時(shí)器完成一樣,于是DMA和DMA控制器就應(yīng)運(yùn)而生了。單片機(jī)CPU存儲(chǔ)器外設(shè)13.1DMA的基本概念13.1.2DMA定義DMA是一種完全由硬件執(zhí)行數(shù)據(jù)交換的工作方式。它由DMA控制器而不是CPU控制在存儲(chǔ)器和存儲(chǔ)器、存儲(chǔ)器和外設(shè)之間的批量數(shù)據(jù)傳輸。一般來(lái)說(shuō),一個(gè)DMA控制器有若干條數(shù)據(jù)傳輸鏈路,稱為DMA流,每條鏈路連接多個(gè)外設(shè)。這些連接在同一DMA流上的多個(gè)外設(shè)可以分時(shí)復(fù)用這條DMA傳輸鏈路。但同一時(shí)刻,一條DMA傳輸鏈路上只能有一個(gè)外設(shè)進(jìn)行DMA數(shù)據(jù)傳輸。外設(shè)CPU存儲(chǔ)器DMA13.1DMA的基本概念13.1.3DMA傳輸過(guò)程CPU對(duì)DMA控制器初始化,并向外設(shè)發(fā)出操作命令,外設(shè)提出DMA請(qǐng)求。(1)DMA請(qǐng)求DMA控制器對(duì)DMA請(qǐng)求判別優(yōu)先級(jí)及屏蔽,向總線裁決邏輯提出總線請(qǐng)求。(2)DMA響應(yīng)DMA控制器獲得總線控制權(quán)后,CPU即刻掛起或只執(zhí)行內(nèi)部操作,由DMA控制器輸出讀寫命令,直接控制存儲(chǔ)器與外設(shè)進(jìn)行DMA傳輸。(3)DMA傳輸當(dāng)完成規(guī)定的成批數(shù)據(jù)傳送后,DMA控制器即釋放總線控制權(quán),并向外設(shè)發(fā)出結(jié)束信號(hào)。(4)DMA結(jié)束13.1DMA的基本概念13.1.4DMA優(yōu)點(diǎn)降低了CPU的負(fù)擔(dān),釋放了CPU的資源,使得CPU的使用效率大大提高。顯著地提高了數(shù)據(jù)傳輸?shù)男剩軡M足高速I/O設(shè)備的要求。因?yàn)椴恍枰虚g變量減少用戶軟件開(kāi)發(fā)的代碼量,程序變得更加簡(jiǎn)潔,編程效率得以提高由硬件直接實(shí)現(xiàn)因?yàn)椴恍枰狢PU干預(yù)13.2STM32F103的
DMA工作原理STM32F103微控制器有兩個(gè)DMA控制器,其共有12個(gè)通道(DMA1有7個(gè)通道,DMA2有5個(gè)通道),每個(gè)通道專門用來(lái)管理來(lái)自于一個(gè)或多個(gè)外設(shè)對(duì)存儲(chǔ)器訪問(wèn)的請(qǐng)求。還有一個(gè)仲裁器來(lái)協(xié)調(diào)各個(gè)DMA請(qǐng)求的優(yōu)先權(quán)。13.2STM32F103的DMA工作原理13.2.1STM32F103的DMA主要特性
12個(gè)獨(dú)立的可配置的通道(請(qǐng)求):DMA1有7個(gè)通道,DMA2有5個(gè)通道每個(gè)通道都直接連接專用的硬件DMA請(qǐng)求,每個(gè)通道都同樣支持軟件觸發(fā)。這些功能通過(guò)軟件來(lái)配置。在同一個(gè)DMA模塊上,多個(gè)請(qǐng)求間的優(yōu)先權(quán)可以通過(guò)軟件編程設(shè)置(共有四級(jí):很高、高、中等和低),優(yōu)先權(quán)設(shè)置相等時(shí)由硬件決定(請(qǐng)求0優(yōu)先于請(qǐng)求1,依此類推)。獨(dú)立數(shù)據(jù)源和目標(biāo)數(shù)據(jù)區(qū)的傳輸寬度(字節(jié)、半字、全字),模擬打包和拆包的過(guò)程。源和目標(biāo)地址必須按數(shù)據(jù)傳輸寬度對(duì)齊。支持循環(huán)的緩沖器管理每個(gè)通道都有3個(gè)事件標(biāo)志(DMA半傳輸、DMA傳輸完成和DMA傳輸出錯(cuò)),這3個(gè)事件標(biāo)志邏輯或成為一個(gè)單獨(dú)的中斷請(qǐng)求。支持存儲(chǔ)器和存儲(chǔ)器、外設(shè)和存儲(chǔ)器、存儲(chǔ)器和外設(shè)之間的傳輸閃存、SRAM、外設(shè)的SRAM、APB1、APB2和AHB外設(shè)均可作為訪問(wèn)的源和目標(biāo)。可編程的數(shù)據(jù)傳輸數(shù)目:最大為6553513.2STM32F103的DMA工作原理13.2.2STM32F103的DMA內(nèi)部結(jié)構(gòu)DMA控制器和Cortex-M3核心共享系統(tǒng)數(shù)據(jù)總線,執(zhí)行直接存儲(chǔ)器數(shù)據(jù)傳輸。當(dāng)CPU和DMA同時(shí)訪問(wèn)相同的目標(biāo)(RAM或外設(shè))時(shí),DMA請(qǐng)求會(huì)暫停CPU訪問(wèn)系統(tǒng)總線達(dá)若干個(gè)周期,總線仲裁器執(zhí)行循環(huán)調(diào)度,以保證CPU至少可以得到一半的系統(tǒng)總線(存儲(chǔ)器或外設(shè))帶寬13.2STM32F103的DMA工作原理13.2.3STM32F103的DMA通道DMA1通道:01外設(shè)通道1通道2通道3通道4通道5通道6通道7ADC1ADC1SPI/I2S
SPI1_RXSPI1_TXSPI/I2S2_RXSPI/I2S2_TX
USART
USART3_TXUSART3_RXUSART1_TXUSART1_RXUSART2_RXUSART2_TXI2C
I2C2_TXI2C2_RXI2C1_TXI2C1_RXTIM1
TIM1_CH1TIM1_CH2TIM1_TX4TIM1_TRIGTIM1_COMTIM1_UPTIM1_CH3
TIM2TIM2_CH3TIM2_UP
TIM2_CH1
TIM2_CH2TIM2_CH4TIM3
TIM3_CH3TIM3_CH4TIM3_UP
TIM3_CH1TIM3_TRIG
TIM4TIM4_CH4
TIM4_CH2TIM4_CH3
TIM4_UPSTM32F103的DMA1有7個(gè)觸發(fā)通道,可以分別從外設(shè)(TIMx[x=1、2、3、4]、ADC1、SPI1、SPI/I2S2、I2Cx[x=1、2]和USARTx[x=1、2、3])產(chǎn)生的7個(gè)訪問(wèn)請(qǐng)求,通過(guò)邏輯或輸入到DMA1控制器,這意味著同時(shí)只能有一個(gè)請(qǐng)求有效。13.2STM32F103的DMA工作原理13.2.3STM32F103的DMA通道DMA2通道:02外設(shè)通道1通道2通道3通道4通道5ADC3ADC3SPI/I2S3SPI/I2S3_RXSPI/I2S3_TXUART4UART4_RXUART4_TXSDIO(1)SDIOTIM5TIM5_CH4TIM5_TRIGTIM5_CH3TIM5_UPTIM5_CH2TIM5_CH1TIM6/DAC通道1TIM6_UP/DAC通道1TIM7/DAC通道2TIM7_UP/DAC通道2TIM8(1)TIM8_CH3TIM8_UPTIM8_CH4TIM8_TRIGTIM8_COMTIM8_CH1TIM8_CH2DMA2控制器及相關(guān)請(qǐng)求僅存在于大容量STM32F103和互聯(lián)型的STM32F105、STM32F107系列產(chǎn)品中。它有5個(gè)觸發(fā)通道,可以分別從外設(shè)(TIMx[5、6、7、8]、ADC3、SPI/I2S3、UART4、DAC通道1、2和SDIO)產(chǎn)生的5個(gè)請(qǐng)求,經(jīng)邏輯或輸入到DMA2控制器,這意味著同時(shí)只能有一個(gè)請(qǐng)求有效。13.2STM32F103的DMA工作原理13.2.4STM32F103的DMA優(yōu)先級(jí)優(yōu)先權(quán)管理軟件優(yōu)先級(jí)每個(gè)通道的優(yōu)先權(quán)可以在DMA_CCRx寄存器中設(shè)置最高優(yōu)先級(jí)高優(yōu)先級(jí)中等優(yōu)先級(jí)低優(yōu)先級(jí)硬件優(yōu)先級(jí)如果2個(gè)請(qǐng)求有相同的軟件優(yōu)先級(jí),則較低編號(hào)的通道比較高編號(hào)的通道有較高的優(yōu)先權(quán)13.2STM32F103的DMA工作原理13.2.5STM32F103的DMA傳輸模式01普通模式是指在DMA傳輸結(jié)束時(shí),DMA通道被自動(dòng)關(guān)閉,進(jìn)一步的DMA請(qǐng)求將不被響應(yīng)。普通模式02循環(huán)模式用于處理一個(gè)環(huán)形的緩沖區(qū),每輪傳輸結(jié)束時(shí)數(shù)據(jù)傳輸?shù)呐渲脮?huì)自動(dòng)地更新為初始狀態(tài),DMA傳輸會(huì)連續(xù)不斷地進(jìn)行。循環(huán)模式13.2STM32F103的DMA工作原理13.2.6STM32F103的DMA中斷每個(gè)DMA通道都可以在DMA傳輸過(guò)半、傳輸完成和傳輸錯(cuò)誤時(shí)產(chǎn)生中斷。為應(yīng)用的靈活性考慮,通過(guò)設(shè)置寄存器的不同位來(lái)打開(kāi)這些中斷。中斷事件事件標(biāo)志位使能控制位傳輸過(guò)半HTIFHTIE傳輸完成TCIFTCIE傳輸錯(cuò)誤TEIFTEIE13.3DMA相關(guān)庫(kù)函數(shù)本節(jié)重點(diǎn)介紹DMA相關(guān)庫(kù)函數(shù)名稱和功能,應(yīng)用方法會(huì)結(jié)合項(xiàng)目實(shí)例詳細(xì)講解。13.3DMA相關(guān)庫(kù)函數(shù)13.3.1函數(shù)DMA_DeInit函數(shù)名DMA_DeInit函數(shù)原形voidDMA_DeInit(DMA_Channel_TypeDef*DMAy_Channelx)功能描述DMAy_Channelx寄存器重設(shè)為缺省值輸入?yún)?shù)DMAy_Channelx:DMAy的通道x其中y可以是1或2對(duì)于DMA1,x可以是1~7,對(duì)于DMA2,x可以是1~5輸出參數(shù)無(wú)返回值無(wú)例:/*DeinitializetheDMA1Channel2*/DMA_DeInit(DMA1_Channel2);13.3DMA相關(guān)庫(kù)函數(shù)13.3.2函數(shù)DMA_Init函數(shù)名DMA_Init函數(shù)原形voidDMA_Init(DMA_Channel_TypeDef*DMAy_Channelx,DMA_InitTypeDef*DMA_InitStruct)功能描述根據(jù)DMA_InitStruct中指定的參數(shù)初始化DMAy的通道x寄存器輸入?yún)?shù)1DMAy_Channelx:DMAy的通道x其中y可以是1或2對(duì)于DMA1,x可以是1~7,對(duì)于DMA2,x可以是1~5輸入?yún)?shù)2DMA_InitStruct:指向結(jié)構(gòu)DMA_InitTypeDef的指針,包含了DMAy通道x的配置信息輸出參數(shù)無(wú)返回值無(wú)DMA_PeripheralBaseAddr:該參數(shù)用以定義DMA外設(shè)基地址DMA_MemoryBaseAddr:該參數(shù)用以定義DMA內(nèi)存基地址DMA_InitTypeDefstructureDMA_InitTypeDef定義于文件“stm32f10x_dma.h”:typedefstruct{u32DMA_PeripheralBaseAddr;u32DMA_MemoryBaseAddr;u32DMA_DIR;u32DMA_BufferSize;u32DMA_PeripheralInc;u32DMA_MemoryInc;u32DMA_PeripheralDataSize;u32DMA_MemoryDataSize;u32DMA_Mode;u32DMA_Priority;u32DMA_M2M;}DMA_InitTypeDef;13.3DMA相關(guān)庫(kù)函數(shù)13.3.2函數(shù)DMA_InitDMA_DIR:DMA_DIR規(guī)定了外設(shè)是作為數(shù)據(jù)傳輸?shù)哪康牡剡€是來(lái)源DMA_DIR描述DMA_DIR_PeripheralDST外設(shè)作為數(shù)據(jù)傳輸?shù)哪康牡谼MA_DIR_PeripheralSRC外設(shè)作為數(shù)據(jù)傳輸?shù)膩?lái)源DMA_BufferSize:
用以定義指定DMA通道的DMA緩存的大小,單位為數(shù)據(jù)單位。根據(jù)傳輸方向,數(shù)據(jù)單位等于結(jié)構(gòu)中參數(shù)DMA_PeripheralDataSize或者參數(shù)DMA_MemoryDataSize的值。DMA_PeripheralInc:用來(lái)設(shè)定外設(shè)地址寄存器遞增與否DMA_PeripheralDataSize:設(shè)定了外設(shè)數(shù)據(jù)寬度DMA_PeripheralInc描述DMA_PeripheralInc_Enable外設(shè)地址寄存器遞增DMA_PeripheralInc_Disable外設(shè)地址寄存器不變DMA_PeripheralDataSize描述DMA_PeripheralDataSize_Byte數(shù)據(jù)寬度為8位DMA_PeripheralDataSize_HalfWord數(shù)據(jù)寬度為16位DMA_PeripheralDataSize_Word數(shù)據(jù)寬度為32位13.3DMA相關(guān)庫(kù)函數(shù)13.3.2函數(shù)DMA_InitDMA_MemoryDataSize:設(shè)定了外設(shè)數(shù)據(jù)寬度。DMA_MemoryDataSize描述DMA_MemoryDataSize_Byte數(shù)據(jù)寬度為8位DMA_MemoryDataSize_HalfWord數(shù)據(jù)寬度為16位DMA_MemoryDataSize_Word數(shù)據(jù)寬度為32位DMA_Mode:設(shè)置了CAN的工作模式DMA_Priority:設(shè)定DMA通道x的軟件優(yōu)先級(jí)DMA_Mode描述DMA_Mode_Circular工作在循環(huán)緩存模式DMA_Mode_Normal工作在正常緩存模式DMA_Mode描述DMA_Priority_VeryHighDMA通道x擁有非常高優(yōu)先級(jí)DMA_Priority_HighDMA通道x擁有高優(yōu)先級(jí)DMA_Priority_MediumDMA通道x擁有中優(yōu)先級(jí)DMA_Priority_LowDMA通道x擁有低優(yōu)先級(jí)注意:當(dāng)指定DMA通道數(shù)據(jù)傳輸配置為內(nèi)存到內(nèi)存時(shí),不能使用循環(huán)緩存模式。13.3DMA相關(guān)庫(kù)函數(shù)13.3.2函數(shù)DMA_InitDMA_M2M:使能DMA通道的內(nèi)存到內(nèi)存?zhèn)鬏擠MA_M2M描述DMA_M2M_EnableDMA通道x設(shè)置為內(nèi)存到內(nèi)存?zhèn)鬏擠MA_M2M_DisableDMA通道x沒(méi)有設(shè)置為內(nèi)存到內(nèi)存?zhèn)鬏斃?*InitializetheDMA1Channel1accordingtotheDMA_InitStructuremembers*/DMA_InitTypeDefDMA_InitStructure;DMA_InitStructure.DMA_PeripheralBaseAddr=0x40005400;DMA_InitStructure.DMA_MemoryBaseAddr=0x20000100;DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;DMA_InitStructure.DMA_BufferSize=256;DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord;DMA_InitStructure.DMA_Mode=DMA_Mode_Normal;DMA_InitStructure.DMA_Priority=DMA_Priority_Medium;DMA_InitStructure.DMA_M2M=DMA_M2M_Disable;DMA_Init(DMA1_Channel1,&DMA_InitStructure);13.3DMA相關(guān)庫(kù)函數(shù)13.3.3函數(shù)DMA_GetCurrDataCounter函數(shù)名DMA_GetCurrDataCounter函數(shù)原形u16DMA_GetCurrDataCounter(DMA_Channel_TypeDef*DMAy_Channelx)功能描述返回當(dāng)前DMAy通道x剩余的待傳輸數(shù)據(jù)數(shù)目輸入?yún)?shù)DMAy_Channelx:選擇DMAy通道x輸出參數(shù)無(wú)返回值當(dāng)前DMA通道x剩余的待傳輸數(shù)據(jù)數(shù)目例:/*GetthenumberofremainingdataunitsinthecurrentDMA1Channel2transfer*/u16CurrDataCount;CurrDataCount=DMA_GetCurrDataCounter(DMA1_Channel2);13.3DMA相關(guān)庫(kù)函數(shù)13.3.4函數(shù)DMA_Cmd函數(shù)名DMA_Cmd函數(shù)原形voidDMA_Cmd(DMA_Channel_TypeDef*DMAy_Channelx,FunctionalStateNewState)功能描述使能或者失能指定的通道x輸入?yún)?shù)1DMAy_Channelx:選擇DMAy通道x輸入?yún)?shù)2NewState:DMA通道x的新?tīng)顟B(tài)
這個(gè)參數(shù)可以取:ENABLE或者DISABLE輸出參數(shù)無(wú)返回值無(wú)例:/*EnableDMA1Channel7*/DMA_Cmd(DMA1_Channel7,ENABLE);13.3DMA相關(guān)庫(kù)函數(shù)13.3.5函數(shù)DMA_GetFlagStatus函數(shù)名
DMA_GetFlagStatus函數(shù)原形
FlagStatusDMA_GetFlagStatus(uint32_tDMAy_FLAG)功能描述
檢查指定的DMAy通道x標(biāo)志位設(shè)置與否輸入?yún)?shù)
DMAy_FLAG:待檢查的DMAy通道x標(biāo)志位參閱Section:DMA_FLAG查閱更多該參數(shù)允許取值范圍輸出參數(shù)
無(wú)返回值
DMA_FLAG的新?tīng)顟B(tài)(SET或者RESET)DMA_M2M:使能DMA通道的內(nèi)存到內(nèi)存?zhèn)鬏擠MA_FLAG描述DMA_FLAG描述DMA1_FLAG_GL1DMA1通道1全局標(biāo)志位DMA1_FLAG_TC2DMA1通道2傳輸完成標(biāo)志位DMA1_FLAG_TC1DMA1通道1傳輸完成標(biāo)志位DMA1_FLAG_HT2DMA1通道2傳輸過(guò)半標(biāo)志位DMA1_FLAG_HT1DMA1通道1傳輸過(guò)半標(biāo)志位DMA1_FLAG_TE2DMA1通道2傳輸錯(cuò)誤標(biāo)志位DMA1_FLAG_TE1DMA1通道1傳輸錯(cuò)誤標(biāo)志位……依次類推……依次類推DMA1_FLAG_GL2DMA1通道2全局標(biāo)志位例:/*TestiftheDMA1Channel6halftransferinterruptflagissetornot*/FlagStatusStatus;Status=DMA_GetFlagStatus(DMA1_FLAG_HT6);13.3DMA相關(guān)庫(kù)函數(shù)13.3.6函數(shù)DMA_ClearFlag函數(shù)名
DMA_ClearFlag函數(shù)原形
voidDMA_ClearFlag(u32DMAy_FLAG)功能描述
清除DMAy通道x待處理標(biāo)志位輸入?yún)?shù)
DMAy_FLAG:待清除的DMA標(biāo)志位,使用操作符“|”可以同時(shí)選中多個(gè)DMA標(biāo)志位輸出參數(shù)
無(wú)返回值
無(wú)例:/*CleartheDMA1Channel3transfererrorinterruptpendingbit*/DMA_ClearFlag(DMA1_FLAG_TE3);13.3DMA相關(guān)庫(kù)函數(shù)13.3.7函數(shù)DMA_ITConfig函數(shù)名
DMA_ITConfig函數(shù)原形
voidDMA_ITConfig(DMA_Channel_TypeDef*DMAy_Channelx,u32DMA_IT,FunctionalStateNewState)功能描述
使能或者失能指定的DMAy通道x中斷輸入?yún)?shù)1DMAy_Channelx:選擇DMAy通道x輸入?yún)?shù)2DMA_IT:待使能或者失能的DMA中斷源,使用操作符“|”可以同時(shí)選中多個(gè)DMA中斷源輸入?yún)?shù)3NewState:DMA通道x中斷的新?tīng)顟B(tài)
這個(gè)參數(shù)可以取:ENABLE或者DISABLEDMA_IT:輸入?yún)?shù)DMA_IT使能或者失能DMAy通道x的中斷。可以取下表的一個(gè)或者多個(gè)取值的組合作為該參數(shù)的值。DMA_IT描述DMA_IT_TC傳輸完成中斷屏蔽DMA_IT_HT傳輸過(guò)半中斷屏蔽DMA_IT_TE傳輸錯(cuò)誤中斷屏蔽例:/*EnableDMA1Channel5completetransferinterrupt*/DMA_ITConfig(DMA1_Channel5,DMA_IT_TC,ENABLE);13.3DMA相關(guān)庫(kù)函數(shù)13.3.8函數(shù)DMA_GetITStatus函數(shù)名
DMA_GetITStatus函數(shù)原形
ITStatusDMA_GetITStatus(uint32_tDMAy_IT)功能描述
檢查指定的DMAy通道x中斷發(fā)生與否輸入?yún)?shù)
DMAy_IT:待檢查的DMAy的通道x中斷源輸出參數(shù)
無(wú)返回值
DMA_IT的新?tīng)顟B(tài)(SET或者RESET)DMAy_IT:參數(shù)DMA_IT定義了待檢察的DMA中斷DMAy_IT描述DMAy_IT描述DMA1_IT_GL1通道1全局中斷DMA1_IT_TC2通道2傳輸完成中斷DMA1_IT_TC1通道1傳輸完成中斷DMA1_IT_HT2通道2傳輸過(guò)半中斷DMA1_IT_HT1通道1傳輸過(guò)半中斷DMA1_IT_TE2通道2傳輸錯(cuò)誤中斷DMA1_IT_TE1通道1傳輸錯(cuò)誤中斷……依次類推……依次類推DMA1_IT_GL2通道2全局中斷例:/*TestiftheDMAChannel7transfercompleteinterrupthasoccurredornot*/ITStatusStatus;Status=DMA_GetITStatus(DMA_IT_TC7);13.4項(xiàng)目實(shí)例本例實(shí)現(xiàn)ADC采集、DMA傳輸、USART顯示綜合應(yīng)用項(xiàng)目。13.4項(xiàng)目實(shí)例13.4.1項(xiàng)目分析本項(xiàng)目需要實(shí)現(xiàn)的功能為在4個(gè)輸入通道采集模擬電壓信號(hào),送ADC1進(jìn)行模數(shù)轉(zhuǎn)換,將轉(zhuǎn)換結(jié)果利用DMA1控制器傳送到內(nèi)存數(shù)組當(dāng)中,并進(jìn)行均值濾波,將濾波后的結(jié)果通過(guò)USART1串口發(fā)送至PC機(jī),PC機(jī)利用串口調(diào)試助手接收并顯示AD轉(zhuǎn)換結(jié)果。所以本項(xiàng)目是“ADC+DMA+USART”,項(xiàng)目綜合性較強(qiáng)。其中ADC部分內(nèi)容同第12章,沒(méi)有大的改變,只要打開(kāi)ADC1的DMA功能即可,在此不作過(guò)多介紹。USART部分內(nèi)容也基本同第10章,但是為了工程通用性,需要重新新建“printf.c”和“printf.h”兩個(gè)文件,并重寫C語(yǔ)言當(dāng)中的printf函數(shù)。DMA傳輸是本章新講授的內(nèi)容,要使用DMA控制器需要打開(kāi)DMA時(shí)鐘,對(duì)DMA進(jìn)行初始化,并啟動(dòng)DMA控制器。13.4項(xiàng)目實(shí)例第一步:復(fù)制第12章創(chuàng)建工程模板文件夾到桌面,并將文件夾改名為“12ADC+DMA+Printf”,將原工程模板編譯一下,直到?jīng)]有錯(cuò)誤和警告為止。11ADC12ADC+DMA+Printf第二步:為工程模板的“ST_Driver”項(xiàng)目組添加DMA庫(kù)函數(shù)源文件“stm32f10x_dma.c”,該文件位于“..\Libraries\STM32F10x_StdPeriph_Driver\src”目錄下。13.4.2項(xiàng)目實(shí)施13.4項(xiàng)目實(shí)例項(xiàng)目實(shí)施第三步:由于本項(xiàng)目需要將AD轉(zhuǎn)換結(jié)果打印到PC機(jī)的串口,由于大家都十分熟悉C語(yǔ)言中的printf函數(shù),所以我們這里將標(biāo)準(zhǔn)C的printf重寫一下,利用微控制器的串口將數(shù)據(jù)發(fā)送至PC機(jī),數(shù)據(jù)發(fā)送方法和我們?cè)跇?biāo)準(zhǔn)C語(yǔ)言中使用printf函數(shù)向顯示屏打印信息是一樣的。具體方法是如下:1.點(diǎn)擊“File/New”新建兩個(gè)文件,將其改名為printf.c和printf.h并保存到工程模板下的APP文件夾中。并將printf.c文件添加到APP項(xiàng)目組下。2、在printf.c文件中輸入如下源程序,在程序中首先包含printf.h頭文件,然后重寫fputc函數(shù),并對(duì)串口USART1進(jìn)行初始化,初始化代碼和第10章是一樣的。參考代碼如下:#include"printf.h"intfputc(intch,FILE*p)//函數(shù)默認(rèn)的在使用printf函數(shù)時(shí)自動(dòng)調(diào)用{USART_SendData(USART1,(u8)ch);while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);returnch;}voidprintf_init()//串口初始化{GPIO_InitTypeDefGPIO_InitStructure;USART_InitTypeDefUSART_InitStructure;/*打開(kāi)端口時(shí)鐘*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);/*配置GPIO的模式和IO口*/GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//TX//串口輸出PA9GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//復(fù)用推挽輸出GPIO_Init(GPIOA,&GPIO_InitStructure);/*初始化串口輸入IO*/GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//RX//串口輸入PA10GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;//模擬輸入GPIO_Init(GPIOA,&GPIO_InitStructure);/*初始化GPIO*//*USART串口初始化*/USART_InitStructure.USART_BaudRate=9600;//波特率設(shè)置為9600//波特率USART_InitStructure.USART_WordLength=USART_WordLength_8b;//數(shù)據(jù)長(zhǎng)8位USART_InitStructure.USART_StopBits=USART_StopBits_1;//1位停止位USART_InitStructure.USART_Parity=USART_Parity_No;//無(wú)效驗(yàn)USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//失能硬件流USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;//開(kāi)啟發(fā)送和接受模式USART_Init(USART1,&USART_InitStructure);/*初始化USART1*/USART_Cmd(USART1,ENABLE);/*使能USART1*/USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//使能或者失能指定的USART中斷接收中斷USART_ClearFlag(USART1,USART_FLAG_TC);//清除USARTx的待處理標(biāo)志位}參考程序代碼13.4項(xiàng)目實(shí)例項(xiàng)目實(shí)施3.在printf.h文件中輸入如下源程序,其中條件編譯格式不變,只要更改一下預(yù)定義變量名稱即可,需要將我們剛定義函數(shù)的聲明加到頭文件當(dāng)中。4.在main.h文件的中間部分添加“#include"printf.h"”語(yǔ)句,即包含printf.h頭文件。參考代碼如下:#ifndef_PRINTF_H#define_PRINTF_H#include"stm32f10x.h"#include"stdio.h"intfputc(intch,FILE*p);voidprintf_init(void);#endif13.4項(xiàng)目實(shí)例項(xiàng)目實(shí)施5.打開(kāi)工程屬性對(duì)話框“OptionsforTarget‘Target1’”,在“Target”選項(xiàng)中選中“UseMicroLIB”復(fù)選框,此步非常重要,否則編譯不能通過(guò)。6、此時(shí)已經(jīng)可以像標(biāo)準(zhǔn)C語(yǔ)言一樣,使用printf函數(shù)向串口輸出數(shù)據(jù)呢!大家可以在main函數(shù)中,使用語(yǔ)句“printf(“HelloWorld!\n”)”,輸出一個(gè)字符串,并在串口調(diào)試助手中查看輸出結(jié)果,串口調(diào)試助手使用方法同第10章。以后如果需要向串口輸出信息時(shí),只要先包含文件“printf.h”,再調(diào)用printf函數(shù)即可,十分方便。13.4項(xiàng)目實(shí)例項(xiàng)目實(shí)施第四步:點(diǎn)擊“File/New”新建兩個(gè)文件,將其改名為DMA-ADC.C和DMA-ADC.H并保存到工程模板下的APP文件夾中。并將DMA-ADC.C文件添加到APP項(xiàng)目組下。第五步:在DMA-ADC.C文件中輸入如下源程序,在程序中首先包含DMA-ADC.H頭文件,分別創(chuàng)建3個(gè)函數(shù)ADC_Use_DMA_Init()、DMA_For_ADC_Init()和filter()函數(shù)。#include"DMA-ADC.H"externu16AD_Value[20][4];//AD轉(zhuǎn)換結(jié)果4個(gè)通道每個(gè)通道20次externu16After_filter[4];//濾波后的數(shù)值共4個(gè)通道//使用DMA傳輸?shù)腁DC初始化程序voidADC_Use_DMA_Init(){GPIO_InitTypeDefGPIO_InitStructure;ADC_InitTypeDefADC_InitStructure;GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;GPIO_Init(GPIOA,&GPIO_InitStructure);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO|RCC_APB2Periph_ADC1,ENABLE);參考程序代碼13.4項(xiàng)目實(shí)例RCC_ADCCLKConfig(RCC_PCLK2_Div6);ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;ADC_InitStructure.ADC_ScanConvMode=ENABLE;ADC_InitStructure.ADC_ContinuousConvMode=ENABLE;ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;ADC_InitStructure.ADC_NbrOfChannel=4;//此次轉(zhuǎn)換共六個(gè)通道PA0~PA3ADC_Init(ADC1,&ADC_InitStructure);ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);ADC_RegularChannelConfig(ADC1,ADC_Channel_1,2,ADC_SampleTime_55Cycles5);ADC_RegularChannelConfig(ADC1,ADC_Channel_2,3,ADC_SampleTime_55Cycles5);ADC_RegularChannelConfig(ADC1,ADC_Channel_3,4,ADC_SampleTime_55Cycles5);ADC_DMACmd(ADC1,ENABLE);//開(kāi)啟ADC的DMA支持具體數(shù)據(jù)讀取還需要進(jìn)一步配置DMAADC_Cmd(ADC1,ENABLE);ADC_ResetCalibration(ADC1);while(ADC_GetResetCalibrationStatus(ADC1));ADC_StartCalibration(ADC1);while(ADC_GetCalibrationStatus(ADC1));ADC_SoftwareStartConvCmd(ADC1,ENABLE);}參考程序代碼13.4項(xiàng)目實(shí)例//DMA控制器初始化程序voidDMA_For_ADC_Init(){DMA_InitTypeDefDMA_InitStructure;RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);//開(kāi)啟DMA時(shí)鐘DMA_DeInit(DMA1_Channel1);//初始化為缺省值DMA_InitStructure.DMA_PeripheralBaseAddr=(u32)&ADC1->DR;//DMA外設(shè)ADC基地址DMA_InitStructure.DMA_MemoryBaseAddr=(u32)&AD_Value;//DMA內(nèi)存基地址DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;//內(nèi)存作為DMA目的地址DMA_InitStructure.DMA_BufferSize=4*20;//緩沖區(qū)的大小DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;//外設(shè)基地址不變DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;//內(nèi)存基址遞增DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;//數(shù)據(jù)寬度16位DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord;//數(shù)據(jù)寬度16位DMA_InitStructure.DMA_Mode=DMA_Mode_Circular;//工作在循環(huán)緩存模式DMA_InitStructure.DMA_Priority=DMA_Priority_High;//DMA高優(yōu)先級(jí)DMA_InitStructure.DMA_M2M=DMA_M2M_Disable;//DMA沒(méi)有設(shè)置為內(nèi)存到內(nèi)存模式DMA_Init(DMA1_Channel1,&DMA_InitStructure);//初始化}//ADC轉(zhuǎn)換結(jié)果中值濾波函數(shù)voidfilter(){u32sum=0;u8i,j;for(i=0;i<4;i++)//4個(gè)通道20次{sum=0;for(j=0;j<20;j++)sum+=AD_Value[j][i];After_filter[i]=sum/20;}}參考程序代碼13.4項(xiàng)目實(shí)例第六步:在DMA-ADC.H文件中輸入如下源程序,其中條件編譯格式不變,只要更改一下預(yù)定義變量名稱即可,需要將我們剛定義函數(shù)的聲明加到頭文件當(dāng)中。項(xiàng)目實(shí)施第六步參考代碼如下:#ifndef_DMA_H#define_DMA_H#include"stm32f10x.h"voidADC_Use_DMA_Init(void);voidDMA_For_ADC_Init(void);voidfilter(void);#endif第七步:在main.h文件的中間部分添加“#include"DMA-ADC.H"”語(yǔ)句,即包含DMA-ADC.H頭文件,main.h文件的源代碼如下所示
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2026年全國(guó)保密教育線上培訓(xùn)考試試題庫(kù)附完整答案(歷年真題)
- 國(guó)際視野測(cè)試題目與答案
- 2026年初中美術(shù)教師面試沖刺押題卷
- 醫(yī)院火災(zāi)應(yīng)急演練工作總結(jié)
- 某集團(tuán)公司信息化規(guī)劃報(bào)告-保障措施及指導(dǎo)思想(3篇)
- 洛陽(yáng)科目四考試題目與答案
- 五年級(jí)下冊(cè)數(shù)學(xué)北師大含答案 分?jǐn)?shù)除法(二)2
- 2026年智能會(huì)議投票 實(shí)時(shí)反饋文具應(yīng)用
- 空氣隔離測(cè)驗(yàn)試題及正確答案
- 2023年6月副主任醫(yī)師考試呼吸內(nèi)科慢性支氣管炎預(yù)防臨床思維訓(xùn)練題及答案
- 遼寧回民公墓管理辦法
- 河道清漂協(xié)議書
- 康養(yǎng)中心可行性研究報(bào)告
- 《加盟模式之ADIDAS》課件
- 天然氣計(jì)量培訓(xùn)課件
- 仁愛(ài)科普版(2024)七年級(jí)上冊(cè)英語(yǔ)Unit 3單元測(cè)試卷(含答案)
- DZ∕T 0334-2020 石油天然氣探明儲(chǔ)量報(bào)告編寫規(guī)范(正式版)
- 倉(cāng)儲(chǔ)物流部安全培訓(xùn)
- YS-T 3042-2021 氰化液化學(xué)分析方法 金量的測(cè)定
- JTG C10-2007 公路勘測(cè)規(guī)范
- 《中外管理思想史》課件
評(píng)論
0/150
提交評(píng)論