[STM32F4] 深入了解STM32F407VG:实现USART串口通信的完整示例

[复制链接]
1837|11
 楼主| Clyde011 发表于 2025-1-18 07:27 | 显示全部楼层 |阅读模式
STM32系列单片机广泛应用于各种嵌入式开发中,其中STM32F4系列以其高性能和丰富的外设配置,成为开发者的首选之一。本文将详细介绍STM32F407VG单片机,重点讲解如何使用该芯片实现USART串口通信,并通过实例代码帮助大家更好地理解STM32F4系列的应用。
STM32F407VG概述STM32F407VG是一款基于ARM Cortex-M4内核的高性能32位微控制器,适用于高速信号处理和复杂算法的应用。其主要特点包括:
  • 内核:Cortex-M4,主频可达168 MHz,支持浮点运算
  • 内存:512 KB Flash,192 KB SRAM
  • 外设:USART、SPI、I2C、ADC、DAC、CAN、USB、SDIO等
  • 输入输出:168个I/O引脚,支持多种功能
  • 工作电压:2.0V到3.6V
  • 工作温度:-40℃到+85℃
STM32F407VG具有强大的计算能力和丰富的外设,适合需要高速通信、大数据处理、实时控制的应用。其内置的浮点运算单元(FPU)使得数**算效率更高,尤其适合需要快速数据处理的任务。
开发环境配置
  • 开发板:常见的开发板如STM32F4Discovery或Nucleo-F4系列。
  • 编程器:ST-LINK/V2调试器或J-Link。
  • 开发环境:STM32CubeIDE或者Keil uVision。
在本教程中,我们将使用STM32CubeIDE进行开发,STM32CubeIDE集成了代码编写、调试和生成外设配置的工具,适合初学者和有经验的开发者。
USART串口通信简介USART(通用同步异步收发传输器)是一种常见的串行通信接口,在嵌入式开发中非常重要。STM32F407VG提供了多个USART接口,可以进行串口通信。通过USART,我们可以将数据从MCU发送到其他设备或接收外部设备的数据。
USART工作模式:
  • 异步模式:常用于常规的串口通信,如PC与MCU之间的通信。
  • 同步模式:用于高速数据传输,通常与外部时钟同步。
USART串口通信示例本示例将介绍如何在STM32F407VG上实现一个简单的USART通信程序,其中MCU将通过串口发送数据,并接收来自PC的指令。我们将使用USART1进行通信,并配置为异步模式。
配置步骤
  • 启动STM32CubeIDE并创建新项目,选择STM32F407VG作为目标MCU。
  • 在Pinout & Configuration中,将PA9(TX)和PA10(RX)配置为USART1的TX和RX引脚。
  • 配置USART1外设,设置波特率为9600,数据位8,停止位1,无校验。
  • 配置系统时钟,默认设置即可。
  • 生成代码并打开项目。
编写代码下面是实现USART串口通信的代码示例。在该程序中,我们将通过USART1发送一串数据并接收来自PC的数据。
  1. #include "main.h"
  2. #include "stm32f4xx_hal.h"

  3. UART_HandleTypeDef huart1;

  4. void SystemClock_Config(void);
  5. static void MX_GPIO_Init(void);
  6. static void MX_USART1_UART_Init(void);

  7. int main(void)
  8. {
  9.     // 初始化HAL库
  10.     HAL_Init();
  11.    
  12.     // 配置系统时钟
  13.     SystemClock_Config();
  14.    
  15.     // 初始化GPIO
  16.     MX_GPIO_Init();
  17.    
  18.     // 初始化USART1
  19.     MX_USART1_UART_Init();
  20.    
  21.     uint8_t txData[] = "Hello from STM32!";
  22.     uint8_t rxData[20];
  23.    
  24.     // 主循环
  25.     while (1)
  26.     {
  27.         // 发送数据
  28.         HAL_UART_Transmit(&huart1, txData, sizeof(txData) - 1, HAL_MAX_DELAY);
  29.         
  30.         // 接收数据
  31.         HAL_UART_Receive(&huart1, rxData, sizeof(rxData), HAL_MAX_DELAY);
  32.         
  33.         // 根据接收到的数据做相应处理
  34.         if (rxData[0] == '1')
  35.         {
  36.             HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_12); // 控制LED
  37.         }
  38.         
  39.         HAL_Delay(1000); // 延时1秒
  40.     }
  41. }

  42. void SystemClock_Config(void)
  43. {
  44.     RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  45.     RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  46.    
  47.     RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  48.     RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  49.     RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  50.     RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  51.     RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL9;
  52.     HAL_RCC_OscConfig(&RCC_OscInitStruct);
  53.    
  54.     RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
  55.     RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  56.     HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);
  57. }

  58. static void MX_GPIO_Init(void)
  59. {
  60.     __HAL_RCC_GPIOD_CLK_ENABLE();
  61.    
  62.     GPIO_InitTypeDef GPIO_InitStruct = {0};
  63.     GPIO_InitStruct.Pin = GPIO_PIN_12;
  64.     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  65.     GPIO_InitStruct.Pull = GPIO_NOPULL;
  66.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  67.     HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
  68. }

  69. static void MX_USART1_UART_Init(void)
  70. {
  71.     __HAL_RCC_USART1_CLK_ENABLE();
  72.     __HAL_RCC_GPIOA_CLK_ENABLE();
  73.    
  74.     GPIO_InitTypeDef GPIO_InitStruct = {0};
  75.     GPIO_InitStruct.Pin = GPIO_PIN_9; // USART1 TX
  76.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  77.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  78.     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  79.    
  80.     GPIO_InitStruct.Pin = GPIO_PIN_10; // USART1 RX
  81.     GPIO_InitStruct.Mode = GPIO_MODE_AF_INPUT;
  82.     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  83.    
  84.     huart1.Instance = USART1;
  85.     huart1.Init.BaudRate = 9600;
  86.     huart1.Init.WordLength = UART_WORDLENGTH_8B;
  87.     huart1.Init.StopBits = UART_STOPBITS_1;
  88.     huart1.Init.Parity = UART_PARITY_NONE;
  89.     huart1.Init.Mode = UART_MODE_TX_RX;
  90.     huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  91.     huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  92.    
  93.     HAL_UART_Init(&huart1);
  94. }
代码解析
  • HAL库初始化:初始化HAL库,使得系统可以使用HAL驱动。
  • USART初始化:通过MX_USART1_UART_Init()函数配置USART1,设置波特率为9600、数据位8、停止位1等。
  • 数据传输:通过HAL_UART_Transmit()函数发送数据,通过HAL_UART_Receive()接收来自PC的数据。
  • LED控制:根据接收到的命令(如'1'),控制GPIO引脚输出,从而点亮或熄灭LED。
编译与烧录编写完代码后,可以使用STM32CubeIDE进行编译,并通过ST-LINK/V2调试器将程序烧录到STM32F407VG开发板上。完成烧录后,使用串口调试工具(如PuTTY)连接到MCU的USART1接口,发送数据并观察LED的变化。
总结STM32F407VG是一个高性能的MCU,适用于复杂的嵌入式应用。在本示例中,我们演示了如何使用USART串口进行数据传输和接收,以及如何通过接收到的指令控制LED灯。这个基础示例可以扩展到更复杂的通信协议和控制任务,帮助开发者快速入门STM32F4系列的应用开发。

公羊子丹 发表于 2025-1-18 07:27 | 显示全部楼层
感觉这篇文章写得挺实用的,USART的配置终于搞明白了,感谢!
周半梅 发表于 2025-1-18 07:27 | 显示全部楼层
大佬,这个代码能用于其他型号的STM32吗?我用的是STM32F103C8T6。
帛灿灿 发表于 2025-1-18 07:28 | 显示全部楼层
我按照这个例子写了个串口通信程序,工作得挺好,就是没有LED灯,换成蜂鸣器行吗?
童雨竹 发表于 2025-1-18 07:28 | 显示全部楼层
我发现这块MCU配置起来有点复杂,有没有什么工具可以简化开发?
万图 发表于 2025-1-18 07:28 | 显示全部楼层
你们有没有遇到过USART数据丢失的情况?我有时候数据接收不全。
Wordsworth 发表于 2025-1-18 07:29 | 显示全部楼层
这篇文章给我很大帮助,我用的就是STM32F4Discovery,已经开始做项目了。
Bblythe 发表于 2025-1-18 07:29 | 显示全部楼层
有没有类似的例子可以实现温度传感器的串口通信?我在做环境监控项目。
Pulitzer 发表于 2025-1-18 07:29 | 显示全部楼层
大神们,HAL库和裸机编程有什么区别?用HAL库会不会影响性能?
Uriah 发表于 2025-1-18 07:30 | 显示全部楼层
学到了,USART确实是个很有用的功能,我准备用它做一个数据采集的系统。
Amazingxixixi 发表于 2025-1-21 17:11 | 显示全部楼层
学习一下啊,还有好多需要学习的。
SophiaOP 发表于 2025-1-22 22:07 来自手机 | 显示全部楼层
407是不是有标准库啊
您需要登录后才可以回帖 登录 | 注册

本版积分规则

167

主题

6004

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部