STM32库函数USART_SendData问题和解决方法

合集下载

STM32串口第一个字节丢失问题的分析过程

STM32串口第一个字节丢失问题的分析过程

STM32 串口第一个字节丢失问题的分析过程
STM32 串口发送必须先检测状态,否则第一个字节无法发出,发送完
毕,必须检测发送状态是否完成,否则,发送不成功,使用stm32f10x 调试
串口通讯时,发现一个出错的现象,硬件复位重启之后,发送测试数据0x01
0x02 0x03 0x04..接收端收到的数据为:0x02 0x03 0x04,第一个数据丢失。

换成发送别的数值的数据,如0x06 0x0ff,则接收到0x0ff,0x06 丢失。

错误依旧。

故障排除过程:
1、刚开始怀疑是接收端的错误,我是使用电脑串口,运行串口辅助调试工
具接收,换成其他软件后,发现故障依旧,而且电脑软件一直是开启状态,
不像和电脑软件有关。

2、使用单步调试,单步运行各个发送指令,都正常。

能收到0x01 0x02 0x03 0x04 的数据。

间接的排除了不是电脑软件的问题,而是其他的错误。

3、单步调试运行虽然正常了,但连续运行时,错误依旧。

现在有点摸不到
头绪了,单步运行正常,看起来编程没有出错,那故障在哪里呢?测试程序如

USART_SendData(USART2, 0x01); //A。

stm32-串口实验遇到的问题

stm32-串口实验遇到的问题

stm32-串⼝实验遇到的问题
1.Printf函数不能在调试助⼿⾥正常打印?
前提是已经重定向了printf到串⼝,⽽且已经在option⾥勾上了use microlib,⼀切配置都毫⽆问题,在main.c⾥简单printf(“balabala”);却不能在调试助⼿⾥打印出来,点发送也只能发送在调试界⾯输⼊的内容;
2.解决⽅案
(1)将连接电脑的串⼝线,拔⼀下,再插⼀下,点击发送,打印就OK了;
(2)上⾯这种⽅法⽐较笨重,还有⼀种简单的⽅法:直接reset,就会直接答印了;
3.分析
实质上两种⽅法有根本的区别,读者⾃⾏实验判断;由于我是⽤串⼝烧写程序的,在烧写时会关闭调试助⼿的串⼝,等烧写完再打开调试助⼿的串⼝,在这段时间内,⼀条printf打印信息已经被发送完了,但根本没被调试助⼿接收到,所以只要reset⼀下,就会马上打印你想输出的信息了;
4.总结
⼀开始以为是调试助⼿的问题,到处下载其他的调试助⼿,实则结果都⼀样;然后再排查程序的问题(重定向),也没问题;再着查看配置的问题,⽐如引脚的配置,波特率的配置,也都没问题;最后偶然插拔了⼀下usb线就可以了解决问题了;再最后发现reset更为有效。

所以通过以上步骤可以发现,遇到问题,只要⼀⼀排查所有的可能性,最终是会发现答案的。

stm32串口发送字符串STM32串口发送注意问题

stm32串口发送字符串STM32串口发送注意问题

stm32串口发送字符串STM32串口发送注意问题导读:就爱阅读网友为您分享以下“STM32串口发送注意问题”资讯,希望对您有所帮助,感谢您对的支持!使用stm32f10x调试串口通讯时,发现一个出错的现象,硬件复位重启之后,发送测试数据0x01 0x02 0x03 0x04..接收端收到的数据为:0x02 0x03 0x04,第一个数据丢失。

换成发送别的数值的数据,如0x06 0x0ff,则接收到0x0ff,0x06丢失。

错误依旧。

故障排除过程:1、刚开始怀疑是接收端的错误,我是使用电脑串口,运行串口辅助调试工具接收,换成其他软件后,发现故障依旧,而且电脑软件一直是开启状态,不像和电脑软件有关。

2、使用单步调试,单步运行各个发送指令,都正常。

能收到0x01 0x02 0x03 0x04的数据。

间接的排除了不是电脑软件的问题,而是其他的错误。

3、单步调试运行虽然正常了,但连续运行时,错误依旧。

现在有点摸不到头绪了,单步运行正常,看起来编程没有出错,那故障在哪里呢?测试程序如下USART_SendData(USART2, 0x01); //Awhile(USART_GetFlagStatus(USART2,USART_FLAG_TC) == RESET); //BUSART_SendData(USART2, 0x02); //Cwhile(USART_GetFlagStatus(USART2,USART_FLAG_TC) == RESET);USART_SendData(USART2, 0x03);while(USART_GetFlagStatus(USART2,USART_FLAG_TC) == RESET);USART_SendData(USART2, 0x04);while(USART_GetFlagStatus(USART2,USART_FLAG_TC) == RESET);4、猜测,也许是因为某个特殊原因,使第二个数据覆盖了首个数据,使得首个数据丢失。

STM32程序添加printf后无法运行的解决方法

STM32程序添加printf后无法运行的解决方法

STM32程序添加printf后无法运行的解决方法标准库函数的默认输出设备是显示器,要实现在串口或LCD 输出,必须重定义标准库函数里调用的与输出设备相关的函数.例如:printf 输出到串口,需要将fputc 里面的输出指向串口(重定向),方法如下:#ifdef __GNUC__/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf set to Yes) calls __io_putchar() */#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)#else#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)#endif /* __GNUC__ */ PUTCHAR_PROTOTYPE{/* Place your implementation of fputc here *//* e.g. write a character to the USART */USART_SendData(USART1, (uint8_t) ch);/* Loop until the end of transmission */while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);return ch;}因printf()之类的函数,使用了半主机模式。

使用标准库会导致程序无法运行,以下是解决方法:方法1.使用微库,因为使用微库的话,不会使用半主机模式.方法2.仍然使用标准库,在主程序添加下面代码:#pragmaimport(__use_no_semihosting)_sys_exit(intx){x=x;}struct__FILE{inthandle;/ *Whateveryourequirehere.Iftheonlyfileyouareusingis*//*standardoutputusingprintf()f ordebugging,nofilehandling*//*isrequired.*/};/*FILEistypedefdinstdio.h.*/FILE__std out;tips:感谢大家的阅读,本文由我司收集整编。

STM32调试过程中常见的问题及解决方法

STM32调试过程中常见的问题及解决方法

一、在“Debug选项卡”下设置好仿真器的类型后,下载程序时却提示“No ULINK Device found.”解决办法:Keil MDK默认使用ULINK仿真器下载程序,在“Utilities选项卡”下把编程所使用的仿真器改为相应的类型即可。

二、编译工程时提示如下信息:main.axf: Error: L6218E: Undefined symbol __BASEPRICONFIG (referred from stm32f10 x_nvic.o).main.axf: Error: L6218E: Undefined symbol __GetBASEPRI (referred from stm32f10x_nvi c.o).main.axf: Error: L6218E: Undefined symbol __RESETFAULTMASK (referred from stm32f 10x_nvic.o).main.axf: Error: L6218E: Undefined symbol __RESETPRIMASK (referred from stm32f10x _nvic.o).main.axf: Error: L6218E: Undefined symbol __SETFAULTMASK (referred from stm32f10x _nvic.o).main.axf: Error: L6218E: Undefined symbol __SETPRIMASK (referred from stm32f10x_n vic.o).解决办法:工程缺少“cortexm3_macro.s”文件,把cortexm3_macro.s和STM3210x.s全部添加到工程即可。

三、调试器不能连接到STM32的问题与解决办法很多人都碰到过调试器不能连接到STM32的问题,不管是IAR的J-Link还是Keil的ULink,或者是ST的ST-Link。

STM32之HAL库串口USART丢数据及ORE卡死的解决方案

STM32之HAL库串口USART丢数据及ORE卡死的解决方案

STM32之HAL库串口USART丢数据及ORE卡死的解决方案刚装了VS2019Preview,VS2017系列应该还有最后一章就结束了,找个时间结束掉它。

昨晚弄了下STM32的串口通信,发现UART在接收PC串口调试助手发送的数据的时候,会时不时卡死,不能接收新的数据。

之前公司有人做这方面的项目的时候也是这个情况,当时发现UART处于ORE(overrun error)状态,归结为波特率太高,降低波特率算妥协了。

结果自己弄Nucleo的开发板也出现这个情况,我想STM官方开发板应该不至于只能跑低速通信。

没办法查查吧。

首先把ORE的检测关掉。

这个东西吧,有啥意义呢?Overrun检测是好的,可以告诉系统目前通信超负荷然后进行调整。

但是目前99%以上的开发者都不会管这个东西,另外他们也没有这么极限数据率通信的需求。

如果要检测ORE,你的系统中一定要有UART的Error handler 函数,进行ORE出现时的状态寄存器清理和系统调整。

否则就会出现系统被卡死再也无法通信的情况。

这个ORE的检测是CubeMX默认打开的,在UART的配置里面,如下(我这是5.0CubeMX):代码里面是这两句(我的CubeMX和MDK都是最新版,可能老版本不一样,如果没有就写ErrorHandler进行错误位复位):1.huart2.AdvancedInit.OverrunDisable = UART_ADVFEATURE_OVERRUN_DISABLE;2.huart2.AdvancedInit.DMADisableonRxError = UART_ADVFEATURE_DMA_DISABLEONRXERROR;---------------------------------------------------------2019/6/25 更新--------------------------------------------------------------------试了下STM32F103RC并没有这个OverrunDisable开关,之前还认为是CubeMX更新后带来的新特性。

stm32串口实现printf重定向及错误解决办法

stm32串口实现printf重定向及错误解决办法
{
ch=ch;
}
struct __FILE
{
int handle;
/* Whatever you require here. If the only file you are using is */
/* standard output using printf() for debugging, no file handling */
/* is required. */
};
/* FILE is typedef’ d in stdio.h. */
FILE __stdout;
//串口1 GPIO_Pin_11,A
//串口2 GPIO_Pin_4,A
//串口3 GPIO_Pin_12,GPIOB
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
PUTCHAR_PROTOTYPE
{
/* Place your implementation of fputc here */
/* e.g. write a character to the USART */
} /*.\OUTPUT\STM32_4PMaser.axf: Error: L6915E: Library reports error: __use_no_semihosting was requested, but _ttywrch was referenced*/
_ttywrch(int ch) //可以消除这个错误
/* Loop until the end of transmission */

usart_senddata函数用法

usart_senddata函数用法

usart_senddata函数用法USART (Universal Synchronous/Asynchronous Receiver/Transmitter) 是一种由微处理器或计算机实现的串行通信接口,用于向外界设备或其他计算机传输数据。

USART可实现异步或同步的串行传输,具有高效性、可靠性和灵活性,因此在许多计算机和嵌入式系统中广泛应用。

USART使用串行通信协议,通过发送和接收数据包,实现设备间的数据交换。

在这里,我们将介绍USART_SendData函数的用法。

USART_SendData函数是STM32微控制器的USART库函数之一,用于在USART通信中向外界设备发送数据。

通常,在发送数据之前,需要初始化USART接口,配置它的各种参数,包括波特率、数据位、停止位和校验位等。

这些参数可以通过STM32芯片上的USART寄存器进行配置。

在配置完成之后,可以使用USART_SendData函数将数据发送到USART接口。

USART_SendData函数的参数有两个,第一个是USART_TypeDef类型的指针,指向USART寄存器组。

USART_TypeDef结构体中包含了USART寄存器的各种寄存器值,包括数据寄存器、状态寄存器和控制寄存器等。

第二个参数是要发送的数据值,为unsigned short类型。

USART_SendData函数的返回值为一个标志位,标志着数据是否成功发送。

如果数据发送成功,返回值为1;如果数据发送失败,返回值为0。

USART_SendData函数的使用非常简单,只需调用函数并传递参数即可发送数据。

以下是USART_SendData函数的示例代码,它将一个8位二进制字节(0x55)发送到USART1接口:USART_SendData(USART1, 0x55);在发送数据之后,通常需要检查发送是否成功。

可以使用USART_GetFlagStatus函数来读取USART标志位状态,以确定数据是否成功发送。

STM32程序无法使用printf,产生停留BEAB BKPT 0xAB处问题的解决

STM32程序无法使用printf,产生停留BEAB BKPT 0xAB处问题的解决

STM32 程序无法使用printf,产生停留BEAB BKPT
0xAB 处问题的解决
在网上搜了下,发现有很多这样的问题,我也遇到了,最后解决了,我在
此总结一下:
问题1(与编译软件无关):在程序中加入printf 语句实现串口输出,但未
写重定向函数fputc,出现编译无任何警号和错误直接下载无法运行,软件仿真
可以运行至MAIN 函数,硬件仿真在汇编窗口看到停留在“0x0800XXXX BEAB BKPT 0xAB //进入调试模式”处无法继续运行。

解决办法:编写fputc 函数如下:
1 int fputc(int ch, FILE *f)
2 {
3 USART_SendData(USART1, (uint8_t) ch);
4 while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
5 {}
6 return ch;
7 }
问题2(与编译软件有关):重定向函数fputc 编写无误,使用的是
MDK4.22-3.40 之间的编译环境,未使用微库,即MiclroLIB,因printf()之类的
函数,使用了半主机模式。

使用微库的话,不会使用半主机模式,所以就没有
问题。

解决办法:在option for target->target 对话框中,选择Use MiclroLIB,重新编译程序即可。

问题3:重定向函数fputc 编写无误,不用微库,即MiclroLIB,依然可以使。

stm32 串口数据处理函数

stm32 串口数据处理函数

stm32 串口数据处理函数STM32是一种嵌入式微控制器,广泛应用于各种领域,如工业控制、汽车电子、智能家居等。

其中,串口通信是一种常见的数据传输方式,因此对于STM32来说,串口数据处理函数是一个非常重要的部分。

本文将从串口数据处理函数的作用、实现方法及常见问题进行介绍。

一、串口数据处理函数的作用串口数据处理函数主要用于接收和处理通过串口传输的数据。

在STM32中,串口通信一般使用USART模块来实现,其中包括了发送和接收数据的寄存器和中断。

通过串口数据处理函数,可以实现对接收到的数据进行解析、处理和应答。

二、串口数据处理函数的实现方法在STM32中,串口数据处理函数一般通过中断的方式实现。

首先需要配置USART模块的寄存器,设置波特率、数据位、停止位等参数。

接着,使能USART的接收中断,并编写中断服务函数。

当接收到数据时,中断服务函数会被触发,将接收到的数据存储到相应的缓冲区中。

在主程序中,可以通过轮询或者事件驱动的方式对接收到的数据进行处理。

根据具体的需求,可以使用字符串处理函数、数据解析函数等对数据进行处理,并根据处理结果进行相应的操作。

三、串口数据处理函数的常见问题1. 数据丢失:由于串口通信的速度较慢,当数据传输速度过快时,可能会导致数据丢失。

为了避免数据丢失,可以使用DMA(直接存储器访问)来实现串口通信,提高数据传输效率。

2. 数据错误:在数据传输过程中,由于噪声等原因,可能会导致数据出现错误。

为了保证数据的准确性,可以使用校验位来验证数据的完整性。

3. 数据解析困难:当接收到的数据较为复杂时,可能会出现数据解析困难的情况。

为了解决这个问题,可以使用状态机或者正则表达式等方法来进行数据解析。

4. 数据处理效率低:当需要处理大量数据时,可能会导致处理效率低下。

为了提高数据处理效率,可以使用多线程或者硬件加速等方法。

四、总结串口数据处理函数在STM32中起着至关重要的作用,通过合理的配置和编写,可以实现对串口数据的接收和处理。

STM32新手常见的一个错误并给出解决方法

STM32新手常见的一个错误并给出解决方法

STM32新手常见的一个错误并给出解决方法在使用STM32微控制器进行开发时,新手常常会遇到一些常见的错误。

以下是一些常见错误以及对应的解决方法,帮助新手更好地克服这些问题。

1.芯片未正确连接:通常情况下,STM32芯片应与开发板正确连接。

新手可能会出现错误的连接方式,例如将芯片倒置或错位连接。

解决这个问题的方法是仔细查看芯片的引脚图并确保正确地连接所有的引脚。

2.引脚配置错误:STM32微控制器具有多功能引脚,可以根据需要进行不同功能的配置。

新手可能会错误地配置引脚,导致功能无法正常工作。

解决这个问题的方法是仔细阅读芯片的数据手册,以确定正确的引脚功能和配置设置。

3.时钟配置错误:STM32微控制器依赖于准确的时钟源以确保正常运行。

新手可能会忽视时钟配置,导致系统无法启动或无法正常工作。

解决这个问题的方法是仔细配置时钟源,并确保时钟频率与所需的系统时钟频率相匹配。

4.软件驱动错误:在使用STM32微控制器进行开发时,需要正确的软件驱动程序来控制硬件功能。

新手可能会遗漏或错误地使用关键的驱动程序,导致无法实现预期的功能。

解决这个问题的方法是仔细阅读相关的软件库文档,并确保正确使用所有必需的软件驱动程序。

5.中断配置错误:STM32微控制器支持多种中断,并需要正确配置以实现正确的中断处理。

新手可能会忽略或错误地配置中断,导致系统无法正确响应中断事件。

解决这个问题的方法是仔细阅读关于中断配置和处理的文档,并确保正确配置所有中断。

6.电源和电源管理问题:STM32微控制器需要稳定和适当的电源供应以确保正常运行。

新手可能会遇到电源不稳定或不足的问题,导致系统无法正常工作。

解决这个问题的方法是确保提供稳定的电源,并使用适当的电源管理技术,例如使用电容和稳压器等来提供稳定和适当的电源。

7.调试问题:在使用STM32微控制器进行开发时,调试是非常重要的。

新手可能会遇到调试问题,例如无法正确读取或显示调试信息。

STM32虚拟串口 CDC官方示例程序修正

STM32虚拟串口 CDC官方示例程序修正

这几天一直在调试STM虚拟串口,我是在官方提供的列程的基础上改的,在调试过程中,发现这个列程存在几个BUG,为了大家学习的方面在此提出自己的一种解决方案,仅供大家参考。

B->UART 没有等串口发送完,现象是只能发一个字符void USB_To_USART_Send_Data(u8* data_buffer, u8 Nb_bytes){u32 i;for (i = 0; i <Nb_bytes; i++){USART_SendData(USART1, *(data_buffer + i));//added by dreamdivewhile(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);}}2.bool USART_Config(void)函数中,数据长度设置错误导致乱码/*set the data type : only 8bits and 9bits is supported */switch (linecoding.datatype){case 0x07://数据长度7位USART_ART_WordLength = USART_WordLength_8b;break;case 0x08://数据长度8位//USART_ART_WordLength = USART_WordLength_9b;//无较验位时用8位方式,否则用9位方式if(linecoding.paritytype==USART_Parity_No)USART_ART_WordLength = USART_WordLength_8b;elseUSART_ART_WordLength = USART_WordLength_9b;break;default :{USART_Config_Default();return (FALSE);}}3.void USART_To_USB_Send_Data(void)函数中,判断错误导致用7位串口方式时UART->USB乱码if (USART_ART_WordLength == USART_WordLength_8b) {buffer_in[count_in] = USART_ReceiveData(USART1) & 0x7F;}else if (USART_ART_WordLength == USART_WordLength_9b) {buffer_in[count_in] = USART_ReceiveData(USART1);}改为:if (linecoding.datatype == 0x07){buffer_in[count_in] = USART_ReceiveData(USART1) & 0x7F;}else{buffer_in[count_in] = USART_ReceiveData(USART1);}经测试,8位无校验/带校验和7位无校验/带校验工作全部正常。

STM32串口死机现象经验分享

STM32串口死机现象经验分享

STM32串口错误中断导致死机现象在对STM32调试中,使用上位机串口调试助手给节点发送命令,误将校验方式选择为无校验,而节点的串口初始化为偶校验方式接收数据,但使用串口工具发送无校验数据时,节点立即死机无反应,最终看门狗复位1.使用jlink在线跟踪调试,发现程序未进入HardFault_Handler异常中断,在收到无校验的数据后,节点立即不停的循环进入串口中断处理程序,最终导致看门狗复位。

2.按照常规流程,通过MDK在线调试工具观察串口USART_CR1 与USART_ISR 寄存器的值;1.发现USART_CR1寄存器的PEIE置位,即将校验错误中断使能,同时串口中断状态寄存器USART_ISR的PE位置位,所以产生中断,但我的中断处理程序里面未对改中断标志做任何处理,没有使用USART_ICR寄存器将PE的中断标志位清除,当退出中断后,STM32会立即再次进入串口中断。

2.这种现象是因为串口配置为偶校验,但收到无校验的串口数据时,数据校验失败同时PEIE位置1从而导致进入串口中断处理程序。

3.采用两种办法解决该问题:将USART_CR1寄存器的PEIE的使能标志位清楚,或者在中断处理程序里面退出之前的时候,将使用USART_ICR寄存器将USART_ISR的PE中断标志位清除,最终测试后问题得到解决1.但是在另外的串口测试中,使用上位机通过串口不停的向节点发送数据,中途手动将串口的硬件连接断开一段时间后再连接,有时候在将断开的串口连接再次连接上时,设备又会循环进入串口中断,最终导致设备的看门狗复位;2.再次通过在线调试观察串口寄存器,发现上面的PEIE已经被置零,说明该中断使能已经被关闭,不是上面提到的校验错误引起的中断;3.最终查看STM32F071的官方参考手册,在看到CR3寄存器上看到如下说明EIE位:错误中断使能控制,该位如果置1时,当USART_ISR的FE或ORE或NF其中一个置位时都将产生中断,FE位:帧错误位标志,当检测到同步错误或过多的噪声或break符;ORE:过载错误标志;NF:噪声错误标志;1.在线调试观察CR3寄存器的EIE位被置位,同时在异常的循环进入串口中断时观察中断状态标志位发现以上三个标志位中存在置位的情况,当初对该EIE标志位的使能未重视;2.最后跟源代码发现在串口的初始化中奖上面的两个中断使能位PEIE与EIE都使能;屏蔽该代码或在中断处理程序中清楚错误标志位后均正常工作;3.该源代码是使用STM32cube工具生成的库,只使用了其串口初始化功能,但未使用工具生成的串口中断处理程序;。

串口助手输出乱码或无输出问题

串口助手输出乱码或无输出问题

串⼝助⼿输出乱码或⽆输出问题
问题描述:使⽤stm32的板⼦下载好程序之后,想通过串⼝助⼿查看调试结果却发现串⼝没有输出或者输出的是乱码。

情景⼀:如果你想要使⽤c标准中的printf函数打印字符到串⼝助⼿,那么你需要先重定义fputc函数,这样才可以正常使⽤printf函数。

/******************************************************
*@brief 重定义fputc函数
*@param ch:返回的字符
*
*******************************************************/
int fputc(int ch, FILE *f)
{
USART_SendData(USART1,ch);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
return ch;
}
情景⼆:如果你的fputc函数已经重定义了,但是还是输出不了字符,那么有可能是以下问题:
问题1:keil软件中没有配置好,具体配置⽅法如下:
1、选择输出中⽂选项
2、勾选Use MicroLIB
问题2:时钟的频率没有修改正确,具体修改步骤如下
1、修改频率
2、修改频率的时候如果⽂件有没有写⼊权限,我们需要先把只读权限去掉具体操作如下:
注意⼀下,修改完频率之后,记得重新把⽂件的写权限加上,重新把⽂件的只读属性勾选上即可。

以上是我在实践中遇到的串⼝助⼿输出的问题,可能还有其他的情况我没有发现,如果朋友们有其他的问题或者有更好的解决⽅法,希望留下你们的宝贵意见。

用STM32官方库自带的USART_SendData函数发送字符串

用STM32官方库自带的USART_SendData函数发送字符串

⽤STM32官⽅库⾃带的USART_SendData函数发送字符串源代码//USARTx 串⼝//*string 字符串//enter 回车void send_Data(USART_TypeDef* USARTx, u8 *string, u8 enter){do{while(USART_GetFlagStatus(USARTx,USART_FLAG_TC)==RESET);USART_SendData(USARTx,*string);while(USART_GetFlagStatus(USARTx,USART_FLAG_TC)!=RESET);string++;}while(*string!='\n');if(enter!=0){while(USART_GetFlagStatus(USARTx,USART_FLAG_TC)==RESET);USART_SendData(USARTx,'\n');while(USART_GetFlagStatus(USARTx,USART_FLAG_TC)!=RESET);}}函数分析在官⽅⾃带的函数库中USART_SendData()只能发送单个字符,因此需要⾃⼰编写⼀个字符串的函数。

在我写的这个函数中有3个参数,第⼀个是串⼝号,第⼆个是要发送的字符串,第三个填0或1,⽤来决定是否在发送完毕后换⾏。

while(USART_GetFlagStatus(USARTx,USART_FLAG_TC)==RESET);⽤于等待串⼝空闲后开始传送数据,防⽌数据冲突导致的乱码。

同理可知while(USART_GetFlagStatus(USARTx,USART_FLAG_TC)!=RESET);⽤于等待串⼝发送完成后再进⾏下⼀步。

在定义第⼆个参数时我们将字符串设为指针,将其设为指针是因为字符串在地址中每增加⼀位就代表着下⼀位字符。

于是当我们要⽤USART_SendData(USARTx,*string);发送数据时,得加上指针符号。

STM32串口usart发送数据

STM32串口usart发送数据

STM32串⼝usart发送数据主函数请直接关注41⾏到47⾏代码!!1 #include "stm32f10x.h"// 相当于51单⽚机中的 #include <reg51.h>2 #include "stm32f10x_gpio.h"3 #include "stm32f10x_usart.h"4 #include "led.h"5 #include "key.h"6 #include "key interrupt.h"7 #include "delay.h"8 #include "usart1.h"9 #include "stdio.h"10 #include "usart.h"1112int main()13 {14/*15 * ⼀、点亮⼀个LED灯16*/1718/*点亮⼀个LED灯*/19//red_on();//红灯20//green_on();//绿灯21//blue_on();//蓝灯2223/*24* ⼆、按键通过按键实现控制led的亮灭(有两种情况)25*/2627//key1();28//key2();29//key3();3031/*32* 三、按键K1,K2中断控制LED亮灭33*/3435//interrupt();//详细代码见key interrupt.c⽂件3637/*38* 四、串⼝39*/4041 usart1_config(); //串⼝初始化42 USART_SendData(USART1,'A'); //发送数据A43 printf("kinson\n"); //⽤printf打印数据kinson,说明:printf默认打印输出在控制台,现在修改源码打印输出⾄串⼝44while(1);454647/*48* 五、 Systick时钟定时49*/5051/*52 SystemInit();//初始化系统,使得系统频率为72兆5354 //配置Systick为10us中断⼀次,时间到后触发定时中断55 //进⼊stm32fxx_it.c⽂件的SysTick_Handle处理,通过数中断次数计时5657 led_gpio_init();//LED端⼝初始化58 while(1)59 {6061 GPIO_Setbits(GPIO,GPIO_Pin_15);62 delay_ms(1000);//延时63 GPIO_ResetBits(GPIO,GPIO_Pin_15);64 delay_ms(1000);//延时65 while(1);66 }67*/68 }新建⼀个⽂件配置串⼝usart相关的配置1 #include "usart1.h"2 #include "stm32f10x.h"//相当于stdio头⽂件3 #include "stm32f10x_gpio.h"//配置GPIO要⽤的头⽂件4 #include "stm32f10x_usart.h"//配置串⼝usart要⽤的头⽂件5 #include "misc.h"//配置中断NVIC要⽤的头⽂件6 #include "stdio.h"//为printf所⽤78/*串⼝1的配置函数*/9void usart1_config()10 {11//第⼀步:时钟配置(GPIO时钟,串⼝时钟)12 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1|RCC_APB2Periph_AFIO,ENABLE); 13//第⼆步,GPIO配置,Rx(接受)为PA10,Tx(发送)为PA914 GPIO_InitTypeDef a; //定义结构体15/*配置PA9为复⽤推挽输出*/16 a.GPIO_Pin=GPIO_Pin_9; //端⼝9,依据来源看电路图17 a.GPIO_Speed=GPIO_Speed_50MHz;18 a.GPIO_Mode=GPIO_Mode_AF_PP; //复⽤推挽输出19 GPIO_Init(GPIOA,&a); //初始化2021/*配置PA10为浮空输⼊*/22 a.GPIO_Pin=GPIO_Pin_10;23 a.GPIO_Mode=GPIO_Mode_IN_FLOATING; //浮空输⼊24 a.GPIO_Speed=GPIO_Speed_50MHz;25 GPIO_Init(GPIOA,&a);2627//第⼆步:NVIC配置28/*NVIC嵌套向量中断控制器*/29 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //优先级配置30 NVIC_InitTypeDef b;31 b.NVIC_IRQChannel = USART1_IRQn;//USART1_IRQn串⼝中断32 b.NVIC_IRQChannelPreemptionPriority = 1;//0 1 2 3 433 b.NVIC_IRQChannelSubPriority = 1;//0 1 2 3 434 b.NVIC_IRQChannelCmd = ENABLE; //使能35 NVIC_Init(&b);3637//第三步:串⼝配置38 USART_InitTypeDef c;39 ART_BaudRate=9600; //波特率40 ART_HardwareFlowControl=USART_HardwareFlowControl_None;//硬件控制流41 ART_Mode=USART_Mode_Rx|USART_Mode_Tx; //模式,此模式为发送和接受42 ART_WordLength=USART_WordLength_8b;//字长843 ART_Parity=USART_Parity_No; //奇偶校验n44 ART_StopBits=USART_StopBits_1; //停⽌位145 USART_Init(USART1,&c);46//第四步:串⼝时能47 USART_Cmd(USART1,ENABLE);48 }4950515253/*以下代码为printf能在发送数据给串⼝所⽤*/54int fputc(int ch,FILE* ffdsfa)55 {56 USART_SendData(USART1,ch);57while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);//等待发送完成58return ch;59 }60616263646566新建.h⽂件(不同⽂件之间的函数调⽤必须掌握的知识点)1 #ifndef _USART1_H_2#define _USART1_H_34void usart1_config();567#endif。

关于STM32串口首字符出现乱码的问题可能原因之一

关于STM32串口首字符出现乱码的问题可能原因之一
/* Reset GPIO init structure parameters values */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
*
* @briefUSART1的初始化工作
*
* @paramNULL
*
* @returnNULL
*
* @byTimeandspace7
*
* @date 20170814
*
* @place YSU_B303-3
**********************************************************************/
USART_ART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(USART1, &USART_InitStructure);
}
/*
*函数名:fputc
*描述:重定向c库函数printf到USART1
*输入:无
*输出:无
*调用:由printf调用
*/
int fputc(int ch, FILE *f)
{
USART_ClearFlag(USART1,USART_FLAG_TC);//清除串口1发送中断--否则第一个数不会发送
/*将Printf内容发往串口*/
USART_SendData(USART1, (uint16_t) ch);
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

STM32库函数USART_SendData问题和解决方法
1. 问题及现象使用USART_SendData()函数非连续发送单个字符是没有问
题的;当连续发送字符时(两个字符间没有延时),就会发现发送缓冲区有溢出现象。

若发送的数据量很小时,此时串口发送的只是最后一个字符,当发送数据量大时,就会导致发送的数据莫名其妙的丢失。

如:
12for(TxCounter = 0;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 状态检测语句,确保一个字符完全发送出去,才进行下
一个字符的发送。

相关文档
最新文档