dingy 发表于 2022-4-12 21:43

串口接收数据问题

STM32F407 DMA串口
407串口1采用DMA收发数据,发送一切正常,接收有问题;接收采用串口的空闲中断来判断接收完成,程序下进去启动后第一次接收正常,往后就不行了,数据维持不变,不往缓存区写数据了;反真是能进串口空闲中断的,也参考了许多许多网上的例程,没有发现什么差异,不知道是哪里有问题。

dingy 发表于 2022-4-12 21:44

中断处理函数?

dingy 发表于 2022-4-12 21:49

void Receive_Data_IRQHandler(void)
{
      if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)
    {
      USART1->SR;
      USART1->DR; //清USART_IT_IDLE标志
      //关闭DMA
      DMA_Cmd(DMA2_Stream2,DISABLE);
      //清除标志位
      DMA_ClearFlag(DMA2_Stream2,DMA_FLAG_TCIF4);

                RS485_RX_CNT = 64 - DMA_GetCurrDataCounter(DMA2_Stream2);

      //获得接收帧帧长
      //memcpy(buf,Rx_Buf_Gsm,len);

      //设置传输数据长度
      DMA_SetCurrDataCounter(DMA2_Stream2,64);
      //打开DMA
      DMA_Cmd(DMA2_Stream2,ENABLE);
    }      
}

dingy 发表于 2022-4-12 21:51


这是网上的中断处理函数:
uint8_t drv_gsm_deal_irq_rx_end(uint8_t *buf)
{   
    uint16_t len = 0;
      
    //接收完成中断
    if(USART_GetITStatus(USART2, USART_IT_IDLE) != RESET)
    {
      USART2->SR;
      USART2->DR; //清USART_IT_IDLE标志
      //关闭DMA
      DMA_Cmd(DMA1_Stream5,DISABLE);
      //清除标志位
      DMA_ClearFlag(DMA1_Stream5,DMA_FLAG_TCIF5);
         
      //获得接收帧帧长
      len = RX_LEN_GSM - DMA_GetCurrDataCounter(DMA1_Stream5);
      memcpy(buf,Rx_Buf_Gsm,len);
         
      //设置传输数据长度
      DMA_SetCurrDataCounter(DMA1_Stream5,RX_LEN_GSM);
      //打开DMA
      DMA_Cmd(DMA1_Stream5,ENABLE);

      return len;
    }   
      
    return 0;
}

dingy 发表于 2022-4-12 21:53

这是我的接收部分DMA配置:

      //串口收DMA配置   
    //启动DMA时钟
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
    //DMA通道配置
      while(DMA_GetCmdStatus(DMA2_Stream2) != DISABLE){}      //等待DMA可配置
    DMA_DeInit(DMA2_Stream2);
    DMA_InitStructure.DMA_Channel = DMA_Channel_4;
    //外设地址
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&USART1->DR);
    //内存地址
    DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)RS485_RX_BUF;
    //dma传输方向
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
    //设置DMA在传输时缓冲区的长度
    DMA_InitStructure.DMA_BufferSize =64;
    //设置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;

    //指定如果FIFO模式或直接模式将用于指定的流 : 不使能FIFO模式   
    DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;      
    //指定了FIFO阈值水平
    DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;         
    //指定的Burst转移配置内存传输   
    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;         
    //指定的Burst转移配置外围转移 */   
    DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;   

    //配置DMA1的通道         
    DMA_Init(DMA2_Stream2, &DMA_InitStructure);   
    //使能通道
    DMA_Cmd(DMA2_Stream2,ENABLE);

dingy 发表于 2022-4-12 21:54

如果把DMA_Mode 改成 DMA_Mode_Circular(循环接收) 则接收正常,单次模式真的只能接收一次,但在串口接收中断里明明已经重新设定了DMA传输数量并重新使能了。不解,有什么是我没考虑到的写的不对的,望指点。

pangb 发表于 2022-4-12 21:57

DMA mode 设定的是DMA_Mode_Normal啊,也就是发送一次后DMA就停止循环了啊,串口就不会有新数据了

xxrs 发表于 2022-4-12 21:58

换成Circular就一直循环

jiajs 发表于 2022-4-12 22:01

如果你要设置单次循环,必须重新设置内存地址DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)RS485_RX_BUF;

stly 发表于 2022-4-12 22:02

为什么我看别人例程都没设呢

chuxh 发表于 2022-4-12 22:04

试试接受完重新配置DMA

renyaq 发表于 2022-4-12 22:06

我也遇到了这个问题,但是我的DMA_Mode 是DMA_Mode_Circular(循环接收),也是只能接收一次,设置的缓存区存满后,就不接收了,不知道楼主有没有遇到这种情况

stly 发表于 2022-4-12 22:08


F7中使用DMA操作SPI也遇到了这个问题,只有第一次DMA发送SPI成功,后面的数据就没有了

stly 发表于 2022-4-12 22:10

我每次发送DMA前都会重写传输数据寄存器的,应该不会有问题啊。

renyaq 发表于 2022-4-12 22:12

有时候莫名其妙的 可能也有硬件问题

heweibig 发表于 2022-4-12 22:14

重新断电上电试试

jiajs 发表于 2022-4-12 22:16

需要重新设置内存地址DMA_InitStructure

huangchui 发表于 2022-4-12 22:21

有没有在别的地方关闭中断了呢

chuxh 发表于 2022-4-12 22:26

DMA传输完成后,DMA的内存地址寄存器的内容也变了,

supernan 发表于 2022-4-12 22:28

要重新写入新的地址,
页: [1] 2
查看完整版本: 串口接收数据问题