【STM32HAL库】STM32CubeMX+STM32CubeMXIDE系列教程(三)——USART串口通信

前言

此例程详细介绍了如何使用STM32CubeMX配置STM32单片机的USART串口,使用STM32CubeMXIDE进行软件编程。
【实现的功能】
1.实现单片机与PC串口调试助手进行信息收发;
2.实现串口调试助手向单片机发送指令控制单片机LED的亮灭。

工具

【库】HAL库
【软件】STM32CubeMX+STM32CubeMXIDE
【开发板】STM32F103C8T6开发板
【硬件资源】LED2、USART1;USB转TTL模块

硬件介绍

硬件连接

【说明】由于小编使用的板子是小系统板,没有板载USB转TTL,需要使用外部USB转TTL连接板子串口IO和PC的USB,才能进行串口助手调试。

//IO连接
USART   USB-TTL
 PA9<--->RXD
 PA10<-->TXD
//LED_IO
 PC13

【板载LED电路】
【STM32HAL库】STM32CubeMX+STM32CubeMXIDE系列教程(三)——USART串口通信_第1张图片
注意LED阳极接3V3电源,因此当PC13输出低电平时LED点亮,PC13输出高电平时LED熄灭。

程序设计

STM32CubeMX配置

【第一步】:DeBug和系统时钟配置
【STM32HAL库】STM32CubeMX+STM32CubeMXIDE系列教程(三)——USART串口通信_第2张图片
【STM32HAL库】STM32CubeMX+STM32CubeMXIDE系列教程(三)——USART串口通信_第3张图片
【STM32HAL库】STM32CubeMX+STM32CubeMXIDE系列教程(三)——USART串口通信_第4张图片
【第二步】:LED_IO配置
【STM32HAL库】STM32CubeMX+STM32CubeMXIDE系列教程(三)——USART串口通信_第5张图片
【第三步】:USART配置
【STM32HAL库】STM32CubeMX+STM32CubeMXIDE系列教程(三)——USART串口通信_第6张图片
【第四步】:工程生成设置
【STM32HAL库】STM32CubeMX+STM32CubeMXIDE系列教程(三)——USART串口通信_第7张图片
【STM32HAL库】STM32CubeMX+STM32CubeMXIDE系列教程(三)——USART串口通信_第8张图片
以上所有配置完成后点击右上角的GENERATE CODE生成配置好的工程文件,打开工程文件进入IDE进行程序设计。

程序设计

函数介绍

********************本例程主要用到的函数********************
//GPIO写函数,给GPIO写0或1(GPIO失能/使能)
void HAL_GPIO_WritePin( GPIO_TypeDef *  GPIOx,  
  						uint16_t  GPIO_Pin,  
  						GPIO_PinState  PinState  
 					  ) 
//UART数据接收函数
HAL_StatusTypeDef HAL_UART_Receive( UART_HandleTypeDef *  huart,  
  									uint8_t *  pData,  
  									uint16_t  Size,  
 									uint32_t  Timeout  
 								  ) 
//UART数据发送函数
HAL_StatusTypeDef HAL_UART_Transmit( UART_HandleTypeDef *  huart,  
  									 uint8_t *  pData,  
  									 uint16_t  Size,  
  									 uint32_t  Timeout  
 								   ) 
//UART接收中断回调函数
void HAL_UART_RxCpltCallback( UART_HandleTypeDef *  huart ) 
//UART中断服务函数
void HAL_UART_IRQHandler( UART_HandleTypeDef *  huart ) 
//内存初始化函数,常用于数组清零或初始化
void * memset(void *, int, size_t);
//以上函数参数不再做详细解释说明,具体可自行查阅HAL库手册和C语言库函数知识了解函数的具体功能和参数类型,这里小编给出一个STM32F1xxxHAL库官方手册以供读者使用。
链接:https://download.csdn.net/download/weixin_43803230/75395590

【HAL库官方手册下载链接】
STM32F1xxxHAL库官方手册

工程代码

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2022 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 "main.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "string.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define Rx_Buffer_Size 256	//最大接收字节数
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */
char Rx_Buffer[Rx_Buffer_Size];	//接收数据存储区
uint8_t aRxBuffer;				//接收数据中间存储区
uint8_t Uart1_Rx_Cnt = 0;		//接受数据长度
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */
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_RxCpltCallback could be implemented in the user file
   */
  if(Uart1_Rx_Cnt >= 255)
  {
	  Uart1_Rx_Cnt = 0;
	  memset(Rx_Buffer,0x00,sizeof(Rx_Buffer));
	  HAL_UART_Transmit(&huart1, (uint8_t *)"数据溢出", 10, 0xFFFF);
  }
  else
  {
	  Rx_Buffer[Uart1_Rx_Cnt++] = aRxBuffer;
	  if((Rx_Buffer[Uart1_Rx_Cnt-1] == 0x0A)&&(Rx_Buffer[Uart1_Rx_Cnt-2] == 0x0D))
	  {
		  if(Rx_Buffer[0] == 'y')	//当串口接收到字符' y '时,LED点亮
		  {
			  HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
			  HAL_UART_Transmit(&huart1, (uint8_t *)&"LED_ON ", 7, 0xFFFF);
		  }
		  if(Rx_Buffer[0] == 'n')	//当串口接收到字符' n '时,LED熄灭
		  {
			  HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
			  HAL_UART_Transmit(&huart1,(uint8_t *)&"LED_OFF ", 8, 0xFFFF);
		  }
		  HAL_UART_Transmit(&huart1, (uint8_t *)&Rx_Buffer, Uart1_Rx_Cnt,0xFFFF);
	      while(HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX);
	      Uart1_Rx_Cnt = 0;
	      memset(Rx_Buffer,0x00,sizeof(Rx_Buffer)); //清空数组
	  }
  }

  HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);   //再开启接收中断
}
/* USER CODE END 4 */

【重点】重要的代码是

//重点关注UART接收中断回调函数中的内容
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	********************
}
//其中这一段是串口调试助手向单片机发送指令控制LED亮灭的程序
/*如果去掉这一段代码,剩下的代码则是仅实现串口调试助手和单片机
进行数据收发的功能,串口调试助手向单片机发送什么,单片机就会将
接收到的数据发送给串口调试助手,并在串口调试助手上显示发的数据。
*/
if(Rx_Buffer[0] == 'y')	//当串口接收到字符' y '时,LED点亮
{
	HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
	HAL_UART_Transmit(&huart1, (uint8_t *)&"LED_ON ", 7, 0xFFFF);
}
if(Rx_Buffer[0] == 'n')	//当串口接收到字符' n '时,LED熄灭
{
	HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
	HAL_UART_Transmit(&huart1,(uint8_t *)&"LED_OFF ", 8, 0xFFFF);
}

例程实现效果

【STM32HAL库】STM32CubeMX+STM32CubeMXIDE系列教程(三)——USART串口通信_第9张图片
其中,当发‘ n ’时,单片机上的LED2会熄灭,当发‘ y ’时,单片机上的LED2会点亮。

完整工程文件

完整工程文件

结语

这次的UART也是一个简单的小例程,通过UART控制单片机的LED,知识UART控制单片机IO一个小方面,不过这个小例程的扩展性很大,可以将其扩展至控制继电器、控制PWM从而控制电机转速实现电机调速系统等等,除了使用串口调试助手,也可以根据特定的应用场合自行编写上位机,实现PC通过UART像单片机发送指令控制其他东西。有兴趣的读者可自行去探索更多的高级玩法,也可以和小编交流哦。对此工程有疑问的也可以评论和小编一起探讨。

如果觉得这篇文章对你有帮助的话就顺手点赞收藏关注一小编叭,您的认可时小编更新的最大动力,谢谢支持(^ _ ^)!!!

你可能感兴趣的:(HAL库,stm32,单片机,arm)