1. 问题及现象
使用USART_SendData()函数非连续发送单个字符是没有问题的;当连续发送字符时(两个字符间没有延时),就会发现发送缓冲区有溢出现象。若发送的数据量很小时,此时串口发送的只是最后一个字符,当发送数据量大时,就会导致发送的数据莫名其妙的丢失。
如:
1
2
|
for(TxCounter = 0;TxCounter < RxCounter; TxCounter++)
USART_SendData(USART1, RxBuffer[TxCounter]);
|
2. 原因
此API函数不完善,函数体内部没有一个判断一个字符是否发送完毕的语句,而是把数据直接放入发送缓冲区,当连续发送数据时,由于发送移位寄存器的速度限制(与通信波特率有关),导致发送缓冲区的数据溢出,老的数据还未及时发送出去,新的数据又把发送缓冲区的老数据覆盖了。
3. 解决方法
发送后等待一段时间延迟的方法就不说了,等待时间不确定,此为下下策。提供下面2种方案:
方案1. 在每一个字符发送后检测状态位
USART_SendData(USART1, RxBuffer[TxCounter]);
while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET){} //等待发送缓冲区空才能发送下一个字符
方案2. 修改库函数
修改USART_SendData()函数,在其内部加入发送缓冲区的USART_FLAG_TXE状态检测语句,确保一个字符完全发送出去,才进行下一个字符的发送。
实现方法:每发送一个字符都检测状态寄存器,确保数据已经发送完毕。具体操作步骤如下所示。
修改前的函数定义体
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
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);
}
|
修改后的函数定义体
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
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){} //等待发送缓冲区空才能发送下一个字符
}
|
可能有人认为,为什么不预先在库函数中处理这个问题,而把解决方法抛给用户。个人认为ST这么做的原因是:使用发送中断功能。
STM32库函数USART_SendData问题和解决方法 | 小谢的小站 http://blog.xieyc.com/stm32-lib-function-usart-send-data-problem-and-solution/
关键字:STM32 库函数
引用地址:
STM32库函数USART_SendData问题和解决方法
推荐阅读最新更新时间:2024-03-16 14:49
【库函数版本】基于STM32F103的MPU6050的原始数据读取程序详解
因为我的博客已经对I2C协议的详细过程已经做了一个例子!所以这个MPU6050的程序我将使用库函数完成! 第一步:硬件连接: 第二步:初始化I2C端口的函数: /***PB6/PB7 端口初始化****/ static void I2C_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOB,ENABLE ); RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE); GPIO_InitStructure.GP
[单片机]
STM32 USB虚拟串口问题汇总
汇总1:STM32的USB例程修改步骤,来自http://blog.csdn.net/cy757/archive/2010/01/01/5117610.aspx 以下是笔者将ST的Custom_HID例程修改为“自定义USB设备”例程时总结出来的,因为笔者也是刚刚学USB开发不久,某些方面理解错误在所难免,请各位大虾指正。 一、usb_desc.c文件 根据你程序使用的通信方式修改。usb_desc.h文件中定义要根据usb_desc.c文件中的数组的大小;ConfigDescriptor 下添加需要处理的端点;根据需要添加或删除报告描述符(主要用于HID)和CDC接口描述符(主要用于实现USB转串口)等。具体方法可以下载个“
[单片机]
《如何制作STM32开发板》之串口
一说到串口,大家应该在脑海中出现下面这个画面就对了: 看到没有,这就是正儿八经的串口。在现在的工控机上,和以前的家用电脑上,都有串口,现在的家用电脑上,已经没有串口了。(千万不要把VGA口看成串口,VGA口是15针,串口是9针) 我们要搞单片机,就必须会用串口。所以,开发板上,就必须要有学习串口的功能。 串口的硬件应用,现在最多的有3种: USB转TTL串口 232串口 485通信 在我们的开发板上,把这3种功能都实现。 一、USB转TTL串口 这个功能,在讲程序下载方式的那一篇文章已经讲过了。STM32VET6有5个串口,但是只有串口1可以下载程序,所以我们默认把USART1与CH340G转成的RXD和TXD放到一起
[单片机]
STM32 之 SysTick
感觉定时1秒还是有点不准,仅为目测,下次用示波器去测量下。 包含文件: (1)Main C语言: Codee#14620 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 实验平台 : ST 官方三合一套件 + 硬件 : STM32F103C8T6 + 开发平台 : IAR For ARM 5.40 + 仿真器 : J-Link + 日期 : 2010-10-26 + 频率 :HSE = 8MHz ,主频 = 72MHz +++++++++++++++++++++++++++++++++++
[单片机]
STM32的输入捕获
实验目的: 在串口调试助手上打印出按键按下的时间 实验步骤: 实验程序: /*******************************timer.c********************************/ #include sys.h #include stm32f4xx.h extern u8 TIM5CHA1_CAPTURE_STA; extern u16 TIM5CHA1_CAPTURE_VAL; /* 本示例的作用就是, 当按键按下时,每次输入捕获的时间差, 然后从串口调试助手中打印出其时间差; */ /*
[单片机]
意法半导体发布STM32 MCU图形界面设计软件TouchGFX 4.20版
STM32 用户界面设计环境新增屏幕旋转和纹理映射功能,支持性能强大的 Neochrom 图形加速器 中国,2022年8月16日---- 服务多重电子应用领域、全球排名前列的半导体公司意法半导体(STMicroelectronics,简称ST;) 公布了STM32 微控制器图形用户界面设计软件TouchGFX 4.20版。最新的软件更新支持意法半导体新推出的 Neochrom 图形加速器。新款图形加速器集成在意法半导体的先进微控制器产品中,例如STM32U5系列。 意法半导体 Chrom-ART Accelerator™ 图形加速技术可以处理像素和形状,源自这项技术的Neochrom支持全屏旋转到任何角度,并支持纹理
[单片机]
GPIO工作模式详解
STM32中每组由16个IO,不同的型号IO分组不一样,比如STM32F407ZGT6 一共有7组IO口, 每组IO口有16个IO, 一共16X7=112个IO,外加2个PH0和PH1,一共114个IO口。分别是GPIOA,GPIOB---GPIOG,外加2个PH0和PH1 一、GPIO介绍 GPIO:就是一个引脚作为输入或者输出。 GPIO的八种工作模式:输入输出是相对于CPU,四种输入、四种输出模式及四种输出最大速度 输入:外部数据输入到开发板 输出:开发板的数据输出到外部设备 (1) GPIO_Mode_AIN 模拟输入 将IO口作为模拟输入接口,输入的可能是变化的值,接收外部的模拟信号输入 (2) GPIO_Mo
[单片机]
STM32待机模式测试
环境: 主机:XP 开发环境:MDK4.10 单片机:STM32F103C8 功能: 开启RTC闹钟,然后进入待机模式,用闹钟唤醒后退出. 说明: 1.RTC闹钟唤醒事件发生时,同时进入闹钟中断,必须在初始化时与外部中断线17关联 2.如果仅想退出待机模式,RTC闹钟事件已经足够,不必与外部中断线17关联 3.退出待机模式后,接下来的流程类似于按下复位按键,程序会从头开始执行 源代码: 初始化时钟,配置时钟为内部时钟LSI,配置RTC闹钟唤醒以及外部中断线17 void RTC_Configuration(void) { //定义中断结构体 NVIC_InitTypeDef NVIC_
[单片机]