从0开始的STM32之旅 7 串口通信(I)

现在,我们终于可以做一些有趣的事情了:那就是来一点串口通信了。串口通信在一定程度上可以辅助我们程序的调试,传递信息,以及做其他令人激动的事情。下面我们就来看看如何开始我们的串口通信之旅。

关于数据通信

通信就是在传递信息,看中的是两或者是多台设备之间的信息交互和链接,是必不可少的一部分,比如:单片机和上位机、单片机和外围器件之间,它们都有数据通信的需求。由于设备之间的电气特性、传输速率、可靠性要求各不相同,于是就有了各种通信类型、通信协议,我们最常的有:USART、IIC、SPI、CAN、USB等。在这里我们说的串口通信更多的指代的是USART的通信。

串行与并行

串行通信的基本特征是数据逐位顺序依次传输,优点是传输线少、布线成本低、灵活度高等优点,一般用于近距离人机交互,特殊处理后也可以用于远距离,缺点就是传输速率低。 而并行通信是数据各位可以通过多条线同时传输,优点是传输速率高,缺点就是布线成本高,抗干扰能力差因而适用于短距离、高速率的通信

这一张图就可以说明白两种通信方式的差异了。

传播方向

分为三种:

  • 单工是指数据传输仅能沿一个方向,不能实现反方向传输,如校园广播。

  • 半双工是指数据传输可以沿着两个方向,但是需要分时进行,如对讲机。

  • 全双工是指数据可以同时进行双向传输,日常的打电话属于这种情形。

同步的方式

通信需要协调传输的数据,如果不协调,就会出现错包乱包的情况。所以有这样一些办法

  1. 要么,我们拉起一根时钟线,在时钟的督促下准时发送准时读取(同步于时钟)

  2. 要么,我们在数据中动手,加入一定的校验 + 协调信息,解耦合我们的传送(异步)

同步通信要求通信双方共用同一时钟信号,在总线上保持统一的时序和周期完成信息传输。

  • 优点:可以实现高速率、大容量的数据传输,以及点对多点传输。

  • 缺点:要求发送时钟和接收时钟保持严格同步,收发双方时钟允许的误差较小,同时硬件复杂。

异步通信不需要时钟信号,而是在数据信号中加入开始位和停止位等一些同步信号,以便使接收端能够正确地将每一个字符接收下来,某些通信中还需要双方约定传输速率。

  • 优点:没有时钟信号硬件简单,双方时钟可允许一定误差。

  • 缺点:通信速率较低,只适用点对点传输。

通信速率

在数字通信系统中,通信速率(传输速率)指数据在信道中传输的速度,它分为两种:传 信率和传码率。

传信率:每秒钟传输的信息量,即每秒钟传输的二进制位数,单位为 bit/s(即比特每秒), 因而又称为比特率。

传码率:每秒钟传输的码元个数,单位为 Baud(即波特每秒),因而又称为波特率。 比特率和波特率这两个概念又常常被人们混淆。

比特率很好理解,我们来看看波特率,波特率被传输的是码元,码元是信号被调制后的概念,每个码元都可以表示一定 bit 的数据信息量。

举个例子,在 TTL 电平标准的通信中,用 0V 表示逻辑 0,5V 表示逻辑1,这时候这个码元就可以表示两种状态。如果电平信号 0V、2V、4V 和6V 分别表示二进制数 00、01、10、11,这时候每一个码元就可以表示四种状态。

由上述可以看出,码元携带一定的比特信息,所以比特率和波特率也是有一定的关系的。 比特率和波特率的关系可以用以下式子表示:比特率 = 波特率 * log_2M其中 M 表示码元承载的信息量。我们也可以理解M 为码元的进制数。

举个例子:波特率为100 Baud,即每秒传输 100 个码元,如果码元采用十六进制编码(即M=2,代入上述式子),那么这时候的比特率就是 400 bit/s。如果码元采用二进制编码(即M=2,代入上述式子),那么这时候的比特率就是 100 bit/s。

可以看出采用二进制的时候,波特率和比特率数值上相等。但是这里要注意,它们的相等只是数值相等,其意义上不同,看波特率和波特率单位就知道。由于我们的所用的数字系统都是二进制的,所以有部分人久而久之就直接把波特率和比特率混淆了。

串口通信协议简介

串口通信是一种设备间常用的串行通信方式,串口按位(bit)发送和接收字节。尽管比特字节(byte)的串行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线接收数据。 ​ 串口通信协议是指规定了数据包的内容,内容包含了起始位、主体数据、校验位及停止位,双方需要约定一致的数据包格式才能正常收发数据的有关规范。

串口通信的数据包由发送设备的 TXD 接口传输到接收设备的 RXD 接口。在串口通信的协议层中,规定了数据包的内容,它由起始位、主体数据、校验位以及停止位组成,通讯双方的数据包格式要约定一致才能正常收发数据,串口通信协议数据包组成可以分为波特率和数据帧格式两部分。

本章主要讲解的是串口异步通信,异步通信是不需要时钟信号的,但是这里需要我们约定好两个设备的波特率。波特率表示每秒钟传送的码元符号的个数,所以它决定了数据帧里面每一个位的时间长度。两个要通信的设备的波特率一定要设置相同,我们常见的波特率是 4800、9600、115200 等。

串口通信的数据帧格式

数据帧格式需要我们提前约定好,串口通信的数据帧包括起始位、停止位、有效数据位以及校验位。 起始位和停止位串口通信的一个数据帧是从起始位开始,直到停止位。数据帧中的起始位是由一个逻辑 0 的数据位表示,而数据帧的停止位可以是 0.5、1、1.5 或 2 个逻辑 1 的数据位表示,只要双方约定一致即可。

  • 有效数据位 :数据帧的起始位之后,就接着是数据位,也称有效数据位,这就是我们真正需要的数据。有效数据位通常会被约定为 5、6、7 或者 8 个位长。有效数据位是低位(LSB)在前,高位(MSB)在后。

  • 校验位:校验位可以认为是一个特殊的数据位。校验位一般用来判断接收的数据位有无错误,检验方法有:奇检验、偶检验、0 检验、1 检验以及无检验。下面分别介绍一下:

  • 奇校验是指有效数据为和校验位中“1”的个数为奇数,比如一个 8 位长的有效数据为:10101001,总共有 4 个“1”,为达到奇校验效果,校验位设置为“1”,最后传输的数据是 8 位的有效数据加上 1 位的校验位总共 9 位。

  • 偶校验与奇校验要求刚好相反,要求帧数据和校验位中“1”的个数为偶数,比如数据帧:11001010,此时数据帧“1”的个数为 4 个,所以偶校验位为“0”。

  • 0 校验是指不管有效数据中的内容是什么,校验位总为“0”,1 校验是校验位总为“1”。

  • 无校验是指数据帧中不包含校验位。我们一般是使用无检验的情况。

STM32的USART和UART

STM32F103ZET6 最多可提供 5 路串口,有分数波特率发生器、支持同步单线通信和半双工单线通讯、支持 LIN、支持调制解调器操作、智能卡协议和IrDA SIR ENDEC 规范、具有DMA 等。 ​ STM32F1 的串口分为两种:USART(即通用同步异步收发器)和UART(即通用异步收发器)。UART 是在 USART 基础上裁剪掉了同步通信功能,只剩下异步通信功能。简单区分同步和异步就是看通信时需不需要对外提供时钟输出,我们平时用串口通信基本都是异步通信。 STM32F1 有3 个USART 和2 个UART,其中USART1 的时钟源来于 APB2 时钟,其最大频率为 72MHz,其他 4 个串口的时钟源可以来于APB1 时钟,其最大频率为36MHz。 STM32 的串口输出的是 TTL 电平信号

分析STM32CubeMX对串口启动的基本流程:

static void MX_USART1_UART_Init(void)
{
​/* USER CODE BEGIN USART1_Init 0 */
​/* USER CODE END USART1_Init 0 */
​/* USER CODE BEGIN USART1_Init 1 */
​/* USER CODE END USART1_Init 1 */// 这里是设置USART1实体的初始化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();}/* USER CODE BEGIN USART1_Init 2 */
​/* USER CODE END USART1_Init 2 */
}
HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)
{/* Check the UART handle allocation */if (huart == NULL){return HAL_ERROR;}
​/* Check the parameters */if (huart->Init.HwFlowCtl != UART_HWCONTROL_NONE){/* The hardware flow control is available only for USART1, USART2 and USART3 */assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance));assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl));}else{assert_param(IS_UART_INSTANCE(huart->Instance));}assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
#if defined(USART_CR1_OVER8)assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
#endif /* USART_CR1_OVER8 */
​if (huart->gState == HAL_UART_STATE_RESET){/* Allocate lock resource and initialize it */huart->Lock = HAL_UNLOCKED;
​
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)UART_InitCallbacksToDefault(huart);
​if (huart->MspInitCallback == NULL){huart->MspInitCallback = HAL_UART_MspInit;}
​/* Init the low level hardware */huart->MspInitCallback(huart);
#else/* Init the low level hardware : GPIO, CLOCK */HAL_UART_MspInit(huart);
#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */}
​huart->gState = HAL_UART_STATE_BUSY;
​/* Disable the peripheral */__HAL_UART_DISABLE(huart);
​/* Set the UART Communication parameters */UART_SetConfig(huart);
​/* In asynchronous mode, the following bits must be kept cleared:- LINEN and CLKEN bits in the USART_CR2 register,- SCEN, HDSEL and IREN  bits in the USART_CR3 register.*/CLEAR_BIT(huart->Instance->CR2, (USART_CR2_LINEN | USART_CR2_CLKEN));CLEAR_BIT(huart->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
​/* Enable the peripheral */__HAL_UART_ENABLE(huart);
​/* Initialize the UART state */huart->ErrorCode = HAL_UART_ERROR_NONE;huart->gState = HAL_UART_STATE_READY;huart->RxState = HAL_UART_STATE_READY;
​return HAL_OK;
}

这个函数无非就是在做这些事情:

参数检查:检查传入的 huart 是否为 NULL,若是,则返回 HAL_ERROR

参数验证

  • 如果启用了硬件流控制,则确保所使用的 UART 实例支持该功能,并验证流控制类型的合法性。

  • 对其他 UART 参数(如字长、过采样等)进行验证,确保它们符合预定义的条件。

状态初始化

  • 如果 huart 的状态为重置,初始化锁资源。

  • 根据是否使用回调函数,调用相应的初始化函数,通常是 HAL_UART_MspInit,以进行底层硬件的初始化(如 GPIO 和时钟设置)。

状态设置:将 huart 的状态设为忙碌。

禁用外设:调用宏 __HAL_UART_DISABLE 禁用 UART 外设。

设置通信参数:调用 UART_SetConfig 函数配置 UART 通信参数。

清除不必要的位:在异步模式下,清除 USART_CR2 和 USART_CR3 中的特定位,以确保 UART 正常工作。

启用外设:调用宏 __HAL_UART_ENABLE 启用 UART 外设。

最终状态设置:将错误代码和状态设置为初始值,标志 UART 处于准备就绪状态。

HAL_UART_Transmit和HAL_UART_Receive

HAL_UART_Receive 是 STM32 HAL 库中的一个函数,用于从 UART 接口接收数据。它通常用于单向通信场景,接收来自外部设备的数据。

函数的基本原型如下:

HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);

参数说明:

  • huart: 指向 UART 句柄的指针。

  • pData: 用于存储接收到的数据的缓冲区指针。

  • Size: 要接收的数据大小(字节数)。

  • Timeout: 操作的超时时间,单位是毫秒。

HAL_UART_Receive 是 STM32 HAL 库中的一个函数,用于从 UART 接口接收数据。它通常用于单向通信场景,接收来自外部设备的数据。

函数的基本原型如下:

c复制代码HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);

参数说明:

  • huart: 指向 UART 句柄的指针。

  • pData: 用于存储接收到的数据的缓冲区指针。

  • Size: 要接收的数据大小(字节数)。

  • Timeout: 操作的超时时间,单位是毫秒。

目前我们使用的是这两个函数完成接受和收发数据的。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

医院绩效考核管理系统源码,医院如何构建绩效考核体系?

医院绩效考核管理系统作为现代医院管理的重要组成部分,其核心功能旨在提高医院运营效率、优化资源配置、确保医疗服务质量,以及增强医院竞争力。 业务科室绩效考核体系的构建 临床医疗与医技科室绩效考核的设置 临床医疗的绩效考核采用百分制&#xff…

使用DexClassLoader类动态加载插件dex

DexClassLoader类的源码 package dalvik.system;public class DexClassLoader extends BaseDexClassLoader {public DexClassLoader(String dexPath, String optimizedDirectory,String librarySearchPath, ClassLoader parent) {super(dexPath, null, librarySearchPath, par…

国产服务器部署1.获取银河麒麟V10服务器。首先挂gpt数据盘

要做系统国产化,现记录国产化的全过程:银河麒麟V10采用ARM架构,基于Ubuntu 18.04 LTS版本的Linux操作系统。‌‌ #uname -r 看系统是x86还是arm 1.获取银河麒麟V10服务器。首先挂数据盘。 1)#lsblk -f vdb为数据盘。需要格式…

Excel:vba实现插入图片

实现的效果: 实现的代码: Sub InsertImageNamesAndPictures()Dim PicPath As StringDim PicName As StringDim PicFullPath As StringDim RowNum As IntegerDim Pic As ObjectDim Name As String 防止表格里面有脏数据Cells.Clear 遍历工作表中的每个图…

性能测试需求分析详解

🍅 点击文末小卡片 ,免费获取软件测试全套资料,资料在手,涨薪更快 1、客户方提出 客户方能提出明确的性能需求,说明对方很重视性能测试,这样的企业一般是金融、电信、银行、医疗器械等;他们一…

机器学习之fetch_olivetti_faces人脸识别--基于Python实现

fetch_olivetti_faces 数据集下载 fetch_olivetti_faceshttps://github.com/jikechao/olivettifaces sklearn.datasets.fetch_olivetti_faces(*, data_homeNone, shuffleFalse, random_state0, download_if_missingTrue, return_X_yFalse, n_retries3, delay1.0)[source] L…

智能离线语音识别不灵敏?如何改善和提升识别率?

前言 有用户反馈离线语音识别不灵敏,跟着笔者一起分析原因吧。笔者知识能力有限,难免会误,还请大家批评指正。 1 影响离线语音识别的因素 笔者分析离线语音识别不灵敏的原因有以下几点 1.1 运行硬件的算力限制 由于离线语音识别在本地MCU…

人工智能在干部选拔任用中的应用研究

干部选拔任用是关系到党和国家事业发展的重要环节。在当今科技飞速发展的时代,人工智能技术的出现为干部选拔任用提供了新的思路和方法。人工智能以其强大的数据处理能力、精准的分析预测能力和高效的决策支持能力,有望在干部选拔任用中发挥重要作用。 …

Grandle 报错_项目无法编译问题解决

文章目录 AndroidStudio 编译遇到的问题Gradle 报错-无法编译需要解决的问题说明AS 与 AGP 版本对应不同平台AS版本及下载地址gradle 无法下载 和 找不到使用腾讯镜像gradle-wrapper.properties 文件找不到 依赖库无法下载,下载速度慢更换阿里镜像仓库阿里仓库镜像下…

C++ 实现俄罗斯方块游戏

✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…

JS进阶级案例-----时钟

首先呢&#xff0c;是由四张图片构成&#xff0c;使用css摆放好&#xff0c;再使用JS给三个指针绑定获取时间和要旋转的角度&#xff0c;在获取对应的指针元素&#xff0c;给到定时器&#xff0c;实现时钟动态更新。 <!DOCTYPE html> <html lang"en"> &…

【前端基础】HTML 基础

目标&#xff1a;掌握标签基本语法&#xff0c;能够独立布局文章页。 核心技术点 网页组成 排版标签 多媒体标签及属性 综合案例一 - 个人简介 综合案例二 - Vue 简介 02-标签语法 HTML 超文本标记语言——HyperText Markup Language。 超文本&#xff1a;链接标记&a…

UE5相机系统初探(一)

UE5相机系统初探&#xff08;一&#xff09; 和Unity类似&#xff0c;UE的相机也是由名为Camera的component控制的。那么&#xff0c;在UE中要如何实现一个跟随玩家的第三人称相机呢&#xff1f;假设我们已经有了一个表示玩家的类ACF_Character&#xff0c;首先第一步就是要先在…

数据库->联合查询

目录 一、联合查询 1.联合查询 2.多表联合查询时MYSQL内部是如何进⾏计算的 3.多表联合查询 3.1语法 3.2指定多个表&#xff0c;进行联合查询 3.3通过表与表中的链接条件过滤掉无效数据 3.4通过指定列查询&#xff0c;精简查询结果​编辑 3.5可以通过给表起别名的方式&…

有关《WebGIS开发 从入门到实践》的分享

从30号发布了新书的上架消息之后&#xff0c;已有不少的朋友、学生下单购买了&#xff0c;有部分已经收到了书了&#xff0c;收到书大致翻阅后也第一时间向我进行了反馈。本文结合我在写本书时的思考和收到的大家反馈&#xff0c;给大家介绍一下我们花了三年写完出的《WebGIS开…

YOLO——yolo v4(2)

文章目录 一、损失函数改进1.GIOU损失2.DIOU损失3.CIOU损失 二、非极大值抑制 YOLOv4是一种先进的目标检测算法&#xff0c;它在YOLO系列的基础上进行了多项改进和优化。 一、损失函数改进 IOU损失表示预测框A和真实框B之间交并比的差值&#xff0c;反映预测检测框的检测效果。…

网络请求优化:理论与实践

文章目录 引言1. DNS 解析耗时因素优化措施扩展阅读 2. 创建连接耗时因素优化措施扩展阅读 3. 发送 / 接收数据耗时因素优化措施扩展阅读 4. 关闭连接耗时因素优化措施扩展阅读 总结 引言 网络请求的性能会直接影响到用户体验。本文将探讨网络请求的各个步骤&#xff0c;以及如…

R语言结构方程模型(SEM)

原文链接&#xff1a;R语言结构方程模型&#xff08;SEM&#xff09;https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247624956&idx4&sn295580a016a86cfee8ee2277c93e32d5&chksmfa8da91bcdfa200da897f1f267492039865bdfe5d75a1c6e6df92ff5005e0eb5cc33a…

android数组控件Textview

说明&#xff1a;android循环控件&#xff0c;注册和显示内容 效果图&#xff1a; step1: E:\projectgood\resget\demozz\IosDialogDemo-main\app\src\main\java\com\example\iosdialogdemo\TimerActivity.java package com.example.iosdialogdemo;import android.os.Bundl…

GA/T1400视图库平台EasyCVR视频分析设备平台微信H5小程序:智能视频监控的新篇章

GA/T1400视图库平台EasyCVR是一款综合性的视频管理工具&#xff0c;它兼容Windows、Linux&#xff08;包括CentOS和Ubuntu&#xff09;以及国产操作系统。这个平台不仅能够接入多种协议&#xff0c;还能将不同格式的视频数据统一转换为标准化的视频流&#xff0c;通过无需插件的…