stm32DMA+消息队列实现串口数据接收不丢包

前提:有一个项目一直使用DMA+串口空闲中断接收数据,最近发现串口数据丢包。

经过检查发现串口发送机在发送数据过程中本来应该是连续发送,但是中间有某一个字节与下一个字节之间的间距大于一个字节,MCU端会认为产生了一个空闲中断,便触发,这时候如果软件直接读取数据,很有可能后面的数据就直接丢失,并且原程序设计时候在处理过程中是关闭DMA的,这就会导致串口数据堵塞后面的数据也进不了,表现为串口接不到数据。

为了解决这个问题:修改程序逻辑,将DMA的两个中断(接收完成中断,和接收一半中断使能),在超过一半时即开始接收数据,存入另一个缓冲区,然后DMA继续运行,不影响后续数据接收。

之所以设定接收一半中断是为了加快数据流转,避免占用过多资源。下面看代码。

//定义一个fifo循环里面不断查询是否有数据,并处理

经过试验即使发送端发生数据发送中断,后续数据正常发送时也能保证数据被完整的接收,不会出现丢包现象。

typedef struct
{
    uint8_t  f_cnt;
    uint8_t  r_cnt;
    uint8_t  msgcnt;
    uint8_t  pock;
    uint8_t  usartbuff[USART2_MSG_MAX];
}ST_UartBuffFIFO;
 

//数据包进入队列
uint8_t Sdk_Usart_BuffQueueInsertData(ST_UartBuffFIFO  *pDataQueue , uint8_t *pDatabuff,uint32_t datasize)
{
    if(pDataQueue->msgcnt <USART2_MSG_MAX)
        {
        pDataQueue->pock = 1;
            pDataQueue->msgcnt+= datasize;
            memcpy(&pDataQueue->usartbuff[pDataQueue->r_cnt],pDatabuff,datasize);

            if(pDataQueue->r_cnt >= (USART2_MSG_MAX -1))
            {
                pDataQueue->r_cnt = 0;
            }
            else
            {
                pDataQueue->r_cnt+=datasize ;
            }
        pDataQueue->pock = 0;
            return 1; 
        }

    return 0;
}

//数据包移除队列

uint8_t Sdk_Usart_BuffQueueDeleteData(ST_UartBuffFIFO  *pDataQueue,  uint8_t *pData )
{
    if (pDataQueue->pock == 0)
    {
        if(pDataQueue->msgcnt >0)
            {
                pDataQueue->msgcnt--;
                *pData = pDataQueue->usartbuff[pDataQueue->f_cnt];

                if(pDataQueue->f_cnt >= (USART2_MSG_MAX -1))
                {
                    pDataQueue->f_cnt = 0;
                }
                else
                {
                    pDataQueue->f_cnt++;
                }
                return 1;
                
            }
        else
            {
            //pDataQueue->f_cnt  = pDataQueue->r_cnt;
            pDataQueue->f_cnt  = 0;
            pDataQueue->r_cnt  = 0;
            return 0;
             
    }
    return 0;
}

 

 


 

  • 1
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值