首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >STM32F0 DMA“输入溢出”

STM32F0 DMA“输入溢出”
EN

Stack Overflow用户
提问于 2017-01-13 13:20:45
回答 1查看 1.7K关注 0票数 0

我有一个问题,STM32F0 DMA接收数据从UART。我使用2个DMA通道(对于rx和tx)都是在非圆模式下,rx通道具有较低的优先级.从UART处理的数据在空闲线中断,在那里我读取DMA接收字节的数量并处理它们。一切正常工作,直到包中的字节数小于或等于DMA缓冲区大小。否则DMA会奇怪地关闭和跟随空闲线中断给我1,0,0,.DMA接收字节数。下面是代码的一部分,其中我检查DMA缓冲区是否填充并尝试将DMA计数器重置为缓冲区大小:

代码语言:javascript
复制
#define S_M_INPUT_CMD_SIZE 20
static char s_m_uart_dma_in_buff[S_M_INPUT_CMD_SIZE + 1]; 

void USART1_IRQHandler(void)
{
   ITStatus reception_status = USART_GetITStatus(USART1, USART_IT_IDLE);
   if(reception_status != RESET)
   {
      int32_t bytes_number = S_M_INPUT_CMD_SIZE - DMA_GetCurrDataCounter(DMA1_Channel3);            
      if (DMA_GetFlagStatus(DMA1_FLAG_TC3) != RESET)
      {
         USART_ITConfig(UART_, USART_IT_IDLE, DISABLE);
         DMA_Cmd(DMA1_Channel3, DISABLE);
         while (DMA1_Channel3->CCR & DMA_CCR_EN);
         for (int i = 0; i < S_M_INPUT_CMD_SIZE; i++)
            s_m_uart_dma_in_buff[i] = '\0'; 
         DMA_SetCurrDataCounter(DMA1_Channel3, S_M_INPUT_CMD_SIZE); 
         DMA_Cmd(DMA1_Channel3, ENABLE); 
         DMA_ClearFlag(DMA1_FLAG_GL3);
      }
      USART_ClearITPendingBit(UART_, USART_IT_IDLE);
   } 
}

在第一次“溢出”和DMA启用之后,rx寄存器中出现了“缓冲区大小+ 1”字节,之后接收到的字节数稳定为零。我做错什么了?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-01-13 14:03:36

在这里,如果您试图使用代码接收大小大于S_M_INPUT_CMD_SIZE的数据包,会发生什么情况:

  1. DMA完全接收块S_M_INPUT_CMD_SIZE和禁用(非循环模式)
  2. USART1接收一个字节
  3. USART1从数据包中再接收一个字节并删除它们,因为没有人处理UART。
  4. 数据包完成后,您将得到空闲中断并恢复DMA。
  5. DMA读取先前接收的字节
  6. 没有数据包-你得到0,0,.DMA接收字节数

我不得不说,这是处理DMA传输的非常奇怪的方式。DMA传输通常必须在DMA中断处理程序中处理,而不是外围处理。

为了处理长数据包,必须实现DMA中断处理程序。因此,恢复DMA接收比空闲中断更早。因此DMA将准备好从UART接收更多数据。

还有一件事。在您的代码中有一个竞赛。在读取bytes_number和禁用DMA之间,可以通过DMA传输一个或多个字节。

但是更正确的处理UART的方法是在循环模式下运行DMA,而不是重新初始化它。因为每次禁用DMA时,都会丢失一些UART输入。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41635591

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档