STM32串口丢失首字符

Preface

最近在搞基于esp8266的服务器框架,发现在进行串口通信的时候出现了丢失第一个字符的现象,最后发现,竟然是stm32自身的问题,特此记录一下。

解决办法

static void myprintf1(char *str)//这是串口发送函数
{
    
    
    USART_ClearFlag(USART1, USART_FLAG_TC); //防止出现stm32第一个字符丢失的现象,添加这一句
    while (*str)
    {
    
    
        USART1->DR = (u8)*str;
        while ((USART1->SR & 0X40) == 0)
            ; //循环发送,直到发送完毕
        str++;
    }
}

问题本质

背景

我们都知道,从编程人员的角度,对外设的控制就是对外设寄存器进行读写。

外设的寄存器无非就三种:

  • 数据寄存器
  • 控制寄存器
  • 状态寄存器

因此,要解决串口发送时丢失第一帧数据,那就是对这三类寄存器的监视。

而我们可以从上面的代码中可以看出,就是状态寄存器的问题。

寄存器

上图就是stm32的状态寄存器:

它这个是stm32参考手册给出的,那是它这个写错了,实际上是:

复位值:0x0000 00C0

还可以从这个地方可以看出来。

有的东西参考手册也是不对的。

如果你不相信,很简单,通过程序验证一下不久可以了。

答案

从上面那幅图我们可以看到,cpu上电复位后的TC状态标志位是1.

static void myprintf1(char *str)//这是串口发送函数
{
    
    
    USART_ClearFlag(USART1, USART_FLAG_TC); //防止出现stm32第一个字符丢失的现象,添加这一句
    while (*str)
    {
    
    
        USART1->DR = (u8)*str;
        while ((USART1->SR & 0X40) == 0)
            ; //特别需要注意的是这个地方
        str++;
    }
}

我们再来看下我们的程序。

当我们向串口发送完第一字符,这个时候由于TC标志位为1,那么程序此时将会直接发送第二个字符,由于cpu的运行频率远大于外设的运行频率,因此上一次发送的数据将回被这一次发送的数据所覆盖。

因此,为了解决这个问题,在每次需要发送数据的时候,将串口状态寄存器的TC状态标志位给清零,这样就不会出现问题了。

猜你喜欢

转载自blog.csdn.net/qq_46359697/article/details/120398274