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);
博客作为一个记录,有问题可以留言~