為什么建設(shè)營銷型網(wǎng)站自媒體平臺app下載
文章目錄
- DMA
- Ⅰ、DMA框圖
- Ⅱ、DMA基本結(jié)構(gòu)
- Ⅲ、不同外設(shè)的DMA請求
- Ⅳ、DMA函數(shù)
- Ⅴ、DMA_InitTypeDef結(jié)構(gòu)體參數(shù)
- ①、DMA_PeripheralBaseAddr
- ②、DMA_PeripheralDataSize
- ③、DMA_PeripheralInc
- ④、DMA_MemoryBaseAddr
- ⑤、DMA_MemoryDataSize
- ⑥、DMA_MemoryInc
- ⑦、DMA_DIR
- ⑧、DMA_BufferSize
- ⑨、DMA_Mode
- ⑩、DMA_M2M
- ①①、DMA_Priority
- Ⅵ、DMA配置示例
- DMA+AD多通道
- 1. ADC單次掃描+DMA數(shù)據(jù)轉(zhuǎn)運
- 2. ADC連續(xù)掃描+DMA循環(huán)轉(zhuǎn)運
DMA
Ⅰ、DMA框圖
Ⅱ、DMA基本結(jié)構(gòu)
Ⅲ、不同外設(shè)的DMA請求
Ⅳ、DMA函數(shù)
// 重置指定的DMA通道寄存器為默認值
void DMA_DeInit(DMA_Channel_TypeDef* DMAy_Channelx);// 初始化指定的DMA通道,根據(jù)初始化結(jié)構(gòu)體配置參數(shù)
void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct);// 初始化DMA初始化結(jié)構(gòu)體的默認值
void DMA_StructInit(DMA_InitTypeDef* DMA_InitStruct);// 開啟或關(guān)閉指定的DMA通道
void DMA_Cmd(DMA_Channel_TypeDef* DMAy_Channelx, FunctionalState NewState);// 開啟或關(guān)閉DMA通道的中斷
void DMA_ITConfig(DMA_Channel_TypeDef* DMAy_Channelx, uint32_t DMA_IT, FunctionalState NewState);// 設(shè)置DMA當(dāng)前數(shù)據(jù)計數(shù)器的值
void DMA_SetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx, uint16_t DataNumber); // 獲取DMA當(dāng)前數(shù)據(jù)計數(shù)器的值
uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx);// 獲取DMA標志狀態(tài)
FlagStatus DMA_GetFlagStatus(uint32_t DMAy_FLAG);
// 清除DMA標志
void DMA_ClearFlag(uint32_t DMAy_FLAG);// 獲取DMA中斷狀態(tài)
ITStatus DMA_GetITStatus(uint32_t DMAy_IT);
// 清除DMA中斷待處理位
void DMA_ClearITPendingBit(uint32_t DMAy_IT);
Ⅴ、DMA_InitTypeDef結(jié)構(gòu)體參數(shù)
①、DMA_PeripheralBaseAddr
指定DMA通道的外設(shè)基地址(外設(shè)寄存器-起始地址)
- 類型:
uint32_t
- 取值范圍:任意有效的外設(shè)地址
- 作用:這是DMA操作的外設(shè)端的起始地址,例如ADC、USART等外設(shè)的數(shù)據(jù)寄存器地址
②、DMA_PeripheralDataSize
指定外設(shè)寄存器的數(shù)據(jù)寬度 (配置DMA傳輸時外設(shè)數(shù)據(jù)的大小)
該參數(shù)可以是
@ref DMA_peripheral_data_size
:
宏定義解釋
DMA_PeripheralDataSize_Byte
- 描述:表示外設(shè)數(shù)據(jù)大小為1字節(jié)(8位)
- 每次DMA傳輸?shù)臄?shù)據(jù)大小為1字節(jié)
DMA_PeripheralDataSize_HalfWord
- 描述:表示外設(shè)數(shù)據(jù)大小為半字(16位)
- 每次DMA傳輸?shù)臄?shù)據(jù)大小為2字節(jié)
DMA_PeripheralDataSize_Word
- 描述:表示外設(shè)數(shù)據(jù)大小為1字(32位)
- 每次DMA傳輸?shù)臄?shù)據(jù)大小為4字節(jié)
宏函數(shù)
IS_DMA_PERIPHERAL_DATA_SIZE(SIZE)
- 描述:檢查給定的外設(shè)數(shù)據(jù)大小設(shè)置是否有效
- 參數(shù):
SIZE
,代表DMA的外設(shè)數(shù)據(jù)大小- 功能:檢查
SIZE
是否等于DMA_PeripheralDataSize_Byte
、DMA_PeripheralDataSize_HalfWord
或DMA_PeripheralDataSize_Word
中的任一個。- 返回值:如果
SIZE
有效,返回1
(真),否則返回0
(假)
③、DMA_PeripheralInc
指定外設(shè)地址寄存器是否遞增
- 類型:
uint32_t
- 取值范圍:
DMA_PeripheralInc_Disable
:外設(shè)地址不遞增DMA_PeripheralInc_Enable
:外設(shè)地址遞增- 作用:控制外設(shè)地址在每次數(shù)據(jù)傳輸后是否遞增
④、DMA_MemoryBaseAddr
指定DMA通道的內(nèi)存基地址 (存儲器-起始地址)
- 類型:
uint32_t
- 取值范圍:任意有效的內(nèi)存地址
- 作用:這是DMA操作的內(nèi)存端的起始地址,例如一個緩沖區(qū)的起始地址
⑤、DMA_MemoryDataSize
指定內(nèi)存數(shù)據(jù)寬度(存儲器-數(shù)據(jù)寬度)
- 類型:
uint32_t
- 取值范圍:
DMA_MemoryDataSize_Byte
:數(shù)據(jù)寬度為8位DMA_MemoryDataSize_HalfWord
:數(shù)據(jù)寬度為16位DMA_MemoryDataSize_Word
:數(shù)據(jù)寬度為32位- 作用:確定內(nèi)存數(shù)據(jù)的大小
⑥、DMA_MemoryInc
指定內(nèi)存地址寄存器是否遞增(指定存儲器-是否遞增)
- 類型:
uint32_t
- 取值范圍:
DMA_MemoryInc_Disable
:內(nèi)存地址不遞增DMA_MemoryInc_Enable
:內(nèi)存地址遞增- 作用:控制內(nèi)存地址在每次數(shù)據(jù)傳輸后是否遞增
⑦、DMA_DIR
指定數(shù)據(jù)傳輸方向,即外設(shè)是數(shù)據(jù)源還是數(shù)據(jù)目標(指定外設(shè)站點是源還是目標)
- 類型:
uint32_t
- 取值范圍:
DMA_DIR_PeripheralSRC
:外設(shè)是數(shù)據(jù)源,內(nèi)存是數(shù)據(jù)目標DMA_DIR_PeripheralDST
:外設(shè)是數(shù)據(jù)目標,內(nèi)存是數(shù)據(jù)源- 作用:確定數(shù)據(jù)傳輸?shù)姆较?/li>
⑧、DMA_BufferSize
指定DMA通道的緩沖區(qū)大小,以數(shù)據(jù)單元為單位
DMA_InitStruct.DMA_BufferSize = Size;
傳遞Size個大小為<數(shù)據(jù)寬度>的數(shù)據(jù)
- 類型:
uint32_t
- 取值范圍:0到65535
- 作用:確定要傳輸?shù)臄?shù)據(jù)量。數(shù)據(jù)單元的大小取決于
DMA_PeripheralDataSize
或DMA_MemoryDataSize
的配置,具體取決于傳輸方向
⑨、DMA_Mode
指定DMAy通道的工作模式(是否要自動重裝)
- 類型:
uint32_t
- 取值范圍:
DMA_Mode_Normal
:正常模式,傳輸完成后停止DMA_Mode_Circular
:循環(huán)模式(自動重裝),傳輸完成后從頭開始- 作用:確定DMA傳輸?shù)哪J?。循環(huán)模式不適用于內(nèi)存到內(nèi)存的傳輸
⑩、DMA_M2M
是否使用軟件觸發(fā)(存儲器到存儲器)
- 類型:
uint32_t
- 描述:指定DMA通道是否用于內(nèi)存到內(nèi)存的傳輸
- 取值范圍:
DMA_M2M_Disable
:不使用內(nèi)存到內(nèi)存?zhèn)鬏?/li>DMA_M2M_Enable
:使用內(nèi)存到內(nèi)存?zhèn)鬏?/li>- 作用:確定DMA通道是否用于內(nèi)存到內(nèi)存的傳輸
①①、DMA_Priority
指定DMA通道的軟件優(yōu)先級
按需求配置
- 類型:
uint32_t
- 取值范圍:
DMA_Priority_Low
:低優(yōu)先級DMA_Priority_Medium
:中優(yōu)先級DMA_Priority_High
:高優(yōu)先級DMA_Priority_VeryHigh
:非常高優(yōu)先級- 作用:確定DMA通道的優(yōu)先級,影響多個DMA請求的處理順序
Ⅵ、DMA配置示例
#include "stm32f10x.h" // Device headeruint32_t Temp_Size;//存儲數(shù)據(jù)計數(shù)器的值void MyDMA_Init(uint32_t Source, uint32_t Dest, uint32_t Size)//參數(shù)需為兩個數(shù)組的數(shù)組名
{Temp_Size = Size;RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);DMA_InitTypeDef DMA_InitStruct;DMA_InitStruct.DMA_PeripheralBaseAddr = Source;//外設(shè)寄存器-起始地址DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//外設(shè)寄存器-數(shù)據(jù)寬度(此處為1byte)DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Enable;//指定外設(shè)地址寄存器-是否遞增DMA_InitStruct.DMA_MemoryBaseAddr = Dest;//存儲器-起始地址DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//存儲器-數(shù)據(jù)寬度DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;//指定存儲器-是否遞增DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;//指定外設(shè)站點是源還是目標DMA_InitStruct.DMA_BufferSize = Size;//傳遞Size個大小為<數(shù)據(jù)寬度>的數(shù)據(jù)DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;//指定DMAy通道的工作模式(是否要自動重裝)DMA_InitStruct.DMA_M2M = DMA_M2M_Enable;//是否使用軟件觸發(fā)(存儲器到存儲器)DMA_InitStruct.DMA_Priority = DMA_Priority_Medium;//指定DMAy通道的軟件優(yōu)先級DMA_Init(DMA1_Channel1, &DMA_InitStruct);DMA_Cmd(DMA1_Channel1, DISABLE);//使能或失能DMA
}void MyDMA_Transfer(void)//調(diào)用函數(shù)則開始轉(zhuǎn)運
{DMA_Cmd(DMA1_Channel1, DISABLE);//失能DMADMA_SetCurrDataCounter(DMA1_Channel1, Temp_Size);//設(shè)置DMA當(dāng)前數(shù)據(jù)計數(shù)器的值DMA_Cmd(DMA1_Channel1, ENABLE);//使能DMAwhile(DMA_GetFlagStatus(DMA1_FLAG_TC1) == RESET)//獲取DMA標志狀態(tài)(等待轉(zhuǎn)運完成)DMA_ClearFlag(DMA1_FLAG_TC1);//清除DMA標志位
}
DMA+AD多通道
1. ADC單次掃描+DMA數(shù)據(jù)轉(zhuǎn)運
#include "stm32f10x.h" // Device header
//模擬量轉(zhuǎn)換為數(shù)字量
//AD多通道(ADC掃描模式+DMA數(shù)據(jù)轉(zhuǎn)運)uint16_t Dest_Data[4];void AD_Init(void)
{ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//開啟GPIO時鐘RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);//開啟ADC時鐘RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//開啟DMA時鐘RCC_ADCCLKConfig(RCC_PCLK2_Div6);//配置ADC時鐘(72MHz/6=12MHz)//配置GPIOGPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;//模擬輸入GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStruct);ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_41Cycles5);//配置ADC常規(guī)通道ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_41Cycles5);//配置ADC常規(guī)通道ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_41Cycles5);//配置ADC常規(guī)通道ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_41Cycles5);//配置ADC常規(guī)通道//配置ADCADC_InitTypeDef ADC_InitStruct;ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;//將ADC配置為獨立或操作雙模式ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;//數(shù)據(jù)右對齊ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//不使用外部觸發(fā)ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;//單次轉(zhuǎn)換or連續(xù)轉(zhuǎn)換ADC_InitStruct.ADC_ScanConvMode = ENABLE;//非掃描模式or掃描模式ADC_InitStruct.ADC_NbrOfChannel = 4;//指定要轉(zhuǎn)換的ADC通道的數(shù)量ADC_Init(ADC1, &ADC_InitStruct);//配置DMA DMA_InitTypeDef DMA_InitStruct;DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;//外設(shè)寄存器-起始地址DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//外設(shè)寄存器-數(shù)據(jù)寬度(此處為1byte)DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//指定外設(shè)地址寄存器-是否遞增DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)Dest_Data;//存儲器-起始地址DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//存儲器-數(shù)據(jù)寬度DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;//指定存儲器-是否遞增DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;//指定外設(shè)站點是源還是目標DMA_InitStruct.DMA_BufferSize = 4;//傳遞Size個大小為<數(shù)據(jù)寬度>的數(shù)據(jù)DMA_InitStruct.DMA_Mode = DMA_Mode_Normal;//指定DMAy通道的工作模式(是否要自動重裝)DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;//是否使用軟件觸發(fā)(存儲器到存儲器)DMA_InitStruct.DMA_Priority = DMA_Priority_Medium;//指定DMAy通道的軟件優(yōu)先級DMA_Init(DMA1_Channel1, &DMA_InitStruct);ADC_DMACmd(ADC1, ENABLE);//開啟ADC的DMA功能DMA_Cmd(DMA1_Channel1, ENABLE);//使能或失能DMAADC_Cmd(ADC1, ENABLE);//開啟ADC//ADC復(fù)位+校準ADC_ResetCalibration(ADC1);//重置ADC校準,準備進行校準操作while(ADC_GetResetCalibrationStatus(ADC1) == SET);//獲取ADC重置校準狀態(tài),檢查是否完成ADC_StartCalibration(ADC1);//開始ADC校準while(ADC_GetCalibrationStatus(ADC1) == SET);//獲取ADC校準狀態(tài),檢查是否完成
}void AD_GetValue(void)//獲取模擬值
{//選擇不同的通道或取ADC值DMA_Cmd(DMA1_Channel1, DISABLE);//失能DMADMA_SetCurrDataCounter(DMA1_Channel1, 4);//設(shè)置DMA當(dāng)前數(shù)據(jù)計數(shù)器的值DMA_Cmd(DMA1_Channel1, ENABLE);//使能DMAADC_SoftwareStartConvCmd(ADC1, ENABLE);//開啟軟件啟動ADC轉(zhuǎn)換,用于軟件觸發(fā)轉(zhuǎn)換--啟動while(DMA_GetFlagStatus(DMA1_FLAG_TC1) == RESET)//獲取DMA標志狀態(tài)(等待轉(zhuǎn)運完成)DMA_ClearFlag(DMA1_FLAG_TC1);//清除DMA標志位}
2. ADC連續(xù)掃描+DMA循環(huán)轉(zhuǎn)運
#include "stm32f10x.h" // Device header
//模擬量轉(zhuǎn)換為數(shù)字量
//AD多通道(ADC連續(xù)掃描+DMA循環(huán)轉(zhuǎn)運)uint16_t Dest_Data[4];void AD_Init(void)
{ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//開啟GPIO時鐘RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);//開啟ADC時鐘RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//開啟DMA時鐘RCC_ADCCLKConfig(RCC_PCLK2_Div6);//配置ADC時鐘(72MHz/6=12MHz)//配置GPIOGPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;//模擬輸入GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStruct);ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_41Cycles5);//配置ADC常規(guī)通道ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_41Cycles5);//配置ADC常規(guī)通道ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_41Cycles5);//配置ADC常規(guī)通道ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_41Cycles5);//配置ADC常規(guī)通道//配置ADCADC_InitTypeDef ADC_InitStruct;ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;//將ADC配置為獨立或操作雙模式ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;//數(shù)據(jù)右對齊ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//不使用外部觸發(fā)ADC_InitStruct.ADC_ContinuousConvMode = ENABLE;//單次轉(zhuǎn)換or連續(xù)轉(zhuǎn)換**********************************************ADC_InitStruct.ADC_ScanConvMode = ENABLE;//非掃描模式or掃描模式ADC_InitStruct.ADC_NbrOfChannel = 4;//指定要轉(zhuǎn)換的ADC通道的數(shù)量ADC_Init(ADC1, &ADC_InitStruct);//配置DMA DMA_InitTypeDef DMA_InitStruct;DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;//外設(shè)寄存器-起始地址DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//外設(shè)寄存器-數(shù)據(jù)寬度(此處為1byte)DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//指定外設(shè)地址寄存器-是否遞增DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)Dest_Data;//存儲器-起始地址DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//存儲器-數(shù)據(jù)寬度DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;//指定存儲器-是否遞增DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;//指定外設(shè)站點是源還是目標DMA_InitStruct.DMA_BufferSize = 4;//傳遞Size個大小為<數(shù)據(jù)寬度>的數(shù)據(jù)DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;//指定DMAy通道的工作模式(是否要自動重裝)******************************DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;//是否使用軟件觸發(fā)(存儲器到存儲器)DMA_InitStruct.DMA_Priority = DMA_Priority_Medium;//指定DMAy通道的軟件優(yōu)先級DMA_Init(DMA1_Channel1, &DMA_InitStruct);ADC_DMACmd(ADC1, ENABLE);//開啟ADC的DMA功能DMA_Cmd(DMA1_Channel1, ENABLE);//使能或失能DMAADC_Cmd(ADC1, ENABLE);//開啟ADC//ADC復(fù)位+校準ADC_ResetCalibration(ADC1);//重置ADC校準,準備進行校準操作while(ADC_GetResetCalibrationStatus(ADC1) == SET);//獲取ADC重置校準狀態(tài),檢查是否完成ADC_StartCalibration(ADC1);//開始ADC校準while(ADC_GetCalibrationStatus(ADC1) == SET);//獲取ADC校準狀態(tài),檢查是否完成ADC_SoftwareStartConvCmd(ADC1, ENABLE);//開啟軟件啟動ADC轉(zhuǎn)換,用于軟件觸發(fā)轉(zhuǎn)換--啟動********************************
}
//*****************************************************************************************