【求助】STM32F407的串口5,4,1用DMA方式接收数据,设置了传输完成中断,MCU每次复位后3个串口中有的无法再次产生DMA接收完成中断

2019-07-20 20:38发布

本帖最后由 天山狐狸 于 2016-8-18 11:42 编辑

如题:我用STM32F407的串口5,4,1,用DMA方式接收数据,每个串口接收的数据都是一样的,就5个字节,有时3个串口DMA的接收完成中断都正常。
         但是我发现把单片机复位下后,有的串口不再产生接收完成中断了,其他2个却是好的。
大致描述:
DMA1_Stream0,DMA_Channel_4,用于串口5的接收,数据存在M1_2400M_Card_Data中
DMA1_Stream2,DMA_Channel_4,用于串口4的接收,数据存在M2_2400M_Card_Data中
DMA2_Stream5,DMA_Channel_4,用于串口1的接收,数据存在M3_2400M_Card_Data中



串口1的配置如下,其他两个类似,就不列了:
[mw_shl_code=applescript,true]void USART1_Init(uint32_t BaudRate)
{
  USART_InitTypeDef USART_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(USART1, &USART_InitStructure);//初始化串口

  USART_Cmd(USART1, ENABLE);//使能串口
  USART_ClearFlag(USART1, USART_FLAG_TC);
}[/mw_shl_code]


DMA设置函数如下:
[mw_shl_code=applescript,true]void DMA_Config(DMA_Stream_TypeDef *DMA_Streamx,
                uint32_t DMA_Channel,
                uint32_t aSRC_Buffer,
                uint32_t aDST_Buffer,
                uint32_t DMA_Priority,
                uint32_t DMA_BufferSize)
{
  DMA_InitTypeDef  DMA_InitStructure;
  while (DMA_GetCmdStatus(DMA_Streamx) != DISABLE)
  {
  }

  /* Configure DMA Stream */
  DMA_InitStructure.DMA_Channel = DMA_Channel;                            //通道选择
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)aSRC_Buffer;       //DMA外设地址
  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)aDST_Buffer;          //DMA 存储器0地址
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;                 //外设到存储器模式
  DMA_InitStructure.DMA_BufferSize = (uint32_t)DMA_BufferSize;            //数据传输量大小
  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_Circular;                         //使用普通模式
  DMA_InitStructure.DMA_Priority = DMA_Priority;                          //DMA优先级
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;                  //DMA FIFO不使能
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;           //DMA FIFO阈值为满
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;             //存储器突发单次传输
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;     //外设突发单次传输
  DMA_Init(DMA_Streamx, &DMA_InitStructure);                              //初始化DMA Stream
  
  DMA_ITConfig(DMA_Streamx, DMA_IT_TC, ENABLE);
  DMA_Cmd(DMA_Streamx, ENABLE);
}[/mw_shl_code]


3个串口使能了DMA接收,且初始化如下:
[mw_shl_code=applescript,true]USART_DMACmd(UART5,USART_DMAReq_Rx,ENABLE);   //使能串口5的DMA接收
  USART_DMACmd(UART4,USART_DMAReq_Rx,ENABLE);   //使能串口4的DMA接收
  USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE);  //使能串口1的DMA接收
  DMA_Config(DMA1_Stream0,DMA_Channel_4,(u32)(&(UART5->DR)),(u32)buffer1,DMA_Priority_Low,5);
  DMA_Config(DMA1_Stream2,DMA_Channel_4,(u32)(&(UART4->DR)),(u32)buffer2,DMA_Priority_Low,5);
  DMA_Config(DMA2_Stream5,DMA_Channel_4,(u32)(&(USART1->DR)),(u32)buffer3,DMA_Priority_Low,5);
  [/mw_shl_code]

这个是哪里的问题呢,哪位前辈给指点下。。每次单片机复位后,出现不产生中断的串口不是固定的,有时3个都是好的。


修改原因:新增3个DMA的NVIC设置
[mw_shl_code=applescript,true]//使能DMA传输完成中断,2016-08-15
  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream0_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);                            //初始化

  //使能DMA传输完成中断,2016-08-15
  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;            //使能
  NVIC_Init(&NVIC_InitStructure);                            //初始化

  //使能DMA传输完成中断,2016-08-15
  NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream5_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);                            //初始化[/mw_shl_code]





友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
27条回答
天山狐狸
1楼-- · 2019-07-21 01:57
zmingwang 发表于 2016-8-19 20:29
把DMA->CCR的CIRC去掉再试试

谢谢一路指点啊


问题已经解决:把DMA的初始化放到串口初始化前就好了。为什么不知道,现在测试一切正常了。。
天山狐狸
2楼-- · 2019-07-21 04:26
 精彩回答 2  元偷偷看……
天山狐狸
3楼-- · 2019-07-21 04:27
本帖最后由 天山狐狸 于 2016-8-18 10:16 编辑

继续分析:测试发现,好像是DMA不去读取串口的数据了。。。但是串口的状态寄存器中却没有RXNE标识,即数据已经被读取了,这个数据被谁拿走了呢
DMA没有取,数组中也是空的,但是数据却被拿走了。。
天山狐狸
4楼-- · 2019-07-21 05:48
本帖最后由 天山狐狸 于 2016-8-20 14:44 编辑

呼叫原子哥,我是哪里出了问题了呢。
xuande
5楼-- · 2019-07-21 06:44

DMA是一对一的事,
3个串口是怎么回事、什么情况?

天山狐狸
6楼-- · 2019-07-21 10:30
 精彩回答 2  元偷偷看……

一周热门 更多>