单片机
返回首页

STM32库函数void USART_SendData()的缺陷和解决方法

2021-05-18 来源:eefocus

简介:本文主要谈到了STM32库函数void USART_SendData()存在的一些问题,针对这些问题提到了3个解决方案,一起来看看。


2.1问题及现象


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


如:


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


USART_SendData(USART1, RxBuffer[TxCounter]);


2.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这么做的原因是:使用发送中断功能。


进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • 红外线探测报警器

  • 短波AM发射器电路设计图

  • RS-485基础知识:处理空闲总线条件的两种常见方法

  • 如何调制IC555振荡器

  • 基于ICL296的大电流开关稳压器电源电路

  • 基于TDA2003的简单低功耗汽车立体声放大器电路

    相关电子头条文章