打印
[STM32F4]

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

[复制链接]
55|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
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的数据。
#include "main.h"
#include "stm32f4xx_hal.h"

UART_HandleTypeDef huart1;

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);

int main(void)
{
    // 初始化HAL库
    HAL_Init();
   
    // 配置系统时钟
    SystemClock_Config();
   
    // 初始化GPIO
    MX_GPIO_Init();
   
    // 初始化USART1
    MX_USART1_UART_Init();
   
    uint8_t txData[] = "Hello from STM32!";
    uint8_t rxData[20];
   
    // 主循环
    while (1)
    {
        // 发送数据
        HAL_UART_Transmit(&huart1, txData, sizeof(txData) - 1, HAL_MAX_DELAY);
        
        // 接收数据
        HAL_UART_Receive(&huart1, rxData, sizeof(rxData), HAL_MAX_DELAY);
        
        // 根据接收到的数据做相应处理
        if (rxData[0] == '1')
        {
            HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_12); // 控制LED
        }
        
        HAL_Delay(1000); // 延时1秒
    }
}

void SystemClock_Config(void)
{
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
   
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
    RCC_OscInitStruct.HSEState = RCC_HSE_ON;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
    RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL9;
    HAL_RCC_OscConfig(&RCC_OscInitStruct);
   
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
    HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);
}

static void MX_GPIO_Init(void)
{
    __HAL_RCC_GPIOD_CLK_ENABLE();
   
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Pin = GPIO_PIN_12;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
}

static void MX_USART1_UART_Init(void)
{
    __HAL_RCC_USART1_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();
   
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Pin = GPIO_PIN_9; // USART1 TX
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
   
    GPIO_InitStruct.Pin = GPIO_PIN_10; // USART1 RX
    GPIO_InitStruct.Mode = GPIO_MODE_AF_INPUT;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
   
    huart1.Instance = USART1;
    huart1.Init.BaudRate = 9600;
    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;
   
    HAL_UART_Init(&huart1);
}
代码解析
  • 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灯,换成蜂鸣器行吗?

使用特权

评论回复
5
童雨竹| | 2025-1-18 07:28 | 只看该作者
我发现这块MCU配置起来有点复杂,有没有什么工具可以简化开发?

使用特权

评论回复
6
万图| | 2025-1-18 07:28 | 只看该作者
你们有没有遇到过USART数据丢失的情况?我有时候数据接收不全。

使用特权

评论回复
7
Wordsworth| | 2025-1-18 07:29 | 只看该作者
这篇文章给我很大帮助,我用的就是STM32F4Discovery,已经开始做项目了。

使用特权

评论回复
8
Bblythe| | 2025-1-18 07:29 | 只看该作者
有没有类似的例子可以实现温度传感器的串口通信?我在做环境监控项目。

使用特权

评论回复
9
Pulitzer| | 2025-1-18 07:29 | 只看该作者
大神们,HAL库和裸机编程有什么区别?用HAL库会不会影响性能?

使用特权

评论回复
10
Uriah| | 2025-1-18 07:30 | 只看该作者
学到了,USART确实是个很有用的功能,我准备用它做一个数据采集的系统。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

35

主题

3491

帖子

0

粉丝