STM32F103单片机HAL库串口通信卡死问题解决方法

在上篇文章 STM32F103单片机使用STM32CubeMX创建IAR串口工程 中分享了使用cubeMX直接生成串口代码的方法,在测试的过程中无意间发现,串口会出现卡死的问题。
在这里插入图片描述
当串口一次性发送十几个数据的时候,串口感觉像卡死了一样,不再接收数据。通过对串口的监控可以看到,串口中ErrorCode的值变成了8。这时候只有对单片机断电重启,串口才能恢复。
在网上查资料发现造成这个原因主要是HAL的流程问题,当串口在发送数据的时候,如果又接收到了数据,程序中就会出现死锁的情况。
找了好多方法,都没有解决这个问题。大多数的方法是自己编写一个错误码回调函数,当出现错误的时候,在错误码回调函数中清除这个错误码计数值。

// 错误回调函数
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
   
   
  if (huart == &huart1)
  {
   
   
    if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) != RESET)
    {
   
   
      __HAL_UART_CLEAR_OREFLAG(huart);
      HAL_UART_Receive_IT(&huart1, &rx_buf, 1);     
    }
  }
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
   
   
  if (huart->Instance == USART1)
  {
   
   
    HAL_UART_Transmit(&huart1, &rx_buf, 1, 1000);   
    HAL_UART_Receive_IT(&huart1, &rx_buf, 1); 
  }
}

在这里插入图片描述
通过上图中可以看出,接收的数据没有卡死,ErrorCode的值也一直是0,但是接收的数据总是少一个。也是没有彻底解决问题。

然后使用正点原子的串口例程测试的时候没出现串口卡死的情况,也没出现丢数据的情况。所以就将正点原子的串口接收方法移植过来。
为了方便分析这里直接贴代码。
usart.c

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    usart.c
  * @brief   This file provides code for the configuration
  *          of the USART instances.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "usart.h"

/* USER CODE BEGIN 0 */

/* 接收缓冲, 最大USART_REC_LEN个字节. */
uint8_t g_usart_rx_buf[USART_REC_LEN];

/*  接收状态
 *  bit15,      接收完成标志
 *  bit14,      接收到0x0d
 *  bit13~0,    接收到的有效字节数目
*/
uint16_t g_usart_rx_sta = 0;

uint8_t g_rx_buffer[RXBUFFERSIZE]; 
/* USER CODE END 0 */

UART_HandleTypeDef huart1;

/* USART1 init function */

void MX_USART1_UART_Init(void)
{
   
   

  /* USER CODE BEGIN USART1_Init 0 */

  /* USER CODE END USART1_Init 0 */

  /* USER CODE BEGIN USART1_Init 1 */

  /* USER CODE END USART1_Init 1 */
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
   
   
    Error_Handler();
  }
  /* USER CODE BEGIN USART1_Init 2 */  
 HAL_UART_Receive_IT(&huart1, (uint8_t *)g_rx_buffer, RXBUFFERSIZE);  
  /* USER CODE END USART1_Init 2 */

}

void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
   
   

  GPIO_InitTypeDef GPIO_InitStruct = {
   
   0};
  if(uartHandle->Instance==USART1)
  {
   
   
  /* USER CODE BEGIN USART1_MspInit 0 */

  /* USER CODE END USART1_MspInit 0 */
    /* USART1 clock enable */
    __HAL_RCC_USART1_CLK_ENABLE();

    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**USART1 GPIO Configuration
    PA9     ------> USART1_TX
    PA10     ------> USART1_RX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_9;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    GPIO_InitStruct.</
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值