历史上的今天
返回首页

历史上的今天

今天是:2025年03月31日(星期一)

正在发生

2020年03月31日 | STM32库函数USART_SendData的缺陷和解决方法

2020-03-31 来源:eefocus

2.1 问题及现象

使用USART_SendData()函数非连续发送单个字符是没有问题的;当连续发送字符时(两个字符间没有延时),就会发现发送缓冲区有溢出现象。若发送的数据量很小时,此时串口发送的只是最后一个字符,当发送数据量大时,就会导致发送的数据莫名其妙的丢失。

如:

for(TxCounter = 0;TxCounter < RxCounter; TxCounter++)

USART_SendData(USART1, RxBuffer[TxCounter]);

 

2. 原因

此API函数不完善,函数体内部没有一个判断一个字符是否发送完毕的语句,而是把数据直接放入发送缓冲区,当连续发送数据时,由于发送移位寄存器的速度限制(与通信波特率有关),导致发送缓冲区的数据溢出,老的数据还未及时发送出去,新的数据又把发送缓冲区的老数据覆盖了。

 

2.3 解决方法(目前总结的两种方案)

 

方案1. 加入延时函数(下下策),不需要修改USART_SendData()函数

for(TxCounter = 0;TxCounter < RxCounter; TxCounter++){

USART_SendData(USART1, RxBuffer[TxCounter]);

DelayMS(2); //加入一个小的延时

}

 

方案2. 修改USART_SendData()函数,在其内部加入发送缓冲区的USART_FLAG_TXE状态检测语句,确保一个字符完全发送出去,才进行下一个字符的发送。


实现方法:每发送一个字符都检测状态寄存器,确保数据已经发送完毕。具体操作步骤如下所示。


修改前的函数定义体

void USART_SendData(USART_TypeDef* USARTx, u16 Data)

{

  /* Check the parameters */

  assert_param(IS_USART_ALL_PERIPH(USARTx));

  assert_param(IS_USART_DATA(Data));

   

  /* Transmit Data */

  USARTx->DR = (Data & (u16)0x01FF);

}

修改后的函数定义体

void USART_SendData(USART_TypeDef* USARTx, u16 Data)

{

  /* Check the parameters */

  assert_param(IS_USART_ALL_PERIPH(USARTx));

  assert_param(IS_USART_DATA(Data));

   

  /* Transmit Data */

  USARTx->DR = (Data & (u16)0x01FF);

  while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET){} //等待发送缓冲区空才能发送下一个字符
}

 

方案3. 不修改原来的库函数,在每一个字符发送后检测状态位。

USART_SendData(USART1, RxBuffer[TxCounter]);

while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET){} //等待发送缓冲区空才能发送下一个字符

 

ST这么做的原因是:使用发送中断功能。

推荐阅读

史海拾趣

Carlisle Interconnect Components公司的发展小趣事

Carlisle Interconnect Components公司深知品质是赢得市场的关键。因此,公司建立了严格的质量管理体系,从原材料采购到生产制造,再到产品出厂,每一个环节都严格把控。这种对品质的执着追求,使得公司的产品在国际市场上获得了良好的口碑。同时,公司还积极拓展海外市场,与多家国际知名企业建立了稳定的合作关系,进一步提升了公司在全球电子连接器市场的影响力。

台湾致强(FORT)公司的发展小趣事

致强科技深知员工是企业持续发展的关键。因此,公司自成立以来便注重企业文化的建设,积极营造和谐、关爱的工作氛围。公司管理层倡导“尊重人性”的理念,不仅为员工提供具有竞争力的薪酬福利,还通过EAP(员工协助计划)等方式关注员工的心理健康和生活需求。EAP项目的实施不仅帮助员工缓解了工作压力,还从多方面提升了员工的归属感和幸福感,为公司的长期发展奠定了坚实的人才基础。

飞翼科技(FEIYI)公司的发展小趣事

面对电子行业的快速发展和市场需求的不断变化,致强科技始终保持敏锐的市场洞察力。公司积极寻求与上下游企业的跨界合作,共同推动产业升级和技术创新。通过与知名电子厂商、科研机构及高校等建立紧密的合作关系,致强科技不断引入新技术、新工艺和新材料,为产品的升级换代提供了有力支持。同时,公司还积极拓展新业务领域,如车联网、物联网等新兴领域,为公司的未来发展开辟了更广阔的空间。

AINFO Inc公司的发展小趣事

为了进一步提升技术水平和市场竞争力,AINFO Inc公司积极寻求与国际知名企业的技术合作。通过与国外企业的合作,公司引进了先进的技术和管理经验,提升了自身的研发能力和管理水平。同时,公司也加快了国际化发展的步伐,拓展了海外市场,提升了品牌知名度。

Analog公司的发展小趣事

随着电子行业的快速发展,AINFO Inc公司积极响应国家产业政策,加快了产业升级的步伐。公司引进了先进的生产设备和技术,实现了智能制造和数字化转型。通过优化生产流程和提高生产效率,公司降低了成本,提高了产品质量,进一步巩固了市场地位。

American Power Management Inc公司的发展小趣事

在电子行业的初期,APMI以一家小型创业公司的身份出现,专注于电源管理技术的研发。当时,市场上的电源管理产品普遍存在效率低下、体积庞大的问题。APMI的研发团队通过深入研究,成功开发出了一款高效、紧凑的电源管理芯片,这一创新为电子产品的小型化和节能化奠定了基础。随着技术的不断完善和推广,APMI逐渐在电源管理领域崭露头角,吸引了众多合作伙伴和投资者的关注。

问答坊 | AI 解惑

关于VGA显示扫描模块

用vga640480这程序  实现一个HS里包含800个CLK  1个VS里包含525个HS library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity vga640480 is   port (clk :in std_logic;   ...…

查看全部问答>

windows ce 虚拟串口对驱动

求wincewindows ce 虚拟串口对开发思路? 要求windows ce 虚拟串口驱动建立一个虚拟串口对,这个虚拟串口对,是彼此连接的。应用程序,可以其中任何一个串口(com2),写数据,另一个串口com3,读出数据。 大家帮帮忙呀!…

查看全部问答>

wince的串口安全判断问题

wince需要与解码器相连,如果断开时需要有发送不成功的提示,出了系统自带的读写异常还有其他办法来判断发送没有正确呢开发语言是c#现在情况是这样的,我用的是serialport控件,串口线接上以后接收事件就自动触发,但没法判断是不是连接了解码器,所以想 ...…

查看全部问答>

求助:Kernel panic

ibblpp> printenvbootargs=noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0bootcmd=nand read.jffs2 0x30007FC0 kernel; bootm 0x30007FC0bootdelay=2baudrate=115200ethaddr=08:00:3e:26:0a:5bipaddr=192.168.7.17serverip=192.168 ...…

查看全部问答>

学完51单片机,下一步PIC,AVR,还是啥呢?

如题,下一步该怎么走,还忘前辈们指教! …

查看全部问答>

WIN7下Protel99se添加元件库和封装库

WIN7系统下Protel99se添加元件库和封装库,按照此方法32bit/64bit win7系统下都可以成功添加。希望给大家带来帮助。…

查看全部问答>

求助啊,很急

昨天刷了一下BOIS,nor flash的,配置什么的都没问题,但是再用ads调试就没有现象了,程序好像正常运行, 就是一个简单的led灯,以前没有问题的,什么办法都用了,还是不行,用jlink调试出现下面提示,请高手看看是怎么回事,很急 其他功能都正常 ...…

查看全部问答>

使用Jlink作为电源为Open1081开发板供电

使用Jlink作为电源为Open1081开发板供电 微雪的Open1081开发板,具备了众多接口和外围设备,结合Core1081核心板,可以提供较全面完整的基于MX1081芯片平台的WIFI物联网设备开发。然而在评估的时候,发现该开发板的一个缺点就是供电方式不是很好 ...…

查看全部问答>

undefined reference to `usb_close'

关于使用libusb的问题。 我在嵌入式的arm板子上编译这个,然后也安装了libusb,而且也链接了-lusb, 但是就是会一直报这样的错,纠结死了。 undefined reference to `usb_close\' undefined reference to `usb_find_busses\' undefined ...…

查看全部问答>

求解答。。。

不知道为什么出现这个问题,老师都觉得我没写错。。。截图我上传到附件了…

查看全部问答>