硬體平台: stm32f407
庫檔案:STM32F4xx_DSP_StdPeriph_Lib_V1.6.1
串口: USART6 TX & RX
STM32F4有兩個DMA控制器,掛載在AHB匯流排上,每一個DMA控制器有八個stream,每一個stream有八個channel。
一個channel可以不同時使用多個stream,一個stream不能同時使用多個channel。
發送資料:
1. 當DMA發送使能,且資料緩衝區有資料則一直發送資料
2.DMA發送完成後產生髮送完成中斷,需要清除發送完成標誌位,如不需要再次發送資料則需要關閉發送通道
3.重新對資料緩衝區寫入資料,開啟發送通道進行下一次發送
接收資料:
當DMA配置好之後,一直在等待接收資料,外設資料進入接收資料緩衝區。當資料流斷流之後產生串口空閑中斷。此時需要關閉相關接收通道,清除接收標誌位,讀取接收到的資料。開啟通道等待下一次接收(請求一次DMA接收)
GPIO初始化:
//USART6 PC6 PC7RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE);gpio.GPIO_Mode = GPIO_Mode_AF;gpio.GPIO_OType = GPIO_OType_OD;gpio.GPIO_PuPd = GPIO_PuPd_NOPULL;gpio.GPIO_Speed = GPIO_Speed_25MHz;gpio.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;GPIO_Init(GPIOC,&gpio);GPIO_PinAFConfig(GPIOC,GPIO_PinSource6,GPIO_AF_USART6);GPIO_PinAFConfig(GPIOC,GPIO_PinSource7,GPIO_AF_USART6);
串口初始化:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6,ENABLE); usart.USART_BaudRate = 115200; usart.USART_HardwareFlowControl = USART_HardwareFlowControl_None; usart.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; usart.USART_Parity = USART_Parity_No; usart.USART_StopBits = USART_StopBits_1; usart.USART_WordLength = USART_WordLength_8b; USART_Init(USART6,&usart); USART_Cmd(USART6,ENABLE); USART_ITConfig(USART6, USART_IT_IDLE, ENABLE);
DMA初始化:
DMA_DeInit(DMA2_Stream1);
DMA_DeInit(DMA2_Stream6);//將stream設定為預設值 DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&USART6->DR); DMA_InitStructure.DMA_BufferSize = 8; 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_High; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOStatus_Full; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;//USART6 DMA收 DMA_InitStructure.DMA_Channel = DMA_Channel_5; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&(bspdata.usart_rxbuffer); DMA_ITConfig(DMA2_Stream1,DMA_IT_TC,ENABLE); DMA_Init(DMA2_Stream1, &DMA_InitStructure);//USART6 DMA發 DMA_InitStructure.DMA_Channel = DMA_Channel_5; DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&(bspdata.usart_txbuffer); DMA_ITConfig(DMA2_Stream6, DMA_IT_TC,ENABLE); DMA_Init(DMA2_Stream6, &DMA_InitStructure);
串口DMA接收和發送初始化
NVIC初始化:
nvic.NVIC_IRQChannel = DMA2_Stream1_IRQn; nvic.NVIC_IRQChannelPreemptionPriority = 0; nvic.NVIC_IRQChannelSubPriority =0;
nvic.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能 NVIC_Init(&nvic); nvic.NVIC_IRQChannel = DMA2_Stream6_IRQn; nvic.NVIC_IRQChannelPreemptionPriority = 0; nvic.NVIC_IRQChannelSubPriority =1; nvic.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能 NVIC_Init(&nvic);
中斷管理器裡面設定DMA中斷優先順序
中斷服務函數:
void DMA2_Stream1_IRQHandler(void){if(DMA_GetITStatus(DMA2_Stream1, DMA_IT_TCIF1) != RESET) {PDout(8) = 1;PDout(9) = 1;PDout(10) = 1; DMA_ClearITPendingBit(DMA2_Stream1, DMA_IT_TCIF1);for(i=0;i<8;i++){bspdata.usart_txbuffer[i] = bspdata.usart_rxbuffer[i];//bspdata.usart_rxbuffer[i] = 0;}flag=1; }DMA_ClearFlag(DMA2_Stream1,DMA_IT_TCIF1);}void DMA2_Stream6_IRQHandler(void){if(DMA_GetITStatus(DMA2_Stream6, DMA_IT_TCIF6) != RESET) {PDout(8) = 0;PDout(9) = 0;PDout(10) = 0; DMA_ClearITPendingBit(DMA2_Stream6, DMA_IT_TCIF6); }} 中斷服務函數裡面清除相關標誌位