F4的片子內部DMA初始化和F103的有很大區別,在這裏引入了數據流(Stream),2個DMA共16的數據流(每個控制器8個),每個數據流則可已處理多達8個通道的數據,每個通道都有一個仲裁器處理DMA請求的優先級。下面貼出DMA請求映射事例
在DMA2中可以看出UART1的發送是數據流7的第4通道,接收是數據流5的第4通道。所以在配置DMA時要注意選擇對應的數據流然後配置對應的通道,最後初始化對應數據流和對應的通道。
下面貼出代碼
//****************************配置UART1 DMA發送
DMA_DeInit(DMA2_Stream7);
while (DMA_GetCmdStatus(DMA2_Stream7) != DISABLE);//等待DMA可配置
/* 配置 DMA Stream */
DMA_InitStructure.DMA_Channel = DMA_Channel_4; //通道選擇
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART1->DR;//DMA外設地址
DMA_InitStructure.DMA_Memory0BaseAddr = (u32)SendBuff;//DMA 存儲器0地址
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;//存儲器到外設模式
DMA_InitStructure.DMA_BufferSize = SEND_BUF_SIZE;//數據傳輸量
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外設非增量模式
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//存儲器增量模式
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//外設數據長度:8位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//存儲器數據長度:8位
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;// 使用普通模式
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;//中等優先級
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;//存儲器突發單次傳輸
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;//外設突發單次傳輸
DMA_Init(DMA2_Stream7, &DMA_InitStructure);//初始化DMA Stream
//DMA NVIC
NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream7_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
DMA_ITConfig(DMA2_Stream7,DMA_IT_TC,ENABLE);
//****************************配置UART1 DMA接收
DMA_DeInit(DMA2_Stream5);
while (DMA_GetCmdStatus(DMA2_Stream5) != DISABLE);//等待DMA可配置
/* 配置 DMA Stream */
DMA_InitStructure.DMA_Channel = DMA_Channel_4; //通道選擇
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART1->DR;//DMA外設地址
DMA_InitStructure.DMA_Memory0BaseAddr = (u32)ReceiveBuff;//DMA 存儲器0地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory ;//外設到存儲器模式
DMA_InitStructure.DMA_BufferSize = RECEIVE_BUF_SIZE;//數據傳輸量
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外設非增量模式
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//存儲器增量模式
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//外設數據長度:8位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//存儲器數據長度:8位
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;// 使用普通模式
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;//中等優先級
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;//存儲器突發單次傳輸
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;//外設突發單次傳輸
DMA_Init(DMA2_Stream5, &DMA_InitStructure);//初始化DMA Stream
//DMA NVIC
NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
DMA_Cmd(DMA2_Stream5, ENABLE); //開啓DMA傳輸
DMA_ITConfig(DMA2_Stream5,DMA_IT_TC,ENABLE);