打印
[应用相关]

【转】STM32库函数USART_SendData的缺陷和解决方法

[复制链接]
672|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
俺是村长他爹|  楼主 | 2016-10-16 21:20 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
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这么做的原因是:使用发送中断功能。
沙发
309030106| | 2016-10-18 22:00 | 只看该作者
当连续发送字符时(两个字符间没有延时),就会发现发送缓冲区有溢出现象
的确是这个问题

使用特权

评论回复
板凳
俺是村长他爹|  楼主 | 2016-10-22 00:31 | 只看该作者
309030106 发表于 2016-10-18 22:00
当连续发送字符时(两个字符间没有延时),就会发现发送缓冲区有溢出现象
的确是这个问题 ...

使用特权

评论回复
地板
294479435| | 2016-10-22 10:54 | 只看该作者
楼主分析的很详细,学习了

使用特权

评论回复
5
CallReceiver| | 2016-10-22 11:15 | 只看该作者
修改USART_SendData()函数,在其内部加入发送缓冲区的USART_FLAG_TXE状态检测语句

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

66

主题

168

帖子

2

粉丝