STM32cubeMX+HAL库+串口中断收发程序

STM32cubeMX+HAL库+串口中断收发程序

1、STM32cubeMX配置

STM32cubeMX+HAL库+串口中断收发程序_第1张图片
STM32cubeMX+HAL库+串口中断收发程序_第2张图片
STM32cubeMX+HAL库+串口中断收发程序_第3张图片
输入72,点击OK
STM32cubeMX+HAL库+串口中断收发程序_第4张图片
STM32cubeMX+HAL库+串口中断收发程序_第5张图片
STM32cubeMX+HAL库+串口中断收发程序_第6张图片
我使用的软件是VScode,不会导入的同学参考我这篇文章链接:【 stm32串口+DMA环形缓冲收发保姆级】链接: link

2、程序篇

1、打开usart.c文件

找到函数:void MX_USART1_UART_Init(void)
添加函数HAL_UART_Receive_IT(),打开串口接受,这个只需要调用一次就可以,如果想要再次接受,需要重新打开,本次实验在回调函数中再次启用此函数。

/**
  * @brief  Receives an amount of data in non blocking mode.
  * @note   When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
  *         the received data is handled as a set of u16. In this case, Size must indicate the number
  *         of u16 available through pData.
  * @param  huart Pointer to a UART_HandleTypeDef structure that contains
  *               the configuration information for the specified UART module.
  * @param  pData Pointer to data buffer (u8 or u16 data elements).
  * @param  Size  Amount of data elements (u8 or u16) to be received.
  * @retval HAL status
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);

实例:

 HAL_UART_Receive_IT(&huart1, (uint8_t *)&uart1_rx_temp_data, 1);//Size  Amount of data elements (u8 or u16) to be received.

UART_Receive_IT:此函数可以指定,每收到若干个数据,调用一次回调函数;这是因为,每收到一个字节,都会把此函数的接收计数器-1,如果接收计数器为零,调用串口接收回调函数HAL_UART_RxCpltCallback。
具体的程序实现流程为:
发送数据,触发中断,触发中断服务函数(USART1_IRQHandler),触发中断服务函数(UART1_IRQHandler),进入函数(UART_Receive_IT),触发回调函数( HAL_UARTEx_RxEventCallback)HAL_UART_RxCpltCallback:弱定义函数,用户可以在此函数中编写业务逻辑。清除中断标记,是中断处理函数一定要做的事情,但是对于用户函数,把这个操作给隐藏了
STM32cubeMX+HAL库+串口中断收发程序_第7张图片

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)

实例:


void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
	 if (huart->Instance == USART1)
  	{

    	if (uart1_rx_cnt >= 255)
    	{
     		 uart1_rx_flag = 1;
    	}
    	else
    	{
      		uart1_rx_buffer[uart1_rx_cnt++] = uart1_rx_temp_data;
      		if (uart1_rx_buffer[uart1_rx_cnt - 2] == 0x0D
        		&& uart1_rx_buffer[uart1_rx_cnt - 1] == 0x0A)
        	{
        	uart1_rx_flag = 1;
      		}
   		 }
    	HAL_UART_Receive_IT(&huart1, (uint8_t*)&uart1_rx_temp_data, 1);
  	}
}

1、在USART.C中的定义以及重定向printf

uint8_t uart1_rx_buffer[16];
uint8_t uart1_rx_temp_data;
uint8_t uart1_rx_cnt;
uint8_t uart1_rx_flag;

int fputc(int ch, FILE *f)
{
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
  return ch;
}

2、在usart.h中添加声明


extern uint8_t uart1_rx_cnt;
extern uint8_t uart1_rx_flag;

extern uint8_t uart1_rx_buffer[16];

2、main.c

HAL_UART_Transmit(&huart2, str, sizeof(str), 100);
  while (1)
  {
    if (uart1_rx_flag == 1)
    {
      HAL_UART_Transmit(&huart1, uart1_rx_buffer, uart1_rx_cnt, 100);

      uart1_rx_flag = 0;
      memset(uart1_rx_buffer, 0, uart1_rx_cnt);
      uart1_rx_cnt = 0;
    }
    if (uart2_rx_flag == 1)
    {
      HAL_UART_Transmit(&huart2, uart2_rx_buffer, uart2_rx_cnt, 100);

      uart2_rx_flag = 0;
      memset(uart2_rx_buffer, 0, uart2_rx_cnt);
      uart2_rx_cnt = 0;
    }
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }

其他地方不需要改动。就可以进行打印接收。
STM32cubeMX+HAL库+串口中断收发程序_第8张图片
这里我们对回调函数进行测试,发现当没有回车换行的时候,他不接受数据,则测试成功,
程序源码为,\r的Ascll就是CR== 0x0D , \n 就是LF== 0x0A ;
具体可查询ascll表

if (uart1_rx_buffer[uart1_rx_cnt - 2] == 0x0D
        && uart1_rx_buffer[uart1_rx_cnt - 1] == 0x0A)

STM32cubeMX+HAL库+串口中断收发程序_第9张图片
最后附上USART.C代码吧,方便初学者移植,只需要把自己的USART.C注释掉(crtrl+A,再ctrl+/),添加上我的就可以了

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    usart.c
  * @brief   This file provides code for the configuration
  *          of the USART instances.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 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 */
uint8_t uart1_rx_buffer[16];
uint8_t uart1_rx_temp_data;
uint8_t uart1_rx_cnt;
uint8_t uart1_rx_flag;


int fputc(int ch, FILE *f)
{
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
  return ch;
}

/* 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 *)&uart1_rx_temp_data, 1);

  /* USER CODE END USART1_Init 2 */

}
/* USART2 init function */


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.Pin = GPIO_PIN_10;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* USART1 interrupt Init */
    HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(USART1_IRQn);
  /* USER CODE BEGIN USART1_MspInit 1 */

  /* USER CODE END USART1_MspInit 1 */
  }
 
}

void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
{

  if(uartHandle->Instance==USART1)
  {
  /* USER CODE BEGIN USART1_MspDeInit 0 */

  /* USER CODE END USART1_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_USART1_CLK_DISABLE();

    /**USART1 GPIO Configuration
    PA9     ------> USART1_TX
    PA10     ------> USART1_RX
    */
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);

    /* USART1 interrupt Deinit */
    HAL_NVIC_DisableIRQ(USART1_IRQn);
  /* USER CODE BEGIN USART1_MspDeInit 1 */

  /* USER CODE END USART1_MspDeInit 1 */
  }

}

/* USER CODE BEGIN 1 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  if (huart->Instance == USART1)
  {
    // HAL_UART_Transmit(&huart1, (uint8_t*)&uart1_rx_temp_data, 1, 100);
    if (uart1_rx_cnt >= 255)
    {
      uart1_rx_flag = 1;
    }
    else
    {
      uart1_rx_buffer[uart1_rx_cnt++] = uart1_rx_temp_data;
      if (uart1_rx_buffer[uart1_rx_cnt - 2] == 0x0D
        && uart1_rx_buffer[uart1_rx_cnt - 1] == 0x0A)
      {
        uart1_rx_flag = 1;
      }
    }
    HAL_UART_Receive_IT(&huart1, (uint8_t*)&uart1_rx_temp_data, 1);
  }

}
/* USER CODE END 1 */


你可能感兴趣的:(stm32,单片机,嵌入式硬件)