你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32F103 串口DMA+IDLE收发,速率过快会造成overrun

[复制链接]
小耳朵1500922649 提问时间:2019-3-20 10:36 /
串口通讯是比较常用的通讯方式,本人以前都是单字节中断接收,再开启一个定时器做空闲判断,和PC端做2ms收发无压力。这样做在高速度通讯过程中MCU会频繁进入接收中断,故而想测试一下DMA+IDLE, 收发都通过DMA,DMA每次接收最大数是64,进入IDLE中断后,从串口缓冲拷贝数据。在27字节收发测试时,PC发送一帧(27字节)的速率10 ms以上时,数据收发正常,而低于10ms后,PC端接收的帧数明显少于发送的帧数,而当发送速率设置为2ms时,PC端就无任何数据接收了。STM32 DEBUG发现串口overrun err,数据溢出,也就是MCU还没来得及拷贝数据,下一帧数据就已经到来了。测试code如下:
//DMA发送
void Usart1SendData_DMA(uint8_t *pdata, uint16_t Length)
{
        HAL_StatusTypeDef res;
        uint8_t retry=0;
        //while(UsartType1.dmaSend_flag == USART_DMA_SENDING);
        //UsartType1.dmaSend_flag = USART_DMA_SENDING;
        do
        {
                UsartType1.dmaSend_flag = USART_DMA_SENDING;
                res = HAL_UART_Transmit_DMA(&huart1, pdata, Length);
                if(res == HAL_OK)
                {
                        UsartType1.dmaSend_flag = USART_DMA_SENDOVER;
                }
                       
                        if(retry++>4) //3次尝试发送
                        {
                                return;
                        }
        }while(res != HAL_OK);
}

//DMA发送完成
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
        __HAL_DMA_DISABLE(huart->hdmatx);//关闭发送DMA
}

//串口接收空闲中断,检测到一个byte的高电平触发
void UsartReceive_IDLE(UART_HandleTypeDef *huart)
{
        uint32_t temp;

        if((__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE) != RESET))
        {
                __HAL_UART_CLEAR_IDLEFLAG(&huart1);
                HAL_UART_DMAStop(&huart1);
                //temp = huart1.hdmarx->Instance->CNDTR;// 获取DMA中未传输的数据个数
                temp = __HAL_DMA_GET_COUNTER(huart1.hdmarx);// 获取DMA中未传输的数据个数
                UsartType1.rx_len =  RECEIVELEN - temp;
                DataCpy(UsartType1.usartDMA_rxBuf, UsartType1.rx_len);
                UsartType1.receive_flag=true;
                HAL_UART_Receive_DMA(&huart1,UsartType1.usartDMA_rxBuf,RECEIVELEN);
        }
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{

}


//主循环检测空闲并发送
while (1)
  {
  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */
        if(UsartType1.receive_flag)//如果产生了空闲中断
                {
                        UsartType1.receive_flag=false;//清零标记
                        Usart1SendData_DMA(uu_rxfifo.buffer ,27);//串口打印收到的数据。

                }
}

void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */
        UsartReceive_IDLE(&huart1);
  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */

  /* USER CODE END USART1_IRQn 1 */
}

收藏 评论2 发布时间:2019-3-20 10:36

举报

2个回答
奏奏奏 回答时间:2019-3-20 11:25:25
自己用RAM容量做消息队列缓存,并控制收与发的时间间隔。
xiaoxiao0932 回答时间:2019-8-16 09:40:25
楼主是否解决此问题,我也遇到类似问题,pc端10ms发送100字节,板子DMA乒乓方式接收后,发送到pc,PC端接收的数据和发送的数据个数不一致

所属标签

相似问题

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版