嵌入式开发学习之STM32F429串口(USART)收发数据

引言

在嵌入式系统中,串口通信是一种常见且重要的通信方式,广泛应用于各种嵌入式设备和系统中。串口通信通过串行传输数据,能够在不同设备之间可靠地传输数据,具有简单、稳定、成本低廉等优点,因此在许多嵌入式应用中得到了广泛应用。

重要性和应用场景
  1. 设备互联: 串口通信可以实现不同设备之间的数据交换和通信,如传感器与控制器之间的数据传输、嵌入式设备与外部设备的连接等。

  2. 调试和监控: 通过串口通信,可以实现对嵌入式系统的调试和监控,方便开发人员进行系统调试、数据采集和监测等工作。

  3. 远程控制: 串口通信还可以实现对嵌入式系统的远程控制,通过串口发送控制指令,实现对远程设备的控制和操作,如智能家居控制、远程数据采集等。

本文内容概述

本文将重点讨论STM32F407微控制器中的串口通信模块(USART)的配置和使用。主要内容包括:

  • STM32F407的USART模块简介:介绍USART模块的功能和特点,以及在嵌入式系统中的应用场景。

  • 硬件连接和配置:详细说明如何将USART模块连接到外部设备,并配置串口的时钟、工作模式、中断和DMA等参数。

  • 开发涉及工具:列举开发串口通信所需的工具,并简要介绍它们的作用。

  • 配置串口:讲解如何配置串口的I/O、参数属性、中断等。

  • 封装串口配置库文件:分步骤创建头文件和源文件,以便封装串口配置为可重用的库文件。

  • 功能实现:根据需求,实现串口收发数据的功能,并展示相关代码和实现细节。

STM32F429的USART模块简介

STM32F407微控制器中的USART(Universal Synchronous Asynchronous Receiver Transmitter)模块是一种功能强大的串口通信模块,具有以下特点和功能:

1. 通用性

USART模块是一种通用的串口通信模块,支持异步串口通信(UART)和同步串口通信(SPI、I2S等),可以满足不同通信需求。

2. 通信协议支持

USART模块支持多种通信协议,包括标准的异步串口通信协议(UART)、同步串口通信协议(SPI、I2S)以及LIN(Local Interconnect Network)等。

3. 外设支持

USART模块可以与多种外设进行通信,如传感器、GPS模块、蓝牙模块、WiFi模块、GSM模块等,实现数据的收发和控制指令的交互。

4. DMA支持

USART模块支持DMA(Direct Memory Access)控制器,可以通过DMA实现高效地数据传输,减少CPU的负载,提高系统性能。

5. 中断支持

USART模块支持中断机制,可以通过中断来处理接收和发送数据,提高系统的实时性和响应性。

6. 高可靠性

USART模块具有数据校验功能,可以通过校验位、奇偶校验和停止位等方式保证数据的可靠性和完整性。

7. 多功能性

USART模块具有丰富的功能特性,如自动波特率检测、多主机通信支持、多帧格式支持等,可以满足复杂通信场景的需求。

硬件连接和配置步骤

1. 引脚连接

将STM32F407微控制器的USART模块的引脚连接到外部设备上:

  • TX引脚连接至外部设备的RX引脚,用于发送数据。
  • RX引脚连接至外部设备的TX引脚,用于接收数据。
  • 如需使用硬件流控制功能,可连接CTS和RTS引脚。
2. 时钟配置

配置USART模块所需的时钟源和时钟频率:

  • 使用RCC(Reset and Clock Control)模块配置USART的时钟源和时钟分频系数,以满足通信波特率要求。
3. 工作模式配置

配置USART模块的工作模式和参数:

  • 设置USART模块的工作模式,包括异步模式(UART)或同步模式(SPI、I2S)。
  • 配置数据位长度、停止位数、奇偶校验位等参数。
4. 中断配置

配置USART模块的中断使能和中断优先级:

  • 通过NVIC(Nested Vectored Interrupt Controller)模块使能USART接收和发送中断,并设置中断优先级。
5. DMA配置(可选)

配置USART模块的DMA支持:

  • 使用DMA控制器配置USART的接收和发送DMA通道,实现数据的高效传输。
6. 初始化USART模块

最后,根据配置的参数初始化USART模块,启动USART通信功能。

基本的串口收发数据流程

初始化串口

  1. 配置串口的工作模式、波特率、数据位长度、停止位数、奇偶校验位等参数。
  2. 启动串口功能,使能发送和接收功能。

发送数据

  1. 准备要发送的数据,可以是单个字节或数据包。
  2. 将数据写入串口发送缓冲区。
  3. 等待发送完成,可以通过轮询或中断方式检查发送完成状态。

接收数据

  1. 监听串口接收缓冲区,等待接收到数据。
  2. 一旦接收到数据,将数据从接收缓冲区读取出来。
  3. 对接收到的数据进行处理,例如解析数据包或执行相应操作。
// 初始化串口
init_uart();

while (1) {
    // 发送数据
    uint8_t data_to_send = generate_data();
    send_data(data_to_send);

    // 接收数据
    if (uart_has_data()) {
        uint8_t received_data = read_received_data();
        process_received_data(received_data);
    }
}

在实际应用中,可以根据具体的需求和硬件平台选择合适的API函数或库来实现串口的初始化、发送和接收功能。

开发涉及工具

  1. 开发板

    • 开发板是用于开发和测试嵌入式系统的硬件平台,通常包含了处理器、内存、各种接口以及调试功能。
    • 它提供了一个环境,使得开发者可以在上面运行和调试他们的程序。
  2. 串口调试助手

    • 串口调试助手是一种软件工具,用于监视和调试串口通信。
    • 它可以显示发送和接收的数据,支持实时监视、数据记录、发送指令等功能,帮助开发者验证串口通信的正确性。
  3. 逻辑分析仪

    • 逻辑分析仪是一种测试工具,用于捕获和分析数字信号。
    • 它可以帮助开发者观察串口通信的信号波形、时序关系,用于调试通信问题和优化性能。
  4. 示波器

    • 示波器是一种用于显示电信号波形的仪器,可用于调试串口通信中的信号质量和时序问题。
    • 它可以帮助开发者观察串口信号的波形、幅度、频率等特性,识别和解决通信中的问题。
  5. 开发工具链

    • 包括编译器、调试器、下载工具等,用于编写、编译、调试和下载嵌入式软件到目标设备。
    • 这些工具支持开发者编写和调试串口通信相关的程序,确保程序的正确性和稳定性。

配置串口

包含头文件和定义常量

#include "stm32F4xx.h"
#include "stm32f4xx_conf.h"
#include "stdio.h"
#include "led.h"
#include "delay.h"
#include "key.h"

初始化串口硬件 

int main(void)
{
	
	    GPIO_InitTypeDef gpio_info;
		USART_InitTypeDef  USART_InitStructure;
		NVIC_InitTypeDef  NVIC_InitStructure;
    
        LED_init();
        key1_init();
        key2_init();
        Delay_init();
	

    
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOH,ENABLE);
    
        gpio_info.GPIO_Mode = GPIO_Mode_AF;
        gpio_info.GPIO_OType = GPIO_OType_PP;
        gpio_info.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;
        gpio_info.GPIO_PuPd = GPIO_PuPd_UP;
        gpio_info.GPIO_Speed = GPIO_Low_Speed;
        GPIO_Init(GPIOA,&gpio_info);
		
	
		GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);
		GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);
	
		
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
		
		
		USART_InitStructure.USART_BaudRate = 115200;
		USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
		USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
		USART_InitStructure.USART_Parity = USART_Parity_No;
		USART_InitStructure.USART_StopBits = USART_StopBits_1;
		USART_InitStructure.USART_WordLength = USART_WordLength_8b;
		USART_Init(USART1,&USART_InitStructure);
		
		
		USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);

		NVIC_InitStructure.NVIC_IRQChannel =  USART1_IRQn;  
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
        NVIC_Init(&NVIC_InitStructure);
		
		
		
		USART_Cmd(USART1,ENABLE);
    }

}

这段代码是用于初始化STM32的USART1串口,并配置为115200波特率,无硬件流控,无奇偶校验,1个停止位,8位数据位的通信模式。让我逐步解释:

  1. GPIO初始化:

    • 初始化了GPIOH,配置为复用功能(AF)。
    • 设置了引脚9和引脚10为GPIO的AF功能。
  2. 时钟使能:

    • 使能了GPIOA的时钟,因为USART1的引脚连接到GPIOA。
  3. GPIO引脚复用配置:

    • 使用 GPIO_PinAFConfig() 函数将引脚9和引脚10配置为USART1的复用功能。
  4. USART时钟使能:

    • 使能了USART1的时钟。
  5. USART初始化:

    • 配置了USART1的参数,包括波特率、硬件流控、模式(接收和发送)、奇偶校验、停止位和数据位长度。
  6. USART中断配置:

    • 使能了USART1的接收中断(USART_IT_RXNE),这表示当接收缓冲区非空时将产生中断。
    • 配置了USART1的中断优先级和使能中断。
  7. 使能USART:

    • 最后,使能了USART1,启动串口通信。

封装串口配置库文件

第一步:创建头文件

首先,我们需要创建一个头文件,其中包含函数声明和必要的宏定义。创建一个名为 uart_config.h 的文件,并在其中添加以下内容:

#ifndef UART_CONFIG_H
#define UART_CONFIG_H

#include <stdint.h>

// 函数声明
void init_uart();
void set_uart_params();
void init_uart_interrupt();
void uart_receive_isr();

#endif /* UART_CONFIG_H */

第二步:创建源文件

接下来,我们创建一个源文件,命名为 uart_config.c,并实现头文件中声明的函数。这里以上提供的代码为基础,稍作修改后进行封装。假设我们把代码放在 Src 文件夹下。

#include "uart_config.h"
#include "stm32f4xx.h"  // 假设你在使用STM32F4系列的微控制器

void init_uart() {
    GPIO_InitTypeDef gpio_info;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    // 初始化串口硬件
    // 这里省略具体实现,根据具体硬件平台完成初始化操作

    // 设置串口参数
    set_uart_params();
}

void set_uart_params() {
    // 设置波特率等参数
    // 省略具体设置,根据需求来设置
}

void init_uart_interrupt() {
    // 配置串口接收中断使能
    // 根据硬件手册和需求来配置相应的寄存器

    // 注册串口接收中断服务函数
    // 这一步根据具体的编程环境和操作系统来完成
}

void uart_receive_isr() {
    // 在这里处理串口接收中断
    // 省略具体实现
}

第三步:使用库文件

#include "uart_config.h"

int main() {
    // 初始化串口
    init_uart();

    // 以下为主程序逻辑
    // 可以在这里编写串口通信相关的代码

    return 0;
}

功能实现

1. 创建工程

首先,在STM32CubeIDE中创建一个新的STM32工程,并选择对应的芯片型号。

2. 配置串口

使用CubeMX配置串口。在Pinout & Configuration选项卡中配置USART1,并启用其收发功能。确保选择正确的引脚,并设置波特率为115200。

3. 生成代码

生成代码并打开工程。

4. 编写代码

main.c文件中编写串口收发数据的代码:

#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_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  
  uint8_t tx_data[] = "Hello, World!\n";
  uint8_t rx_data[20];
  
  while (1)
  {
    HAL_UART_Transmit(&huart1, tx_data, sizeof(tx_data), HAL_MAX_DELAY);
    HAL_UART_Receive(&huart1, rx_data, sizeof(rx_data), HAL_MAX_DELAY);
    HAL_Delay(1000);
  }
}

void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = 8;
  RCC_OscInitStruct.PLL.PLLN = 50;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  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_3) != HAL_OK)
  {
    Error_Handler();
  }
}

static void MX_USART1_UART_Init(void)
{
  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();
  }
}

static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  __HAL_RCC_GPIOA_CLK_ENABLE();
  
  /**USART1 GPIO Configuration    
  PA9     ------> USART1_TX
  PA10     ------> USART1_RX 
  */
  GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}

5. 编译并下载到STM32芯片

编译代码,并将程序下载到STM32芯片中。

6. 测试

连接串口调试助手,你应该能够看到串口发送 "Hello, World!" 字符串,并且能够收到芯片回传的数据。

实际应用案例

场景描述:

1. 系统硬件组成:
  • STM32微控制器:负责控制整个系统的操作,包括串口通信和数据处理。
  • 温度传感器:用于测量环境温度,并将数据通过串口发送给STM32微控制器。
  • 上位机:通过串口连接到STM32微控制器,接收并处理传感器发送的温度数据,并进行可视化展示。
2. 系统工作流程:
  1. STM32微控制器初始化并配置串口通信功能。
  2. 温度传感器定期测量环境温度,并将数据通过串口发送给STM32微控制器。
  3. STM32微控制器接收传感器发送的温度数据,并进行必要的处理(如单位转换、数据滤波等)。
  4. 处理后的数据通过串口发送给上位机。
  5. 上位机接收并解析串口数据,将温度数据显示在界面上,可能还会进行进一步的分析和处理。

实际应用案例:

在实际场景中,我们可以将这个智能温度监控系统应用于以下场景之一:

1. 室内温度监测:

在办公室、实验室或生产车间等场所安装多个温度传感器,通过STM32微控制器将数据发送到上位机,实时监测和记录室内温度变化,以确保环境舒适度和生产安全。

2. 冷链物流监控:

在冷藏货车、冷库或冷链仓库中安装温度传感器,通过STM32微控制器将温度数据传输到上位机,实时监测货物的温度变化,确保货物处于适宜的温度范围内,防止货物腐坏或变质。

3. 智能农业:

在农田、温室或养殖场中安装温度传感器,通过STM32微控制器将温度数据发送到上位机,帮助农民监测环境温度,合理调节种植或养殖条件,提高农作物或动物的产量和品质。

4. 温度控制系统:

与空调、加热器或温室控制系统集成,实现自动调节温度的功能。STM32微控制器通过串口接收温度传感器的数据,并根据设定的温度范围控制相应的设备,实现环境温度的自动调节。

通过以上应用案例,展示了串口通信在嵌入式系统中与传感器、外部设备的数据交换的实际应用。

总结 

串口通信在嵌入式开发中具有重要的地位和价值。通过串口通信,嵌入式系统可以与外部设备(如传感器、上位机等)进行可靠的数据交换和通信,实现数据采集、控制和监测等功能。本文介绍了一个智能温度监控系统的设计和应用案例,强调了串口通信在实时数据传输和系统集成中的关键作用。

学习嵌入式开发中串口通信的意义在于:

  1. 实时数据传输: 串口通信可以实现实时数据传输,将传感器采集到的数据快速、可靠地传输到上位机或其他设备进行处理和分析。

  2. 系统集成: 通过串口通信,嵌入式系统可以与各种外部设备进行连接和通信,实现系统功能的扩展和灵活性的增强。

  3. 应用广泛: 串口通信在各种领域和行业中都有广泛的应用,如工业控制、物联网、医疗设备等,学习串口通信能够为未来的职业发展打下坚实的基础。

  4. 解决实际问题: 通过串口通信,可以设计和实现各种实用的嵌入式系统,解决现实生活中的各种问题,如环境监测、智能控制、数据采集等。

因此,学习嵌入式开发中的串口通信是非常有价值的,能够为个人技能提升和职业发展带来重要的收益。

  • 13
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值