极海APM32F1xx系列单片机串口RXBNE事件丢失问题

有块板子使用APM32F103RB的USART作为UART全双工串口和PC进行通信,PC上循环发送字符数据到单片机,单片机使用中断模式(只使能RXBNE事件)接收数据:

    if (USART_ReadIntFlag(ptUart, USART_INT_RXBNE))
    {
        /* 检测接收是否有错误发生, 错误事件会在读取数据后自动清掉 */
        dwSTS = ptUart->STS;
        if (dwSTS & USART_FLAG_PE)
            ptStat->dwRxPECnt++;

        if (dwSTS & USART_FLAG_FE)
            ptStat->dwRxFECnt++;

        if (dwSTS & USART_FLAG_NE)
            ptStat->dwRxNECnt++;

        if (dwSTS & USART_FLAG_OVRE)
            ptStat->dwRxOECnt++;

        /* 读取数据 */
        wData = USART_RxData(ptUart);

        ......
    }

在main主循环里面将收到的字符数据再发送出去,即环回给PC,测试发现PC侧发了n个字符数据,但是收到的字符数据少于n个,中间数据丢了,在中断里面增加统计信息,发现中断计数和PC发送的字符个数是一致的,但是RXBNE事件的计数少于中断计数,而且RXBNE事件个数等于PC端收到的字符个数,说明是串口控制器丢了RXBNE事件。

芯片手册上有关RXBNE事件的清除动作是先读取STS寄存器,然后读取DATA寄存器:

 但是DATA寄存器是收发共享的,怀疑是发送数据时写DATA寄存器时把RXBNE事件给清掉了。为了验证我的想法,对中断处理代码进行简化:

串口中断处理里面设置断点,即PC发了一个字符数据给单片机后会停住,然后读取寄存器的值分析
dwSTS = ptUart->STS;            /* 这里读到的值是0xE0,Bit5=RXBNE=1是有事件的 */
USART_TxData(ptUart, 0x55);     /* 然后故意发送一个字符,即随便写个值到DATA寄存器 */
dwSTS = ptUart->STS;            /* 再次读取一次STS寄存器,发现值变成0xD0,RXBNE变0了 */
wData = USART_RxData(ptUart);   /* 此时强行读取一次DATA寄存器值,这个值是PC发的那个字符;
                                   说明控制器内部数据还是收发分开的,并不会串 */

由此可见,写DATA寄存器确实把接收的RXBNE事件给清掉了,这明显是芯片的一个BUG。

看了STM32F103的寄存器也是这样的,估计也会有同样的问题。

而STM32F0系列的芯片手册上UASRT里面已经把DATA寄存器分成RxDATA和TxDATA两个寄存器了,这个系列的芯片不存在该问题。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值