由于做项目的需要的原因,我们这次使用了 DMA +IDLE 模式的接受模式,即任意的长度的数据仅仅需要一个IDLE中断就可以接受完成。 在tx方面我们采用了DMA 环形buffer的方式。下面详细说
1. RX Mode
RX Mode 比较简单 我们只是使能了IDLE mode 和DMA的buffer即可
下面是两个函数:
voidDMA_Init_Rx(u32 Source_addr, u32 Destination_addr)
{
DMA_InitTypeDef DMA_RX;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1,ENABLE);
DMA_DeInit(DMA1_Stream1);
DMA_RX.DMA_DIR=DMA_DIR_PeripheralToMemory;
DMA_RX.DMA_Memory0BaseAddr=Destination_addr;
DMA_RX.DMA_MemoryDataSize=DMA_MemoryDataSize_Byte;
DMA_RX.DMA_PeripheralBaseAddr=Source_addr;
DMA_RX.DMA_PeripheralInc=DMA_PeripheralInc_Disable;
DMA_RX.DMA_MemoryInc=DMA_MemoryInc_Enable;
DMA_RX.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte;
DMA_RX.DMA_Priority=DMA_Priority_Medium;
DMA_RX.DMA_Mode=DMA_Mode_Normal;
DMA_RX.DMA_Channel=DMA_Channel_4;
DMA_RX.DMA_FIFOMode=DMA_FIFOMode_Disable;
DMA_RX.DMA_MemoryBurst=DMA_MemoryBurst_Single;
DMA_RX.DMA_PeripheralBurst=DMA_PeripheralBurst_Single;
DMA_Init(DMA1_Stream1,&DMA_RX);
DMA_Cmd(DMA1_Stream1,ENABLE);
}voidUsart3_Init(uint32_t BaudRate)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//enable the GPIOB pins clock
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); //USART3 clock setting
GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_USART3);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_USART3);//Configure USART3 Tx (PB.10) as alternate function push-pull
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11;//PB.10 USART3_TX PB.11 USART3_RX
GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd= GPIO_PuPd_UP; //MOD
GPIO_Init(GPIOB, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate=BaudRate;
USART_InitStructure.USART_WordLength=USART_WordLength_8b;
USART_InitStructure.USART_StopBits=USART_StopBits_1;
USART_InitStructure.USART_Parity=USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode= USART_Mode_Rx |USART_Mode_Tx;
USART_Init(USART3,&USART_InitStructure);
USART_ITConfig(USART3, USART_IT_IDLE, ENABLE); //其中这个地方我们需要使能IDLE 模式
USART_ClearFlag(USART3, USART_FLAG_TC|USART_FLAG_IDLE); //needs to clear the TC flag
USART_ClearFlag(USART3, USART_FLAG_RXNE); //needs to clear the TC flag
USART_DMACmd(USART3, USART_DMAReq_Tx|USART_DMAReq_Rx, ENABLE);
USART_Cmd(USART3, ENABLE);/*Enable the USARTx Interrupt*/NVIC_InitStructure.NVIC_IRQChannel=USART3_IRQn;
NV