历史上的今天
今天是: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这么做的原因是:使用发送中断功能。
史海拾趣
|
用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; ...… 查看全部问答> |
|
求wincewindows ce 虚拟串口对开发思路? 要求windows ce 虚拟串口驱动建立一个虚拟串口对,这个虚拟串口对,是彼此连接的。应用程序,可以其中任何一个串口(com2),写数据,另一个串口com3,读出数据。 大家帮帮忙呀!… 查看全部问答> |
|
wince需要与解码器相连,如果断开时需要有发送不成功的提示,出了系统自带的读写异常还有其他办法来判断发送没有正确呢开发语言是c#现在情况是这样的,我用的是serialport控件,串口线接上以后接收事件就自动触发,但没法判断是不是连接了解码器,所以想 ...… 查看全部问答> |
|
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 ...… 查看全部问答> |
|
WIN7系统下Protel99se添加元件库和封装库,按照此方法32bit/64bit win7系统下都可以成功添加。希望给大家带来帮助。… 查看全部问答> |
|
使用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 ...… 查看全部问答> |




