STM32 HAL 串口中断接收 记录

参考教程小记stm32实现串口接收的四种方法(hal库)_串口接收方式_Z980778982的博客-CSDN博客

首先在STM32 CubeMX中打开串口全局中断,

 stm32f1xx_it.c中需要修改,我设置了三个串口,触发RX非空中断后触发回调,如果不这么设置的话发送和接收会触发两次中断。

#include "main.h"
#include "stm32f1xx_it.h"

extern UART_HandleTypeDef huart1;
extern UART_HandleTypeDef huart2;
extern UART_HandleTypeDef huart3;
extern TIM_HandleTypeDef htim3;

void NMI_Handler(void)
{
  /* USER CODE BEGIN NonMaskableInt_IRQn 0 */

  /* USER CODE END NonMaskableInt_IRQn 0 */
  /* USER CODE BEGIN NonMaskableInt_IRQn 1 */
  while (1)
  {
  }
  /* USER CODE END NonMaskableInt_IRQn 1 */
}

/**
  * @brief This function handles Hard fault interrupt.
  */
void HardFault_Handler(void)
{
  /* USER CODE BEGIN HardFault_IRQn 0 */

  /* USER CODE END HardFault_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_HardFault_IRQn 0 */
    /* USER CODE END W1_HardFault_IRQn 0 */
  }
}

/**
  * @brief This function handles Memory management fault.
  */
void MemManage_Handler(void)
{
  /* USER CODE BEGIN MemoryManagement_IRQn 0 */

  /* USER CODE END MemoryManagement_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
    /* USER CODE END W1_MemoryManagement_IRQn 0 */
  }
}

/**
  * @brief This function handles Prefetch fault, memory access fault.
  */
void BusFault_Handler(void)
{
  /* USER CODE BEGIN BusFault_IRQn 0 */

  /* USER CODE END BusFault_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_BusFault_IRQn 0 */
    /* USER CODE END W1_BusFault_IRQn 0 */
  }
}

/**
  * @brief This function handles Undefined instruction or illegal state.
  */
void UsageFault_Handler(void)
{
  /* USER CODE BEGIN UsageFault_IRQn 0 */

  /* USER CODE END UsageFault_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_UsageFault_IRQn 0 */
    /* USER CODE END W1_UsageFault_IRQn 0 */
  }
}

/**
  * @brief This function handles System service call via SWI instruction.
  */
void SVC_Handler(void)
{
  /* USER CODE BEGIN SVCall_IRQn 0 */

  /* USER CODE END SVCall_IRQn 0 */
  /* USER CODE BEGIN SVCall_IRQn 1 */

  /* USER CODE END SVCall_IRQn 1 */
}

/**
  * @brief This function handles Debug monitor.
  */
void DebugMon_Handler(void)
{
  /* USER CODE BEGIN DebugMonitor_IRQn 0 */

  /* USER CODE END DebugMonitor_IRQn 0 */
  /* USER CODE BEGIN DebugMonitor_IRQn 1 */

  /* USER CODE END DebugMonitor_IRQn 1 */
}

/**
  * @brief This function handles Pendable request for system service.
  */
void PendSV_Handler(void)
{
  /* USER CODE BEGIN PendSV_IRQn 0 */

  /* USER CODE END PendSV_IRQn 0 */
  /* USER CODE BEGIN PendSV_IRQn 1 */

  /* USER CODE END PendSV_IRQn 1 */
}

/**
  * @brief This function handles System tick timer.
  */
void SysTick_Handler(void)
{
  /* USER CODE BEGIN SysTick_IRQn 0 */

  /* USER CODE END SysTick_IRQn 0 */
  HAL_IncTick();
  /* USER CODE BEGIN SysTick_IRQn 1 */

  /* USER CODE END SysTick_IRQn 1 */
}

/******************************************************************************/
/* STM32F1xx Peripheral Interrupt Handlers                                    */
/* Add here the Interrupt Handlers for the used peripherals.                  */
/* For the available peripheral interrupt handler names,                      */
/* please refer to the startup file (startup_stm32f1xx.s).                    */
/******************************************************************************/

/**
  * @brief This function handles USART1 global interrupt.
  */
void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */
	uint32_t isrflags   = READ_REG(huart1.Instance->SR);
  if ((isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_RXNE)) == RESET)
  {
    /* UART in mode Receiver -------------------------------------------------*/
    if (((isrflags & USART_SR_RXNE) != RESET) )
    {
			HAL_UART_RxCpltCallback(&huart1);
    }
  }		
  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */
	
  /* USER CODE END USART1_IRQn 1 */
}

/**
  * @brief This function handles USART2 global interrupt.
  */
void USART2_IRQHandler(void)
{
  /* USER CODE BEGIN USART2_IRQn 0 */
	uint32_t isrflags   = READ_REG(huart2.Instance->SR);
  if ((isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_RXNE)) == RESET)
  {
    /* UART in mode Receiver -------------------------------------------------*/
    if (((isrflags & USART_SR_RXNE) != RESET) )
    {
			HAL_UART_RxCpltCallback(&huart2);
    }
  }		
  /* USER CODE END USART2_IRQn 0 */
  HAL_UART_IRQHandler(&huart2);
  /* USER CODE BEGIN USART2_IRQn 1 */
	
  /* USER CODE END USART2_IRQn 1 */
}

/**
  * @brief This function handles USART3 global interrupt.
  */
/**
  * @brief This function handles USART3 global interrupt.
  */

void USART3_IRQHandler(void)
{
  /* USER CODE BEGIN USART3_IRQn 0 */
	uint32_t isrflags   = READ_REG(huart3.Instance->SR);
  if ((isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_RXNE)) == RESET)
  {
    /* UART in mode Receiver -------------------------------------------------*/
    if (((isrflags & USART_SR_RXNE) != RESET) )
    {
			HAL_UART_RxCpltCallback(&huart3);
    }
  }		
  /* USER CODE END USART3_IRQn 0 */
  HAL_UART_IRQHandler(&huart3);
  /* USER CODE BEGIN USART3_IRQn 1 */
	
  /* USER CODE END USART3_IRQn 1 */
}

stm32f1xx_it.h也需要修改


#ifndef __STM32F1xx_IT_H
#define __STM32F1xx_IT_H

#ifdef __cplusplus
 extern "C" {
#endif

void NMI_Handler(void);
void HardFault_Handler(void);
void MemManage_Handler(void);
void BusFault_Handler(void);
void UsageFault_Handler(void);
void SVC_Handler(void);
void DebugMon_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);

void USART1_IRQHandler(void);
void USART2_IRQHandler(void);
void USART3_IRQHandler(void);

#ifdef __cplusplus
}
#endif

#endif /* __STM32F1xx_IT_H */

下面这段加在usart.c

#include "string.h"

uint8_t aRxBuffer;			//接收中断缓冲
uint8_t Uart_RxBuff[256] = {0};		//接收缓冲
uint8_t Uart_Rx_Cnt = 0;		//接收缓冲计数
uint8_t Uart_RxFlag = 0;
uint8_t	cAlmStr[] = "数据溢出(大于256)\r\n";

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(huart);
  /* NOTE: This function Should not be modified, when the callback is needed,
           the HAL_UART_TxCpltCallback could be implemented in the user file
   */
	if(Uart_Rx_Cnt >= 255)  //溢出判断
	{
		Uart_Rx_Cnt = 0;
		memset(Uart_RxBuff,0x00,sizeof(Uart_RxBuff));
		HAL_UART_Transmit(huart, (uint8_t *)&cAlmStr, sizeof(cAlmStr),0xFFFF);	
	}
	else
	{
		Uart_RxBuff[Uart_Rx_Cnt++] = aRxBuffer;   //接收数据转存
	
		if((Uart_RxBuff[Uart_Rx_Cnt-1] == 0x0A)&&(Uart_RxBuff[Uart_Rx_Cnt-2] == 0x0D)) //判断结束位
		{
			Uart_RxFlag = 1;
		}
	}
	HAL_UART_Receive_IT(huart, (uint8_t *)&aRxBuffer, 1);   //再开启接收中断
}

这段加在usart.h

extern uint8_t aRxBuffer;			//接收中断缓冲
extern uint8_t Uart_RxBuff[256];	//接收缓冲
extern uint8_t Uart_Rx_Cnt;		//接收缓冲计数
extern uint8_t Uart_RxFlag;
extern uint8_t	cAlmStr[];//"数据溢出(大于256)\r\n";

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);

在main.c中使用的时候,需要在初始化的时候开启串口中断,然后在while(1)里面循环

//这段放在初始化
HAL_UART_Receive_IT(&huart2,&aRxBuffer,1);

//这段放在while循环
if(Uart_RxFlag != 0)
    {
		HAL_UART_Transmit(&huart2, Uart_RxBuff, Uart_Rx_Cnt - 2, 10000);
        //这里这个Uart_Rx_Cnt相当于数据长度,-2是为了清除0D 0A,不换行
        Uart_RxFlag = 0;
        Uart_Rx_Cnt = 0;
        memset(Uart_RxBuff,0x00,256);
    }
		HAL_Delay(1000);

博客作为一个记录,有问题可以留言~