stm32——UART和USART

news2025/6/9 9:44:26

串口通信协议UART和USART


1. UART与USART协议详解

特性UART (Universal Asynchronous Receiver/Transmitter)USART (Universal Synchronous Asynchronous Receiver/Transmitter)
全称通用异步收发器通用同步/异步收发器
同步/异步异步:不共享时钟,数据通过起始位和停止位同步。同步和异步:<br/>- 异步模式:与UART相同,不共享时钟。<br/>- 同步模式:共享时钟信号,适用于需要更高数据传输速率和更严格时序的场景,例如SPI、I2S等。
时钟无独立时钟线,发送端和接收端各自使用内部时钟,通过波特率匹配实现通信。异步模式下无独立时钟线。同步模式下有独立时钟线(CK引脚)。
数据传输串行全双工,通过TX和RX引脚进行数据传输。串行全双工,通过TX和、RX、CK(同步时钟)、NSS(从设备选择)引脚进行数据传输。
数据帧起始位 + 数据位 (5-9位) + 奇偶校验位 (可选) + 停止位 (1或2位)异步模式下与UART相同。同步模式下数据帧结构更灵活,通常没有起始位和停止位,数据传输由时钟控制。
数据速率相对较低,受波特率匹配和晶振精度限制。同步模式下可实现更高的数据速率。
应用场景简单设备通信(如与PC串口通信、蓝牙模块、GPS模块、GSM模块等)需要高速、高精度数据传输的场景(如与外部ADC、DAC、EEPROM、其他MCU等)
STM32支持大多数STM32微控制器都集成了多个UART接口。大多数STM32微控制器都集成了多个USART接口。
流控制硬件流控制 (CTS/RTS) 可选支持。硬件流控制 (CTS/RTS) 可选支持。
1.1 UART与USART的工作原理
UART (异步模式)
  • 数据帧结构:
    • 空闲态: 线路处于高电平。
    • 起始位 (Start Bit): 由高电平跳变为低电平,持续一个位周期,标志着数据传输的开始。
    • 数据位 (Data Bits): 通常为5到9位,低位在前,高位在后。
    • 奇偶校验位 (Parity Bit - 可选): 用于检测数据传输过程中的错误。根据数据位中1的数量,奇校验使1的数量为奇数,偶校验使1的数量为偶数。
    • 停止位 (Stop Bit): 高电平,通常为1位或2位,标志着数据帧的结束。
    • 空闲态: 线路再次回到高电平。
  • 同步方式: 发送端和接收端通过预设的波特率进行通信。接收端根据起始位检测到数据传输开始,然后按照波特率的节拍依次采样数据位和停止位。两者的波特率必须尽可能接近,否则可能导致数据错误。
USART (同步模式)
  • 时钟同步: 在同步模式下,发送端和接收端共享一个时钟信号(CK引脚)。发送端在时钟的上升沿或下降沿输出数据,接收端在对应的时钟沿采样数据。这确保了数据传输的严格同步性,从而实现更高的传输速率和更可靠的数据传输。
  • 应用: 常常用于与需要外部时钟的设备进行通信,例如SPI、I2S协议的底层实现。STM32的USART模块可以配置为同步主模式或从模式。

2. STM32中UART/USART开发流程

在STM32中开发UART/USART通信通常涉及以下几个步骤。我们将以STM32CubeMX和HAL库为例进行详细讲解。

2.1 硬件连接

确保你的STM32开发板与外部设备(如PC的USB转串口模块、其他MCU、蓝牙模块等)正确连接。

  • STM32 TX 引脚连接到 外部设备 RX 引脚。
  • STM32 RX 引脚连接到 外部设备 TX 引脚。
  • GND 连接到 GND
  • 如果使用硬件流控制,还需要连接 RTSCTS 引脚。
2.2 STM32CubeMX配置

STM32CubeMX是一款强大的图形化工具,可以帮助我们快速配置STM32微控制器,生成初始化代码。

  1. 新建工程: 打开STM32CubeMX,选择“New Project”,选择你的STM32型号。
  2. 配置时钟: 在“System Core” -> “RCC”中,配置高速外部晶振(HSE)或内部高速时钟(HSI)。然后到“Clock Configuration”页面,配置系统时钟树,确保外设时钟(APB1/APB2)满足UART/USART需求。
  3. 配置UART/USART
    • 在“Connectivity”分类下,选择需要使用的UART/USART外设(例如:USART1)。
    • 在配置界面中,将“Mode”设置为“Asynchronous”(异步模式,即UART功能)或“Synchronous”(同步模式,即USART功能)。
    • 异步模式(UART)配置
      • Baud Rate (波特率): 设置通信速率,例如:115200 bps。
      • Word Length (数据位): 8 Bits或9 Bits。
      • Parity (奇偶校验): None(无)、Even(偶校验)或Odd(奇校验)。
      • Stop Bits (停止位): 1 Bit或2 Bits。
      • Data Direction (数据方向): Receive and Transmit。
      • Hardware Flow Control (硬件流控制): None(无)、RTS/CTS。
    • 同步模式(USART)配置
      • 除了上述异步模式的配置外,还需要配置“Clock Polarity”和“Clock Phase”,这对于同步通信至关重要,需要与外部设备的设置相匹配。
      • 通常还需要配置“NSS Signal”为“Hardware NSS Output”或“Software NSS”。
    • GPIO设置: CubeMX会自动为UART/USART配置相应的TX和RX引脚。
  4. 配置中断: 如果需要使用中断接收或发送数据,在“NVIC Settings”选项卡中,勾选对应UART/USART中断的“Enabled”复选框。
  5. 生成代码: 点击“Project”->“Generate Code”生成工程文件。选择你的IDE(MDK-ARM、TrueSTUDIO等)。
2.3 编写应用程序代码

生成代码后,在你的IDE中打开工程。主要的工作将在main.c文件和其他相关文件中完成。

2.3.1 初始化 (由CubeMX生成)

CubeMX会生成UART/USART的初始化代码,通常在main.c中的MX_USARTx_UART_Init()MX_USARTx_Init()函数中。

// 示例:USART1初始化代码片段 (由CubeMX生成)
UART_HandleTypeDef huart1;

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();
  }
}
2.3.2 数据发送

HAL库提供了多种数据发送方式:

  • 轮询发送 (阻塞式): 简单易用,但会阻塞CPU直到发送完成。

    char tx_data[] = "Hello, STM32 UART!\r\n";
    HAL_UART_Transmit(&huart1, (uint8_t*)tx_data, strlen(tx_data), HAL_MAX_DELAY);
    
    • &huart1: UART句柄。
    • (uint8_t*)tx_data: 要发送的数据的指针。
    • strlen(tx_data): 要发送的数据的长度。
    • HAL_MAX_DELAY: 超时时间,HAL_MAX_DELAY表示一直等待直到发送完成。
  • 中断发送 (非阻塞式): 在后台发送数据,发送完成后会触发中断。

    char tx_data[] = "Hello, Interrupt!\r\n";
    HAL_UART_Transmit_IT(&huart1, (uint8_t*)tx_data, strlen(tx_data));
    // 发送完成后会调用HAL_UART_TxCpltCallback()回调函数
    
  • DMA发送 (非阻塞式): 效率最高,适用于大量数据传输,DMA控制器在后台完成数据传输,CPU可以执行其他任务。

    char tx_data[] = "Hello, DMA!\r\n";
    HAL_UART_Transmit_DMA(&huart1, (uint8_t*)tx_data, strlen(tx_data));
    // 发送完成后会调用HAL_UART_TxCpltCallback()回调函数
    
2.3.3 数据接收

HAL库也提供了多种数据接收方式:

  • 轮询接收 (阻塞式): 等待接收到指定长度的数据后返回。

    uint8_t rx_buffer[20];
    HAL_UART_Receive(&huart1, rx_buffer, sizeof(rx_buffer), HAL_MAX_DELAY);
    // 接收到20字节数据后继续执行
    
  • 中断接收 (非阻塞式): 接收到1个字节或指定长度的数据后会触发中断,可以在中断回调函数中处理数据。

    uint8_t rx_byte;
    // 启动一个字节的中断接收
    HAL_UART_Receive_IT(&huart1, &rx_byte, 1);
    // 在HAL_UART_RxCpltCallback()中处理接收到的字节,并再次启动接收
    

    stm32f1xx_it.c中(或其他中断服务文件)会调用HAL库的回调函数:

    void USART1_IRQHandler(void)
    {
      HAL_UART_IRQHandler(&huart1);
    }
    

    main.c(或其他自定义文件)中重写接收完成回调函数:

    uint8_t rx_buffer[BUFFER_SIZE];
    uint16_t rx_index = 0; // 接收数据索引
    
    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    {
      if (huart->Instance == USART1)
      {
        // 接收到1个字节,将其存储到缓冲区
        rx_buffer[rx_index++] = huart->RxXferData[0]; // 获取接收到的字节
        if (rx_index >= BUFFER_SIZE)
        {
          rx_index = 0; // 缓冲区满,重置索引或进行处理
        }
        // 重新启动单字节接收,以便接收下一个字节
        HAL_UART_Receive_IT(&huart1, (uint8_t*)&huart1.RxXferData[0], 1);
      }
    }
    
    • 注意: 对于中断接收,通常的做法是每次接收一个字节,然后在回调函数中处理接收到的字节,并再次启动单字节接收,以实现连续接收。
  • DMA接收 (非阻塞式): 最推荐的方式,将接收到的数据直接传输到内存缓冲区,大大减轻CPU负担。

    uint8_t rx_buffer[BUFFER_SIZE];
    HAL_UART_Receive_DMA(&huart1, rx_buffer, BUFFER_SIZE);
    // 接收到BUFFER_SIZE长度的数据后会调用HAL_UART_RxCpltCallback()回调函数
    

    与中断接收类似,需要重写HAL_UART_RxCpltCallback()来处理接收到的数据。

2.4 编译和烧录

完成代码编写后,编译工程并将其烧录到STM32微控制器中。

2.5 调试和测试
  • 使用串口调试助手: 在PC上打开串口调试助手(如XCOM、Putty、SecureCRT等),配置与STM32相同的波特率、数据位、停止位和奇偶校验。
  • 发送/接收数据: 在PC端发送数据到STM32,观察STM32是否正确接收并处理。在STM32端发送数据,观察PC端是否正确显示。
  • 调试工具: 使用STM32的SWD/JTAG调试器(如ST-Link),可以在IDE中进行单步调试、设置断点、查看变量值等,以便找出问题。

3. 常见问题与优化

  • 波特率不匹配: 这是最常见的问题。确保发送端和接收端的波特率完全一致。
  • 引脚连接错误: 检查TX和RX引脚是否交叉连接。
  • 时钟配置错误: 确保UART/USART外设的时钟频率配置正确,影响波特率的计算。
  • 缓冲区溢出: 在使用中断或DMA接收时,如果没有及时处理接收到的数据,可能会导致缓冲区溢出。需要合理设计缓冲区大小和数据处理逻辑。
  • 噪声干扰: 在复杂的电磁环境下,通信线路可能受到噪声干扰,导致数据错误。可以考虑使用屏蔽线、差分信号传输或增加奇偶校验来提高鲁棒性。
  • 中断优先级: 如果同时使用多个中断,需要合理设置中断优先级,避免中断嵌套问题。
  • 空闲帧检测: UART通常会检测到接收线路上的空闲帧(长时间高电平)来判断数据传输是否结束。
  • 错误处理: 在实际应用中,需要考虑接收错误(帧错误、奇偶校验错误、溢出错误等),并在代码中添加相应的错误处理机制。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2405201.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

算法题(165):汉诺塔问题

审题&#xff1a; 本题需要我们找到最优的汉诺塔搬法然后将移动路径输出 思路&#xff1a; 方法一&#xff1a;递归 我们先分析题目 n为2的情况&#xff0c;我们先将第一个盘子移动到三号柱子上&#xff0c;然后再将二号盘子移动到二号柱子上 n为3的情况&#xff0c;我们先将前…

玄机——某次行业攻防应急响应(带镜像)

今天给大家带来一次攻防实战演练复现的过程。 文章目录 简介靶机简介1.根据流量包分析首个进行扫描攻击的IP是2.根据流量包分析第二个扫描攻击的IP和漏扫工具&#xff0c;以flag{x.x.x.x&工具名}3.提交频繁爆破密钥的IP及爆破次数&#xff0c;以flag{ip&次数}提交4. 提…

低代码逻辑引擎配置化实战:三步穿透审批记录查询

在堆积如山的报销单中埋头寻找某笔特殊费用的审批轨迹在跨部门协作时被追问"这个合同到底卡在哪个环节" 在快节奏的办公自动化场景中&#xff0c;这些场景是很常见的&#xff0c;传统OA系统中分散的审批记录查询方式往往太繁琐。 为破解这一痛点&#xff0c;在JVS低…

【Zephyr 系列 15】构建企业级 BLE 模块通用框架:驱动 + 事件 + 状态机 + 低功耗全栈设计

🧠关键词:Zephyr、BLE 模块、架构设计、驱动封装、事件机制、状态机、低功耗、可维护框架 📌面向读者:希望将 BLE 项目从“Demo 工程”升级为“企业可复用框架”的研发人员与技术负责人 📊预计字数:5500+ 字 🧭 前言:从 Demo 到产品化,架构该如何升级? 多数 BLE…

Docker构建Vite项目内存溢出:从Heap Limit报错到完美解决的剖析

问题现象:诡异的"消失的index.html" 最近在CI/CD流水线中遇到诡异现象:使用Docker构建Vite项目时,dist目录中缺少关键的index.html文件,但本地构建完全正常。报错截图显示关键信息: FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out…

Android端口转发

如上图所示&#xff0c;有一个Android设备&#xff0c;Android设备里面有主板&#xff0c;主板上有网络接口和Wi-Fi&#xff0c;网络接口通过网线连接了一个网络摄像头&#xff0c;这就跟电脑一样&#xff0c;电脑即可以通过网线接入一个网络&#xff0c;也可以同时用Wi-Fi接入…

PHP环境极速搭建

一、为什么选择phpStudy VS Code&#xff1f; 作为一名初次接触PHP的开发者&#xff0c;我深知环境配置往往是学习路上的第一道门槛。传统PHP环境搭建需要手动配置Apache/Nginx、PHP解释器、MySQL等多重组件&#xff0c;光是处理版本兼容性和依赖问题就可能耗费半天时间——这…

建造者模式深度解析与实战应用

作者简介 我是摘星&#xff0c;一名全栈开发者&#xff0c;专注 Java后端开发、AI工程化 与 云计算架构 领域&#xff0c;擅长Python技术栈。热衷于探索前沿技术&#xff0c;包括大模型应用、云原生解决方案及自动化工具开发。日常深耕技术实践&#xff0c;乐于分享实战经验与…

代码中文抽取工具并替换工具(以ts为例)

文章目录 基本思路目录结构配置文件AST解析替换代码中文生成Excel启动脚本 基本思路 通过对应语言的AST解析出中文相关信息&#xff08;文件、所在行列等&#xff09;存到临时文件通过相关信息&#xff0c;逐个文件位置替换掉中文基于临时文件&#xff0c;通过py脚本生成Excel…

pgsql batch insert optimization (reWriteBatchedInserts )

reWriteBatchedInserts 是 PostgreSQL JDBC 驱动 提供的一个优化选项&#xff0c;它可以 重写批量插入语句&#xff0c;从而提高插入性能。 作用 当 reWriteBatchedInsertstrue 时&#xff0c;PostgreSQL JDBC 驱动会将 多个单独的 INSERT 语句 转换为 一个多行 INSERT 语句&a…

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(上)

概述 在 Swift 开发语言中&#xff0c;各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过&#xff0c;在涉及到多个子类派生于基类进行多态模拟的场景下&#xff0c;…

华为云Flexus+DeepSeek征文 | 基于DeepSeek-V3构建企业知识库问答机器人实战

作者简介 我是摘星&#xff0c;一名专注于云计算和AI技术的开发者。本次通过华为云MaaS平台体验DeepSeek系列模型&#xff0c;将实际使用经验分享给大家&#xff0c;希望能帮助开发者快速掌握华为云AI服务的核心能力。 目录 作者简介 1. 引言 2. 技术选型与架构设计 2.1 技…

【Docker 01】Docker 简介

&#x1f308; 一、虚拟化、容器化 ⭐ 1. 什么是虚拟化、容器化 物理机&#xff1a;真实存在的服务器 / 计算机&#xff0c;对于虚拟机来说&#xff0c;物理机为虚拟机提供了硬件环境。虚拟化&#xff1a;通过虚拟化技术将一台计算机虚拟为 1 ~ n 台逻辑计算机。在一台计算机…

AUTOSAR实战教程--DoIP_02_诊断链路建立流程

第一步&#xff1a;DoIP实体车辆声明/诊断仪车辆识别请求 打开激活线以后&#xff0c;DoIP实体发的三帧车辆声明报文。其中包含了DoIP实体的诊断逻辑地址&#xff08;可以类比DoCAN的物理请求/响应地址&#xff09;&#xff0c;对应车辆的VIN码&#xff08;若已配置&#xff0…

音频剪辑软件少之又少好用

我们平时见到的图片以及视频编辑工具非常多&#xff0c;但是音频剪辑软件却是少之又少&#xff0c;更不用说有没有好用的&#xff0c;今天&#xff0c;给大家带来一款非常专业的音频剪辑软件&#xff0c;而且是会员喔。 软件简介 一款手机号登录即可以享受会员的超专业音频剪…

客户端和服务器已成功建立 TCP 连接【输出解析】

文章目录 图片**1. 连接状态解析****第一条记录&#xff08;服务器监听&#xff09;****第二条记录&#xff08;客户端 → 服务器&#xff09;****第三条记录&#xff08;服务器 → 客户端&#xff09;** **2. 关键概念澄清****(1) 0.0.0.0 的含义****(2) 端口号的分配规则** *…

day26-计算机网络-4

1. tcp的11种状态 ss -ant -a 表示看所有状态 -n 表示不将ip解析为主机名 -t 表示tcp 1.1. closed状态&#xff08;客户端、服务端&#xff09; 客户端发起建立连接前的状态服务端启动服务前的状态 1.2. listen状态&#xff08;服务端&#xff09; 服务端软件运行的时候状…

国防科技大学计算机基础慕课课堂学习笔记

1.信息论 香农作为信息论的这个创始人&#xff0c;给出来了这个信息熵的计算方法&#xff0c;为我们现在的这个生活的很多领域奠定了基础&#xff0c;我第一次听说这个信息熵是在这个数学建模里面的理论学习中有关于这个&#xff1a;决策树的模型&#xff0c;在那个问题里面&a…

【第七篇】 SpringBoot项目的热部署

简介 本文介绍了热部署&#xff08;Hot Deployment&#xff09;的概念、使用场景及在IDEA中的配置方法。热部署可在不重启应用的情况下动态更新代码&#xff0c;提升开发效率&#xff0c;适用于调试、微服务架构和自动化测试等场景。文章详细说明了热部署的实现步骤&#xff08…

解决pycharm同一个文件夹下from *** import***仍显示No module named

1、&#xff0c;from ***import *&#xff0c;同文件夹中已有.py文件但是仍然报错No module named 原因是因为pycharm没有把文件夹设置为根目录&#xff0c;只需要在文件夹的上一级设置为根目录即可&#xff0c;测试过如果仅仅将当前的文件夹设置仍然报错&#xff0c;如果把最上…