zoukankan      html  css  js  c++  java
  • STM32库函数void USART_SendData的缺陷和解决方法

    void USART_SendData()函数在快速发送时存在问题 有丢数据的可能

    转自https://blog.csdn.net/qq_27114397/article/details/50601548

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

    如:

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

    USART_SendData(USART1, RxBuffer[TxCounter]);

    原因

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

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

    方案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)

    {

    assert_param(IS_USART_ALL_PERIPH(USARTx));

    assert_param(IS_USART_DATA(Data));

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

    }

    修改后的函数定义体

    void USART_SendData(USART_TypeDef* USARTx, u16 Data)

    {

    assert_param(IS_USART_ALL_PERIPH(USARTx));

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

  • 相关阅读:
    IEEE 网址
    知乎上非常棒的机器学习专栏
    怎样认识比你优秀的人并和他们成为朋友?
    影藏铜皮,显示原点与更改
    PCB检查事项,生成钻孔表
    布局-同样模块复用
    制作DIP Package及DIP焊盘制作,不规则焊盘制作
    制作SMD Package及SMD焊盘制作
    导入网络表
    导入DXF文件
  • 原文地址:https://www.cnblogs.com/xuhongfei0021/p/10526354.html
Copyright © 2011-2022 走看看