• STM32串口在首次发送字符的时候,首字符丢失解决办法


    网上关于发送字符的代码大多如下:

    USART_SendData(USART1, (uint8_t)ch);
    while( USART_GetFlagStatus(USART1, USART_FLAG_TC) != SET);

    其实咋一看是说的通的,但是在仔细看手册的时候发现 TC 和 TXE 标志位在复位的时候被置1 ,这样第一次while循环就是没有用的。这样导致了首次第一个字符还没有被输出,就被后面的字符覆盖掉,造成实际看到的丢失现象。解决办法就很简单:在前面加上一句 USART1->SR;

    具体代码如下:

    USART1->SR;
    USART_SendData(USART1, (uint8_t)ch);
    while( USART_GetFlagStatus(USART1, USART_FLAG_TC) != SET);

    下面我来说说原因: 第一句读取SR寄存器,第二句写DR寄存器 刚好清除了TC标志位 。第一次while循环就起作用了。


     USART1->SR; 可使用  while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);  代替

    我在使用库函数中的printf函数时,添加的fputc函数。

    int fputc(int ch, FILE *f)
    {
    /* TC TXE 标志位在复位的时候被置1 */
    /*第一句读取SR寄存器,第二句写DR寄存器*/
    /* 如果不这样操作,首次发送的第一个字符会丢失 */
    USART1->SR;
    USART_SendData(USART1, (uint8_t)ch);
    while( USART_GetFlagStatus(USART1, USART_FLAG_TC) != SET);
    return (ch);
    }

    在USART的发送端有2个寄存器,一个是程序可以看到的USART_DR寄存器(下图中阴影部分的TDR),另一个是程序看不到的移位寄存器(下图中阴影部分Transmit Shift Register)。

    对应USART数据发送有两个标志,一个是TXE=发送数据寄存器空,另一个是TC=发送结束;对照下图,当TDR中的数据传送到移位寄存器后,TXE被设置,此时移位寄存器开始向TX信号线按位传输数据,但因为TDR已经变空,程序可以把下一个要发送的字节(操作USART_DR)写入TDR中,而不必等到移位寄存器中所有位发送结束,所有位发送结束时(送出停止位后)硬件会设置TC标志。

    另一方面,在刚刚初始化好USART还没有发送任何数据时,也会有TXE标志,因为这时发送数据寄存器是空的。

    TXEIE和TCIE的意义很简单,TXEIE允许在TXE标志为'1'时产生中断,而TCIE允许在TC标志为'1'时产生中断。

    至于什么时候使用哪个标志,需要根据你的需要自己决定。但我认为TXE允许程序有更充裕的时间填写TDR寄存器,保证发送的数据流不间断。TC可以让程序知道发送结束的确切时间,有利于程序控制外部数据流的时序。

  • 相关阅读:
    PS学习【不间断在本页面更新】
    html5的css3等学习资料网页合集
    分别实现图片沿着XYZ轴旋转的动画
    css3实现循环抖动等动画
    jpg图片隐藏压缩文件
    基础知识【笔记】
    java爬虫,爬取网址、爬取视频、爬取图片
    纯js实现音乐播放的功能
    iOS
    iOS -MVC
  • 原文地址:https://www.cnblogs.com/wwjdwy/p/2951127.html
Copyright © 2020-2023  润新知