STM32之USART库函数USART_SendData的bug

发布者:精灵宠儿最新更新时间:2016-06-13 来源: eefocus关键字:STM32  USART  库函数  bug 手机看文章 扫描二维码
随时随地手机看文章
1.最近在调试ATM32F103CB时发现,一串数据的最后一个字节总是发送不出去,用的是RS485收发;

2.代码如下:

    void uartReturn(unsigned char childBoardAddr)

 uchar temp = 0;  //must have
  
 temp += 0xAB;
  temp += childBoardAddr;
  temp += 0x30;
  temp += 0x01;
  temp += childBoardAddr;
 
 RS485_TX_EN;  //enable rs485 tx 
 
 sendByte(0xAB);
 sendByte(childBoardAddr);
 sendByte(0x30);
 sendByte(0x01);
 sendByte(childBoardAddr);
 sendByte(temp);
 
 RS485_RX_EN;  //enable rs485 rx 
}

其中:sendByte函数如下:

  void  sendByte( unsigned char data)
{
  //RS485_TX_EN; 
  USART_SendData( USART2,data );
  while( USART_GetFlagStatus( USART2,USART_FLAG_TXE ) == RESET ); //数据没有被传入输出移位寄存器,则一直等待下去 
  //RS485_RX_EN;
}

同事帮忙改了一下lib库函数:USART_SendData,在其后面加了: while((USARTx->SR&0x40)==0);//////////发现最后一字节数据会漏发,才加上的;

这调语句可不就是等价于:while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET)吗;

>>>>>>>>来看看网上是怎么说的?

用串口连续发送一串数字时,第一个数总是发不出去,我用STM32F103ZE,STM32F103CB都是这样的情况,以下是代码:
USART_SendData(USART1,0x06);while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);
USART_SendData(USART1,0x07);while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);
USART_SendData(USART1,0x08);while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);

,第一字节发送不出去,看网友是怎么分析解答的吧:

1:这个问题的根本原因是复位后,TC和TXE标志位默认都是1,很多人喜欢这样写: 
    USART_SendData(USART1, (u8) ch);  while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)  
    while在发送第一个字节时没有起到应有作用,直接跳出,接着写第二个字节,这时第一个字节还未发出,数据被破坏了.

看看datasheet,果然复位以后,SR=0x00c0;TC=TXE=1;

疑问:为什么网友说:只要第一个用TXE,其它用什么标志无所谓,都能正常发送。按道理,TXE也没起到保护啊!!!

2.while的确很费时,另外当TDR寄存器中的数据被硬件转移到移位寄存器的时候,TXE被硬件置位(注意:单缓冲器传输中使用该位);当包含有数据的一帧发送完成后,并且TXE=1时,由硬件将该位置’1’,只有在多缓存通讯中才推荐这种清除程序。其中TC判断的是一帧数据,而TXE是当TDR数据传到移位寄存器就被置位了,所以TC的时间比较长,很容易被下一次数据覆盖~~~所以一般喜欢判断TXE,数据写到DR就可以了 ,剩下的工作就交给硬件了

3.一般的用TXE就可以了, TC一般用于需要延时的场合,比如说是232/485转换器,需要得到TC后,才能将发送改变成接收,否则最后一个字节发送不完全。

 看来,3很符合我的情况:我的相当于2个等待:

        while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET;   //@1

        while( USART_GetFlagStatus( USART2,USART_FLAG_TXE ) == RESET ); //@2

考虑一下:@2能不能拿掉呢??

关键字:STM32  USART  库函数  bug 引用地址:STM32之USART库函数USART_SendData的bug

上一篇:STM32 位带应用
下一篇:STM32 串口中的硬件BUG,注意!

推荐阅读最新更新时间:2024-03-16 14:57

关于STM32的计数与延时
Ⅰ关于STM32的计数和延时 在STM32中,具有计数(或计时)功能的模块基本都能实现延时功能。如:系统滴答SysTick、定时器TIM、实时时钟RTC、看门狗WDG。 精确延时一般使用定时器TIM即可实现。当然,是否精确,取决于你的主频(也就是晶振)是否准确,如果主频精确,那么实现的延时也一定精确。 一般来说,常温下实现us微秒级的延时,误差还是挺小的(应该说挺精确)。拿F407,主频168M来说,可以实现几十ns纳秒的延时,如果选用高精度的晶振,误差还是很小的。 总结:想要TIM定时器实现高精确的延时,就需要高精度的晶振。主频精确,那么延时就精确。 ⅡSTM32的TIM定时器 STM32的定时器有3类: 高级定
[单片机]
关于<font color='red'>STM32</font>的计数与延时
STM32--MDK仿真调试:逻辑分析仪的使用
在调试Debug环境下: 1.view--Analysis Windows--Logic Analyzer //调用逻辑分析仪 2.单击逻辑分析仪窗口右上角的“Setup…(setup logic analyzer)”进行设置:设置监视分析的引脚。 例:我想看看PORTB.5引脚的仿真情况: 在“current logic analyzer signals”--插入“PORTB.5”,然后它会自动转换成(PORTB &0x00000020) 5形式,即:只保留第5引脚的值,其他引脚清零; 在signal Display--Display Type:设置为bit/color:设置显示的颜色。 3.run运行一
[单片机]
STM32 YMODEM实现bootloader
这几天一直在尝试学STM32 bootloader,在网上查阅了一番,发现实现方法不计其数。于是自己有了想动手实现一番的欲望。 下面请听我细细道来,我选用的芯片是STM32F103ZE系类,该芯片是512k,每页是2k的。 接下来就是你要重点了: 其实bootloader说白了,就是在原有APP程序 再加上另一段程序---bootloader,这个bootloader可以对你flash进行擦写操作。 那么关于STM32具体实现BOOTLOADER步骤是怎么样的呢? 下面我就具体几个细节之处谈谈: 1,如何实现在APP程序跳转到BOOTLOADER程序. 2,既然APP程序可以跳转到bootloader
[单片机]
<font color='red'>STM32</font> YMODEM实现bootloader
使用STM32实现PMSM电机的正弦驱动
Microchip 的应用笔记 AN1017 讲述了一种使用空间矢量调制(Space Vector Modulation,SVM)方法产生用于驱动 PMSM 电机各相的正弦电流,以此驱动具有霍尔位置传感器的永磁同步电机(Permanent Magnet Synchronous Motor,PMSM)的控制算法,其配套的开源算法采用 dsPIC® 数字信号控制器实现,此前在淘宝购入了一块基于 STM32 的无刷直流电机开发板,于是试着将该开源代码移植至手上这块开发板上。开发板如下图所示: 中断服务程序一览表 中断 何时调用 执行操作 TIM1 20kHz 根据当前位置使用 SVM 产生正弦波 TIM2 1kH
[单片机]
使用<font color='red'>STM32</font>实现PMSM电机的正弦驱动
STM32使用虚拟示波器
在调试过程中.,经常会有需要看到数据实时变化的情况,这时候便需要用到虚拟示波器。如:制作平衡车时,需要了解拟合角度跟随加速度计和陀螺仪的动态变化情况;做电机PWM调速时需要了解速度的变化曲线等。 对于虚拟示波器的选择,由于之前参加过飞思卡尔,用过是山外的多功能调试助手中的虚拟示波器,感觉还不错。 现在想用stm32制作一个平衡车,需要用到虚拟示波器,现在把使用方法分享出来,给那些有需要的人。 首先是通信协议:(下面是虚拟示波器部分的通信协议) 虚拟示波器采用串口通信的方式和下位机通信。因此首先要配置好串口(这里就不做介绍了),接下来便需要实现发送函数。 ///发送一个字节的数据 void usart3_send_c
[单片机]
<font color='red'>STM32</font>使用虚拟示波器
stm32 - keil中启动文件的选择和固件库宏定义
● 启动文件的选择 1. Low-density devices (STM32F10nx4 = 16k, STM32F10nx6 = 32k) - startup_stm32f10x_ld_vl.s: 小容量超值型。STM32F100xx系列,闪存16k~32k字节。 - startup_stm32f10x_ld.s: 小容量型。STM32F101xx, STM32F102xx, STM32F103xx系列,闪存16k~32k字节。 2. Medium-density devices (STM32F10nx8 = 64k, STM32F10nxB = 125k) - startup_stm32f10x_md_vl.s: 中
[单片机]
<font color='red'>stm32</font> - keil中启动文件的选择和固件库宏定义
STM32单片机定时器调试之方波输出
今天试着让STM32的定时器输出50%占空比信号,按照例程写了一下方波初始化函数,例程用的是STM32自带库函数,由于嫌麻烦,我又自己写了一个简单的,采用定时器1进行输出。结果一上来,没反应,修改了很多参数,还是没反应,然后将开发板例程写进芯片后,有反应 ,仔细越多数据手册,没有问题,纠结一上午,中午吃饭。吃完饭后,下午又开始试验,还是别人程序有反映,自己程序,没反应。再看了看,开发板程序使用的是TIM3,而我使用的是TIM1,于是又把我的程序将TIM1换成TIM3,点击调试运行,有反应 。不会是高级定时器只能干高级的任务吧,像输出方波这么简单的低级任务他不惜的干?郁闷了半天。后来通过在网上查找,这个程序 以下为源代码,CC1进行比
[单片机]
应用笔记 | 关闭SPI会导致WRPERR错误的问题分析
01 引言 在STM32的应用中,SPI算是用的比较多的外设了,也是单片机最常见外设之一。客户说它执行了关闭SPI的代码,竟然会导致Flash中的WRPERR标志置位,致使应用碰到一些问题。这就奇怪了,SPI和内部Flash看起来是风马牛不相及的事情,为什么会发生这种事呢?一起来看看吧。 02 问题 2.1 问题起源 客户在使用STM32L072RBT6的时候,使用STM32 CubeL0库,在程序编写时,发现执行关闭SPI代码时,会导致Flash的写保护错误标志WRPERR置位,导致其后面准备写EEPROM的时候,就无法对EEPROM写入了。 客户使用两个标志flag1和flag2,来观察WRPERR标志的变
[单片机]
应用笔记 | 关闭SPI会导致WRPERR错误的问题分析
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

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