STM32串口接收数据有时候会出错

void USART_Config(void)
{
GPIO_InitTypeDef GPIO_InitStruct ;
USART_InitTypeDef USART_InitStruct ;
NVIC_InitTypeDef NVIC_InitStruct ;

#ifdef DMA_EN
DMA_InitTypeDef   DMA_InitStructure ;                        


RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);  

//DMA1通道5配置

DMA_DeInit(DMA1_Channel6); //USART2_RX DMA1 channel 6

//外设地址

DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&USART2->DR);

//内存地址

DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART_Rev_Buffer;

//dma传输方向单向

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

//设置DMA在传输时缓冲区的长度

DMA_InitStructure.DMA_BufferSize = 40 ;//UART_RX_LEN;

//设置DMA的外设递增模式,一个外设

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

//设置DMA的内存递增模式

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

//外设数据字长

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;

//内存数据字长

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;

//设置DMA的传输模式

DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;

//设置DMA的优先级别

DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;

//设置DMA的2个memory中的变量互相访问

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

DMA_Init(DMA1_Channel6,&DMA_InitStructure);

//使能通道6 

DMA_Cmd(DMA1_Channel6,ENABLE);

#endif

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);

USART_DeInit(USART2) ;

GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2 ;  //USART1-TX
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz ;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP ;
GPIO_Init(GPIOA,&GPIO_InitStruct);

GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3 ;  //USART1-RX
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz ;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING ;
GPIO_Init(GPIOA,&GPIO_InitStruct);

USART_InitStruct.USART_BaudRate = 115200 ;
USART_InitStruct.USART_WordLength = USART_WordLength_8b ;
USART_InitStruct.USART_StopBits = USART_StopBits_1 ;
USART_InitStruct.USART_Parity = USART_Parity_No ;
USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx ;
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None ;
USART_Init(USART2,&USART_InitStruct) ;

NVIC_InitStruct.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=0 ; //抢占优先级 3
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 3; //子优先级 3
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;  //IRQ 通道使能
NVIC_Init(&NVIC_InitStruct);  

USART_ITConfig(USART2,USART_IT_IDLE,ENABLE) ;
/* CPU的小缺陷:串口配置好,如果直接Send,则第1个字节发送不出去 如下语句解决第1个字节无法正确发送出去的问题 */ 
//USART_ClearFlag(USART2, USART_FLAG_TC); /* 清发送外城标志,Transmission Complete*/

USART_DMACmd(USART2, USART_DMAReq_Rx, ENABLE); // 开启串口DMA接收

USART_Cmd(USART2, ENABLE);

}

void USART2_IRQHandler(void)
{
uint8_t temp = 0;

uint8_t i = 0;

if(USART_GetITStatus(USART2, USART_IT_IDLE) != RESET)

{

//USART_ClearFlag(USART1,USART_IT_IDLE);

temp = USART2->SR;

temp = USART2->DR; //清USART_IT_IDLE标志

DMA_Cmd(DMA1_Channel6,DISABLE);

    temp = 40 - DMA_GetCurrDataCounter(DMA1_Channel6);   //接收到数据的长度
    for(i=0;i<temp;i++)
    {
        printf(" %x ",USART_Rev_Buffer[i]);
    }
    printf("\r\n");
    printf("\r\n");
    //if(temp == USART_Rev_Buffer[4]+5)
    //{
    //  USART_FLAG_RX = 1 ;      //标志位置1 
        //USART_TX = 0 ;
    //}
    //设置传输数据长度  
    DMA_SetCurrDataCounter(DMA1_Channel6,40);  
    //打开DMA  
    DMA_Cmd(DMA1_Channel6,ENABLE);  

}

__nop();

}

图片说明

1个回答

http://blog.csdn.net/a29562268/article/details/68955729
我喜欢用的方法 可以参考下

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问