STM32 HAL库关于串口中断烧录程序后可以正常运行

发布者:WhisperingLight最新更新时间:2025-02-18 来源: cnblogs关键字:STM32  HAL库  串口 手机看文章 扫描二维码
随时随地手机看文章

1、情景描述:

最近在做一个项目,X86的上位机通过串口控制MCU,使用串口中断接收上位机数据时,MCU在上电的情况下烧录程序,可以正常接收上位机的数据,在断电重启后,一直进入不了中断回调函数,上电的情况是X86上电,MCU也同时上电。


2、原因分析:

造成这个的原因是因为硬件上电的时候,因为X86跟MCU是同时上电的,上电后会把串口的电平拉高,这个高电平触发了MCU的串口中断,导致MCU的串口中断误以为接收到了一个数据,例如 HAL_UART_Receive_IT(&huart1, (uint8_t *)Rx_buff, 5) 这里,上电后MCU误以为接收了一个数据,还剩下4个数据没有接收,然后上位机每次发送5个数据过来后MCU中断数据接收个数错误,所以一直无法进入中断回调函数。


我们看到 HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart) ,里面的 RxXferCount  是告诉我们中断要接收的剩余数据量大小,根据上面举例子的话,上电时因为那个高电平的原因导致 RxXferCount 变成了4,如下图打印信息所示

接着我们重新看回 HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart) 函数里的调用回调函数部分,下图所示,发现 RxXferCount  要为0的时候才会调用中断回调函数,依旧以上面例子说明,当MCU误以为上电时的高电平为数据时,上位机再发送5个数据下来,RxXferCount  就永远无法变成0,所以导致一直进入不了中断回调函数。

3、解决方法:

3.1软件解决方法

软件解决的时候,我们要知道导致这个问题的根源是 RxXferCount 这个值被误判了,所以我们只需要在上电的时候,对这个值进行修正即可;


首先我们定义一个标志位,用来标志MCU的状态是刚上电的状态  


char uart_error_flag=0;


接着我们编写函数对 RxXferCoun 值进行处理


/***

 函数名:void uart_error(void)

 说  明:解决刚上电时,由于串口电平拉高,导致串口中断误以为接收到了一个字节,

        导致后面接收数据个数一直错误,无法进入中断回调函数问题

 传入值:无

 传出值:无

**/

void uart_error(void)

{

      if( (huart1.RxXferCount < Rxdsize) && (uart_error_flag==0) )

        { 

            /*RxXferCount 告诉我们剩余空间大小,如果剩余空间和总空间不一样,则说明中断收到数据了*/

            printf('huart1.RxXferCount = %drn',huart1.RxXferCount);    

            uart_error_flag = 1;

            huart1.RxXferCount = 5; //修改回原来你需要接收数据大小的剩余空间,防止无法进入回调        

        }

}


最后我们在 main 函数里的 while 循环前调用即可


int main(void)

{


  HAL_Init();

  SystemClock_Config();

  MX_GPIO_Init();

  MX_USART2_UART_Init(); //初始化打印信息串口

  MX_USART1_UART_Init(); //初始化中断接收串口  

  HAL_UART_Receive_IT(&huart1, (uint8_t *)Rx_buff, Rxdsize); //打开串口中断接收

  uart_error(); //处理上电时串口中断误判的问题

  while (1)

  {

   /* 注意要在中断回调函数里重新打开串口中断接收,否则串口中断接收只能接收一次 */

  }

}


3.2 硬件解决方法


硬件解决方法比较粗暴,就是做一个电源延时电路,等X86重新上电后,再给MCU上电。


补充说明:

使用DMA接收时候不会出现这种情况,不过使用DMA接收,如果上位机发送数据过快,会出现数据粘包现象,例如上位机发送是数据一包是5个数据,如果上位机发送数据过快(20ms以内),MCU就好会把接收到的好几包数据当做一包数据来处理,例如把3包数据当做1包数据来处理,这样MCU就会误以为一包数据的15个了,出现误判的情况,不过它接收的数据是准确的,就是分包能力没有串口中断强。


关键字:STM32  HAL库  串口 引用地址:STM32 HAL库关于串口中断烧录程序后可以正常运行

上一篇:STM32 实现串口不定长数据接收(HAL库版--方法2)
下一篇:STM32 在串口通信时运用MODBUS协议

推荐阅读最新更新时间:2026-03-20 11:56

STM32 HAL库串口同时收发,接收卡死?
为什么STM32 HAL库串口会出现同时收发导致接收卡死的问题?如何解决这个问题? 首先,我们来了解一下STM32 HAL库的串口通信机制。 STM32 HAL库是针对STM32系列单片机的一套常用的高级抽象层库。在HAL库中,串口通信是通过针对USART外设的封装实现的。HAL库中提供了一些函数,可以方便地配置USART外设的各种参数,如波特率、数据位、停止位、奇偶校验等,还提供了发送和接收数据的函数。 串口通信是一种异步通信方式,发送和接收是独立的。在使用HAL库编写串口通信代码时,如果在发送数据的同时也接收数据,就可能会出现接收卡死的问题。这是由于串口通信中数据的传输需要遵循一定的协议,同时发送和接收可能会导致这种协议破坏,
[单片机]
STM32HAL库 STM32CubeMX教程四---UART串口通信详解
前言: 今天我们学习STM32CubeMX串口的操作,以及HAL库串口的配置,我们会详细的讲解各个模块的使用和具体功能,并且基于HAL库实现Printf函数功能重定向,UART中断接收,本系列教程将HAL库与STM32CubeMX结合在一起讲解,使您可以更快速的学会各个模块的使用 所用工具: 1、芯片: STM32F407ZET6 2、STM32CubeMx软件 3、IDE: MDK-Keil软件 4、STM32F1xx/STM32F4xxHAL库 5、串口: 使用USART1 PA9,PA10 知识概括: 通过本篇博客您将学到: STM32CubeMX创建串口例程 HAL库UATR函数库
[单片机]
【<font color='red'>STM32</font>】<font color='red'>HAL库</font> STM32CubeMX教程四---UART<font color='red'>串口</font>通信详解
stm32串口HAL库的DMA发送问题
本文使用stm32f411ret的串口1的DMA方式发送数据,刚开始调试的时候发现串口只能发送一次数据,之后就把系统hang住了。通过网上搜资料和不断尝试,发现问题是中断回调函数没有写的原因。 使用HAL库的DMA,需要同时实现DMA中断回调函数和串口中断回调函数。 void DMA2_Stream7_IRQHandler(void) { HAL_DMA_IRQHandler(Uart1Handle.hdmatx); } void USART1_IRQHandler(void) { HAL_NVIC_ClearPendingIRQ(USART1_IRQn); HAL_UART_IRQHandler(&Uart1
[单片机]
STM32 HAL库学习(二) 串口收发数据
上一篇实现了LED的点亮和串口轮询发送数据,这章想着实现串口接收数据,不得不说,在开始使用STM32的外设才对HAL库的框架有更准确的理解。之前一直不懂HAL库的优越性在哪,这次对它的msp层有了一定认识。 简单来说,HAL库有一个特点就是对于许多外设的初始化以及功能操作,都提供有一个weak版本的函数,例如串口的HAL_UART_MspInit()函数和HAL_UART_MspDeInit()函数等,这些都可以供用户在需要时在stm32f0xx_hal_msp.c中进行重写实现功能。 用串口初始化来举例子,用Cube配置UART1使能并生成代码后可以看到有三个关键函数: 1、void MX_USART1_UART_I
[单片机]
STM32使用HAL库实现串口通讯
一、对中断的理解。 该文章引用自单片机技术–新浪博客 为了提高CPU的工作效率以及对实时系统的快速响应,产生了中断控制方式的信息交换。 在日常生活中广泛存在着“中断”的例子。例如一个人正在看书,这时电话铃响了,于是他将书放下去接电话。为了在接完电话后继续看书,他必须记下当时的页号,接完电话后,将书取回,从刚才被打断的位置继续往下阅读。由此可见,中断是一个过程。计算机是这样处理的,当有随机中断请求后,CPU暂停执行现行程序,转去执行中断处理程序,为相应的随机事件服务,处理完毕后CPU恢复执行被暂停的现行程序。 在这个过程中,应注意如下几方面: 一、 外部或内部的中断请求是随机的,若当前程序允许处理应立即响应; 二
[单片机]
<font color='red'>STM32</font>使用<font color='red'>HAL库</font>实现<font color='red'>串口</font>通讯
STM32使用HAL库实现串口通讯——理论原理详细讲解
一、中断模式 1.中断接收。 1.1先看中断接收的流程(以 USART2 为例) 在启动文件中找到中断向量 USART2_IRQHandler 找到USART2_IRQHandler的函数定义 可以看到这里又转到另一个函数里去了,再找下去: 该函数的源码: /** * @brief This function handles UART interrupt request. * @param huart: pointer to a UART_HandleTypeDef structure that contains * the configuration informat
[单片机]
<font color='red'>STM32</font>使用<font color='red'>HAL库</font>实现<font color='red'>串口</font>通讯——理论原理详细讲解
stm32hal库串口BUG
今天在使用stm32f407的HAL库发现一个BUG。当时我中断使用多了、把所有time定时器使用了4个外部中断、不管怎么调整nvic不管用。这个时候HAL串口接收功能已经崩溃、已经无法正确接受数据、串口发送也会卡死。这个网上可以查到这个BUG是由于hal库运行速度缓慢导致的、目前没有很好的办法解决。 这个时候我果断转了ll库、瞬间解决再也没有这些问题了。稳。 当然这个bugF不管103还是F4都是存在的。
[单片机]
STM32HAL库串口处理---中断收发
利用STM32串口中断收发和buffer机制(循环队列的原理)实现数据的准确接收和发送。为后续添加上层通信协议建立基础。为了方便使用,为函数接口统一标准 Arduino串口机制的接口函数 void begin(unsigned long baud);//初始化接口 void end(void);//关闭串口 int available(void);//获取缓存中可以读取的字节数 int peek(void);//从缓存中读取字节数据,但不删除该数据 int read(void);//从缓存中读取字节数据,并删除该数据 int availableWrite(void);//获取发送缓存还可以写入的字节数 void flush(voi
[单片机]
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved