12 通用同步异步收发器(USART)

news2025/1/13 6:19:29

目录

通用同步异步收发器(USART)

理论部分

USART概览

STM32和PC通信模型

STM32和PC通过RS-232标准通信

RS-232标准介绍

RS-232协议电平标准对比

RS-232标准的物理接口规定及接口标号

RS-232标准下接口标号的作用

RS-232标准数据传输协议层

协议概念

数据校验

外设框图

实验部分

CubeMX配置过程

CubeMX生成串口如何使用

手动编写(BSP板级支持包)


通用同步异步收发器(USART)

相关内容参考:

CubeMX生成串口如何使用:cubemx快速使用串口_cubemx 串口_弦续北上i的博客-CSDN博客

串口重映射:STM32——USART1重映射_usart重映射_Jack_Cheng_2021的博客-CSDN博客

理论部分

USART概览

  • 通用异步收发传输器,英文全称Universal Asynchronous Receiver/Transmitter,简称UART。
    • STM32上的USART外设可以实现同步传输功能,所以外设名为USART,比UART多了一个S,即synchronous(同步)。
  • UART器件主要用来产生相关接口的协议信号,如RS232\RS485等串行接口标准规范和总线标准规范,要使用传输数据这些接口,就要按照接口规定的协议信号发送数据。所以UART器件广泛应用于串口通信中,扮演者传输器的角色。

STM32和PC通信模型

STM32和PC通过RS-232标准通信

RS-232标准介绍

  • RS-232是美国电子工业联盟(EIA)制定的串行数据通信的接口标准,原始编号全称是EIA-RS-232(简称232,RS232)。它被广泛用于计算机串行接口外设连接。
  • RS-232 标准规定了连接电缆和机械、电气特性、信号功能及发送过程。

RS-232协议电平标准对比

一般开发板上使用的电平标准与通讯使用的电平标准不同,如TTL 标准及 RS-232 标准。

因为控制器一般使用 TTL 电平标准,所以常常会使用 MA3232 芯片对 TTL 及 RS-232电平的信号进行互相转换。

RS-232标准的物理接口规定及接口标号

现在一般不使用RS232串口而使用USB转串口

RS-232标准下接口标号的作用

一般只使用RXD、TXD和GND即可完成串口通信。

RS-232标准数据传输协议层

串口通讯的数据包由发送设备通过自身的 TXD 接口传输到接收设备的 RXD 接口。在串口通讯的协议层中,规定了数据包的内容,它由起始位、主体数据、校验位以及停止位组成,通讯双方的数据包格式要约定一致才能正常收发数据,其组成见图。

协议概念

  • 波特率

        本章中主要讲解的是串口异步通讯,异步通讯中由于没有时钟信号(如前面讲解的 DB9接口中是没有时钟信号的),所以两个通讯设备之间需要约定好波特率,即每个码元的长度,以便对信号进行解码, 图中用虚线分开的每一格就是代表一个码元。常见的波特率为4800、 9600、 115200 等。

  • 通讯的起始和停止信号

        串口通讯的一个数据包从起始信号开始,直到停止信号结束。数据包的起始信号由一个逻辑 0 的数据位表示,而数据包的停止信号可由 0.5、 1、 1.5 或 2 个逻辑 1 的数据位表示,只要双方约定一致即可。

  • 有效数据

        在数据包的起始位之后紧接着的就是要传输的主体数据内容,也称为有效数据,有效数据的长度常被约定为 5、 6、 7 或 8 位长。

  • 数据校验

        在有效数据之后,有一个可选的数据校验位。由于数据通信相对更容易受到外部干扰导致传输数据出现偏差,可以在传输过程加上校验位来解决这个问题。校验方法有奇校验(odd)、偶校验(even)、 0 校验(space)、 1 校验(mark)以及无校验(noparity)

数据校验

外设框图

F1\F4\F7-USART外设

其中TX和RX使用GPIO引脚作为输入输出,涉及到GPIO引脚的复用功能

H7-USART外设

实验部分

CubeMX配置过程

在CDE数据手册(STM32产品手册)中,可以查找所有GPIO引脚的功能

以配置串口1为例

(1)选择异步传输模式Asynchronous

(2)配置串口的工作模式参数

(3)对于USART1,可以有多组引脚选择(参照GPIO功能表),默认为PA9和PA10,如果选择PB6,会自动变为PB6和PB7。注意:在实际使用中,每个串口只能使用一组GPIO

(4)勾选NVIC中断,关于DMA下一讲介绍,这里暂时不用

(5)工程代码:

如图所示:

HAL_UART_Init调用了HAL_UART_MspInit函数

补充:

以HAL_UART_MspInit为例,HAL_UART_MspInit为弱定义函数,可以用户自己实现功能

补充:

MSP是指和MCU相关的初始化,举个例子就可以理解:

比如串口的初始化

1、我们要初始化和MCU无关的东西:例如串口协议,其中包括波特率,奇偶校验,停止位等等,这些设置和使用什么样的MCU没有任何关系,可以使用F1的MCU,也可以是F2...F4,甚至是PC上的串口。所以就把串口抽像成为一个“串口”。

2、有了抽像的串口,这个“串口”就要在MCU上进行承载,用STM32F4进行承载,PA9做为发送,PA10做为接收.MSP就是要初始化PA9,PA10。配置这两个引解

所以HAL驱动方式的初始化流程就是:HAL_USART_Init() ------>HAL_USART_MSP_Init()  先初始化协议,再初始化MCU的引角。在STM32的HAL驱动中MSP_Init()是做为回调,包含在PPP_Init()中的。

CubeMX生成串口如何使用

以USART1回显为例

(1)添加使能串口中断

(2)由于我们用CubeMX生成的串口引脚是PB6、PB7,而实际使用的是PA9和PA10,所以将重映射部分注释掉,否则会影响串口使用

(3)添加自定义发送字符串函数和重定义C库函数

(4)在终端函数中的回调函数后加上自定义功能

(5)在main函数中打印一句话

(6)上位机测试

以上是CubeMX串口生成已经使用过程。

手动编写(BSP板级支持包)

步骤如下:

一、 定义一个UART_HandleTypeDef结构体句柄

二、 通过HAL_UART_MspInit函数来实现串口外设的底层初始化:

要做什么功能:

1、 使能UART外设时钟

2、 配置UART使用的引脚模式

3、 如果要用中断,就配置中断

4、 如果要用DMA,就配置DMA

三、 通过前面定义的结构体,来配置串口的波特率、数据字长、停止位、奇偶校验位、硬件流控制。

四、 通过调用HAL_UART_Init函数,来将串口配置为异步模式。

同样以USART1回显为例

头文件
#ifndef __DEBUG_USART_H
#define    __DEBUG_USART_H

#include "stm32f1xx.h"
#include <stdio.h>

//串口波特率
#define DEBUG_USART_BAUDRATE                    115200

//引脚定义
/*******************************************************/
#define DEBUG_USART                             USART1
#define DEBUG_USART_CLK_ENABLE()                __HAL_RCC_USART1_CLK_ENABLE();

#define DEBUG_USART_RX_GPIO_PORT                GPIOA
#define DEBUG_USART_RX_GPIO_CLK_ENABLE()        __HAL_RCC_GPIOA_CLK_ENABLE()
#define DEBUG_USART_RX_PIN                      GPIO_PIN_10

#define DEBUG_USART_TX_GPIO_PORT                GPIOA
#define DEBUG_USART_TX_GPIO_CLK_ENABLE()       __HAL_RCC_GPIOA_CLK_ENABLE()
#define DEBUG_USART_TX_PIN                      GPIO_PIN_9

#define DEBUG_USART_IRQHandler                  USART1_IRQHandler
#define DEBUG_USART_IRQ                             USART1_IRQn
/************************************************************/

void Usart_SendString(uint8_t *str);
void DEBUG_USART_Config(void);
int fputc(int ch, FILE *f);
int fgetc(FILE *f);
extern UART_HandleTypeDef UartHandle;
#endif /* __USART1_H */


源文件
#include "./usart/bsp_debug_usart.h"

UART_HandleTypeDef UartHandle;
//extern uint8_t ucTemp;  

 /**
  * @brief  DEBUG_USART GPIO 配置,工作模式配置。115200 8-N-1
  * @param  无
  * @retval 无
  */  
void DEBUG_USART_Config(void)
{ 
  
  UartHandle.Instance          = DEBUG_USART;
  
  UartHandle.Init.BaudRate     = DEBUG_USART_BAUDRATE;
  UartHandle.Init.WordLength   = UART_WORDLENGTH_8B;
  UartHandle.Init.StopBits     = UART_STOPBITS_1;
  UartHandle.Init.Parity       = UART_PARITY_NONE;
  UartHandle.Init.HwFlowCtl    = UART_HWCONTROL_NONE;
  UartHandle.Init.Mode         = UART_MODE_TX_RX;
  
  HAL_UART_Init(&UartHandle);
   
 /*使能串口接收断 */
  __HAL_UART_ENABLE_IT(&UartHandle,UART_IT_RXNE);  
}


/**
  * @brief UART MSP 初始化 
  * @param huart: UART handle
  * @retval 无
  */
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{  
  GPIO_InitTypeDef  GPIO_InitStruct;
  
  DEBUG_USART_CLK_ENABLE();
    
    DEBUG_USART_RX_GPIO_CLK_ENABLE();
  DEBUG_USART_TX_GPIO_CLK_ENABLE();
  
/**USART1 GPIO Configuration    
  PA9     ------> USART1_TX
  PA10    ------> USART1_RX 
  */
  /* 配置Tx引脚为复用功能  */
  GPIO_InitStruct.Pin = DEBUG_USART_TX_PIN;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed =  GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStruct);
  
  /* 配置Rx引脚为复用功能 */
  GPIO_InitStruct.Pin = DEBUG_USART_RX_PIN;
  GPIO_InitStruct.Mode=GPIO_MODE_AF_INPUT;    //模式要设置为复用输入模式!    
  HAL_GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStruct); 
 
  HAL_NVIC_SetPriority(DEBUG_USART_IRQ ,0,1);    //抢占优先级0,子优先级1
  HAL_NVIC_EnableIRQ(DEBUG_USART_IRQ );            //使能USART1中断通道  
}


/*****************  发送字符串 **********************/
void Usart_SendString(uint8_t *str)
{
    unsigned int k=0;
  do 
  {
      HAL_UART_Transmit(&UartHandle,(uint8_t *)(str + k) ,1,1000);
      k++;
  } while(*(str + k)!='\0');
  
}
//重定向c库函数printf到串口DEBUG_USART,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{
    /* 发送一个字节数据到串口DEBUG_USART */
    HAL_UART_Transmit(&UartHandle, (uint8_t *)&ch, 1, 1000);    
    
    return (ch);
}

//重定向c库函数scanf到串口DEBUG_USART,重写向后可使用scanf、getchar等函数
int fgetc(FILE *f)
{        
    int ch;
    HAL_UART_Receive(&UartHandle, (uint8_t *)&ch, 1, 1000);    
    return (ch);
}

/*********************************************END OF FILE**********************/


中断:
void  DEBUG_USART_IRQHandler(void)
{
  uint8_t ch=0; 
  
    if(__HAL_UART_GET_FLAG( &UartHandle, UART_FLAG_RXNE ) != RESET)
    {        
    ch=( uint16_t)READ_REG(UartHandle.Instance->DR);
    WRITE_REG(UartHandle.Instance->DR,ch); 
 
    }
}

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

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

相关文章

探索数字化前沿:数字化产品引领科技创新风潮

随着数字化时代的到来&#xff0c;国内数字化产品市场蓬勃发展&#xff0c;涌现出许多引领行业变革的产品。本文将介绍几个在数字孪生和人工智能领域取得突破的国内产品&#xff0c;带大家了解数字化产品的创新应用和影响力。 山海鲸可视化&#xff1a;山海鲸可视化是一款强大…

Linux 常用命令记录

Linux(Ubuntu) 常用命令的总结 总结工作中用到的ubuntu命令&#xff0c;和添加一些常见的Linux的命令; 1.文件操作&常见命令操作 前置补充&#xff1a;Linux 终端提示符 && 命令语法 Centos[rootoldboy_python ~] ## [用户名主机机器名 路径] 提示符# 用户名 ro…

《计算机系统与网络安全》 第十章 防火墙技术

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…

Three.js快速入门

Three.js快速入门 1、threejs文件包下载和目录简介 下载地址&#xff1a; 网盘链接:https://pan.baidu.com/s/1_Ix8TiOScypNcQe3BIl5vA?pwdrrks 提取码:rrksthreejs文件资源目录介绍 three.js-文件包 └───build——three.js相关库&#xff0c;可以引入你的.html文件中…

Frida遍历启动App所有Activity/Service

说明&#xff1a;仅供学习使用&#xff0c;请勿用于非法用途&#xff0c;若有侵权&#xff0c;请联系博主删除 作者&#xff1a;zhu6201976 一、需求 在一些大型App中&#xff0c;往往注册了大量的Activity和Service&#xff0c;这在App的AndroidManifest.xml文件可以清晰呈现。…

Centos7完整安装

一、前言 由于使用VMware workstation使用典型安装以及默认安装方式进行安装的Centos多存在组件不足的问题&#xff0c;这使得使用上述方式进行安装的系统在一些特定情况下需要安装组件&#xff0c;致使系统不是很便利&#xff0c;本文提供了在VMware workstation下进行完整安装…

Verdi之nTrace/nSchema

目录 3.nTrace介绍 3.1 启动Verdi 3.2查看Verdi中的设计结构 3.3查看Verdi中的验证结构 3.4 查找模块和trace信号 3.5 查找string 3.6 信号drive/load 3.7 快速查看设计有哪些信号 4 nSchema 4.1 如何打开原理图 4.2 如何查找 nShema window中器件的源码 4.3 如何显示原理…

【Java面试题】框架篇——Redis

文章目录 Redis的使用场景Redis支持的数据类型如何在Redis中实现分布式锁Redis和Mysql的事务有什么区别&#xff1f;Redis缓存穿透如何解决&#xff1f;Redis缓存雪崩如何解决&#xff1f;什么是缓存击穿&#xff0c;如何解决&#xff1f;Redis是单线程模式的&#xff0c;为什么…

chatgpt赋能python:Python超大数计算

Python超大数计算 介绍 在日常编程中&#xff0c;我们常常需要处理大量数据。这些数据可以是普通的整数或浮点数&#xff0c;但有时候我们需要计算的数据可能会超出计算机处理的数值范围。这时&#xff0c;我们需要使用更为高级的算法来进行超大数计算。 Python语言因为其简…

【Java】 Java 中处理 null 或缺失数据

本文仅供学习参考&#xff01; 相关教程地址&#xff1a; https://juejin.cn/post/7234924083842154556 https://cloud.tencent.com/developer/article/1107739?areaSource106005.3 https://www.developer.com/java/null-data-java/ 将某些内容表示为空白或不存在始终是编程中…

TX Text Control 31 sp3 for ActiveX-VB6-Crack

Visual Basic 6 应用程序的文档处理 适用于 Visual Basic 6 和基于 COM 的语言的综合文字处理和报告 视窗用户界面 功能齐全的文档编辑器 TX Text Control 是一款免版税、完全可编程的丰富编辑控件&#xff0c;它在专为 Visual Studio 设计的可重用组件中为开发人员提供了广泛的…

数字空间【高校版】上线

WRITE-BUG团队一直在致力于推动科技创新与科研学习数字化建设&#xff0c;为学生的学习、老师的工作&#xff0c;插上数字化的翅膀。 目前&#xff0c;我们注意到高校在大力推进数字化建设&#xff0c;在内容管理上遇到以下问题亟待解决&#xff1a; 各个科研实验室资料、项目…

【后端面经-Java】Synchronize和ReentrantLock区别

【后端面经-Java】Synchronize和ReentrantLock区别 1. 概念介绍1.1 线程安全锁1.2 公平锁1.3 响应中断/等待可中断 2. 区别2.1 底层实现2.2 锁的用法2.3 锁的特点2.4 性能比较2.5 适用场景 3. 总结比较参考文献 1. 概念介绍 1.1 线程安全锁 Synchronize&#xff08;同步锁&am…

Spring Boot 中的 @PutMapping 注解是什么,原理,如何使用

Spring Boot 中的 PutMapping 注解是什么&#xff0c;原理&#xff0c;如何使用 在 Spring Boot 中&#xff0c;PutMapping 是一种注解&#xff0c;它可以将 HTTP PUT 请求映射到指定的处理方法上。本文将介绍 PutMapping 的原理以及如何在 Spring Boot 中使用它。 PutMapping…

【软考网络管理员】2023年软考网管初级常见知识考点(31)-著作权、商标权、专利权详解

涉及知识点 著作权保护期限&#xff0c;著作权人的确定&#xff0c;侵权如何去判定&#xff0c;商标权是什么&#xff1f;专利权详解&#xff0c;软考网络管理员常考知识点&#xff0c;软考网络管理员网络安全&#xff0c;网络管理员考点汇总。 原创于&#xff1a;CSDN博主-《…

Visual C++中的虚函数和纯虚函数(对比学习法之一)

我是荔园微风&#xff0c;作为一名在IT界整整25年的老兵&#xff0c;今天来说说Visual C中的虚函数和纯虚函数。该系列帖子全部使用我本人自创的对比学习法。也就是当C学不下去的时候&#xff0c;就用JAVA实现同样的代码&#xff0c;然后再用对比的方法把C学会。 直接说虚函数…

初识mysql数据库之表的约束

目录 一、表的约束的概念 二、非空约束&#xff08;空属性&#xff09; 2. 空属性的使用 三、default约束&#xff08;默认值&#xff09; 1. 默认值的含义 2. 默认值的使用 3. 默认值与非空约束的关系 3.1 默认值与非空约束的生效问题 3.2 default自动生成与not null的…

Linux 学习记录40(C++篇)

Linux 学习记录40(C/QT篇) 本文目录 Linux 学习记录40(C/QT篇)一、QT软件的使用1. 新建工程 二、C语言和C的区别1. C对C的扩充2. C对C的兼容 三、第一个C程序1. cout标准输出流对象(1.介绍&#xff1a;(2. 运算符(3. cout的使用 2. cin标准输出流对象(1.介绍&#xff1a;(3. ci…

python【爬虫】【批量下载】年报抓取

python年报爬取更新 本人测试发现&#xff0c;ju chao网的年报爬取距离我上一篇博客并没有啥变化&#xff0c;逻辑没变&#xff0c;应好多朋友的需要&#xff0c;这里补充代码 import json import osimport requestsweb_url 改成网站的域名&#xff0c;因为csdn屏蔽 def load…

深入了解cookie以及实际项目中的应用

目录 cookie的原理 cookie是不可跨域的 cookie 的属性 Cookie与Session的区别 在git中的应用 cookie的原理 什么是cookie呢&#xff1f; 众所周知&#xff1a;http都是无状态的 但随着 Web 的不断发展&#xff0c;这种 无状态 的特性出现了弊端。当你登录到一家购物网站…