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

发布者:WhisperingWinds最新更新时间:2017-11-03 来源: eefocus关键字: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可以让程序知道发送结束的确切时间,有利于程序控制外部数据流的时序。


关键字:STM32  串口  发送字符  首字符丢失 引用地址:STM32串口在首次发送字符的时候,首字符丢失解决办法

上一篇:STM32 输入捕获 测量频率 PWM占空比
下一篇:关于STM32中断的部分理解

推荐阅读最新更新时间:2024-03-16 15:42

【菜鸟入门】stm32的第一个程序--LED
经过今天一天的努力终于完成了我的stm32第一个程序;我也是今天才开始接触stm32。 由于苦于没有资料,木有例程,找到的例程都是带有库的,这样对stm32基础的管脚配置就不容易懂了,主要是没有一个具体的轮廓。 经过对库文件的研究,和看了好几节视频,又根据自己以前搞430和arm9的经验,就按着以前的思路进行研究,终于开发出自己的第一个LED程序; 1、创建工程 (1)Project -- New uvision Project (2)选择工程要保存的地方 (3)选择CPU (4)选择“是”(如果你使用从STM下载的库的话,就选“否”) (5)修改一下代码(如果不注视掉红色部分,会出现错误)
[单片机]
STM32的ADC编程方法总结
这里的ADC转换也来使用DMA---这个也是STM32的ADC转换最常见的方式。 第一步是了解STM32的ADC对应的GPIO口如下图不用记住,可以查询,我是将它剪下来粘贴到书本的相应章节! 第二步是配置相应ADC转换的GPIO口这里使用PC0--PC1 static void ADC1_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //打开DMA1的时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 “ RCC_APB
[单片机]
使用74LS164将AVR的串口输出扩为并口输出
系统功能 使用74LS164将AVR的串口输出扩为并口输出。 硬件设计     AVR主控电路原理图 串行输出扩展为并行输出芯片74LS164控制电路原理图 软件设计 下面部分从TXT拷出,拷到网页,代码部分缺省了很多空格,比较凌乱,请谅解! //目标系统: 基于AVR单片机 //应用软件: ICC AVR /*01010101010101010101010101010101010101010101010101010101010101010101 ---------------------------------------------------------------------- 实验内容: 使用PB口
[单片机]
使用74LS164将AVR的<font color='red'>串口</font>输出扩为并口输出
STM32 内部flash的读写程序
/* Base address of the Flash sectors */ #define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base @ of Sector 0, 16 Kbytes */ #define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08004000) /* Base @ of Sector 1, 16 Kbytes */ #define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08008000) /* Base @ of Sector 2, 16 Kbytes */ #de
[单片机]
STM32 嵌入式学习入门(2)——STM32的GPIO介绍
GPIO:General Purpose Input Output ,即通用输入/输出,简称为GPIO。 GPIO应该是学习单片机、学习嵌入式、学习STM32的第一个知识点了。在介绍GPIO相关的内容前,这里先总得说一下自己对GPIO的理解。对于初学者,可以把GPIO的作用想象成C语言里面的做输入输出的函数(scanf(); printf(); gets(); puts();等等),在C语言里面scanf()和printf()这两个函数是做输入输出的,对于几乎所有的C语言程序,都可以看成是用输入函数读取了一些输入,然后进行程序的逻辑处理,最后通过输出函数把程序最后执行的结果显示出来的过程。 同样地,这可以类比到嵌入式系统上
[单片机]
STM32F030学习之串口收发程序
使用USART最简单的情况是只使用3根线:Tx用于 数据发送,Rx用于数据接收,GND是信号地线,提供通信双方的参考电平。 实现的功能: 1、通过串口发送数据; 2、中断方式接收数据,并将接收到的数据回送。 首先,第一步:配置引脚,将串口映射到PA9(Tx),PA10(Rx)。 void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; /* Connect GPIOs to USART1 RX&TX */ GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_1); //Tx GPIO_Pin
[单片机]
STM32一个Timer输出4路不同频率、可调占空比的PWM
main.c /********************************************* 标题:操作USART的练习 软件平台:MDK-ARM Standard Version4.70 硬件平台:stm32f4-discovery 主频:168M Periph_Driver_version: V1.0.0 描述:用一个定时器(TIM3),实现四路不同频率、占空比可调的PWM 代码参考自STM32F4-Discovery_FW_V1.1.0\Project\Peripheral_Examples\TIM_TimeBase author:大舟 data:2013-04-13
[单片机]
stm32的八种GPIO配置模式
1. 模拟输入; 2. 浮空输入; 3. 上拉输入; 4. 下拉输入; 5. 开漏输出; 6. 推挽输出; 7. 复用开漏输出; 8. 复用推挽输出 具体的: 1.模拟输入 从上图我们可以看到,我觉得模拟输入最重要的一点就是,他不经过输入数据寄存器,所以我们无法通过读取输入数据寄存器来获取模拟输入的值,我觉得这一点也是很好理解的,因为输入数据寄存器中存放的不是0就是1,而模拟输入信号不符合这一要求,所以自然不能放进输入数据寄存器。该输入模式,使我们可以获得外部的模拟信号。 2.浮空输入 该输入状态,我的理解是,它的输入完全由外部决定,我觉得在数据通信中应该可以使用该模式。应为在数据通信中,我们直观的理解就是线路两端连接着发送端
[单片机]
<font color='red'>stm32</font>的八种GPIO配置模式
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved