标准库发送数据深入理解USART

news/2025/2/6 10:58:01/

如何使用USART(编程理论讲解)

如下是串口发送信息的原理图,CPU将数据写入TDR寄存器,然后串口外设将寄存器中的数据发送出去 这就是串口发送的全部流程  (图中所有图片均来自博主 铁头山羊)

在这个发送流程的过程中,我们涉及一种转换思想叫做串并转换,为什么要进行串并转换呢?很简单,我们的数据写入寄存器的时候是并行写入的,但是我们的寄存器向外发送这个信号的时候却是串行发送的,所以这个过程就涉及串并转换

在这之前我们先补充移位寄存器

移位寄存器顾名思义其作用就是将这个寄存器里面的每一个数据一位一位的移出这个寄存器 同时也满足低位先行

USART基本模型

USART的完整框图

接下来我们讲如何具体配置其相关寄存器

首先是数据帧格式设置(借此我们也来复习一下如何看懂数据手册)

如下这张图中的CR寄存器就是我们控制数据帧的寄存器,我们只需要向这个寄存器相应的位写入1或0就能使能寄存器,或者关闭寄存器。

我们以具体的参考手册为例

在参考手册中我们是可以找到该寄存器的每一位代表了什么,对每一位置0或者置1,我们就能配置相应的模式,就比如CR1寄存器的第13位(虽然写着12 但是我们的寄存器是从0开始的),它控制的就是我们的数据长度,如果我们将此位置为1 那么我们的数据长度就为9,如果我们将此位置位0 那么我们的数据长度就为8

了解了串口的基本组成原理之后,我们现在来实现串口发送的功能

在串口的发送过程中,我们的数据是以双缓存的方式进行存储和发送的分,双缓存顾名思义就是我们要发送的数据会存储到两个不同的寄存器中 由这两个不同的寄存器进行相互作用来发送数据

双缓存的数据发送模式会带来两个问题 1.数据发送过快导致的覆盖问题 2.数据什么时候发送完成的问题

1.就比如我们的第一组数据仍在移位寄存器中未发送完成,我们的第二个数据此时已经存储到TDR寄存器中,但是第三个数据也被搬运到TDR寄存器中 这样就会导致数据二与数据三的数据混淆或者说数据二的数据被数据三给覆盖

2.数据什么时候发送完成的问题,就比如此时我们的第一组数据仍在移位寄存器中还没有彻底发送成功 我们就将TDR寄存器中的数据二写入到移位寄存器中,这样就会导致数据一的发送被混淆

所以为了解决第一个数据覆盖的问题,我们加入了寄存器TXE,当TXE标志位为0时就代表了TDR寄存器中有数据存在,当TDR寄存器为1的时候就代表了TDR寄存器中没有数据存在,所以我们就可以通过读取TXE寄存器的数值来判断TDR寄存器中是否有数据,具体的编程如下用while循环来判断TXE寄存器的数值是否为零,若为零我们会一直在while循环中等待 因为TXE为零就代表了我们的TDR寄存器中此时有数据存在,若不满足TXE==的条件 我们就会跳出while循环 执行接下来的操作 也就是给TDR寄存中写入下一组数据

我们在数据手册中看一下关于TXE的简介 参考手册中的 禁止产生中断就代表了 我们的TDR寄存器中此时仍有数据存在

而为了解决第二个问题 我们引入第二个寄存器 TC寄存器 ,TC寄存器的数值就代表了在移位寄存器中的数据是否成功发送 如果TC标志位为0就代表了我们的移位寄存器中仍有数据未发送成功,若TC标志位为1就代表了我们的移位寄存器中数据已经发送成功 此时我们可以将TDR寄存器中的数据写入移位寄存器(补充一下 TDR寄存器中的数据更新到移位寄存器中的这个过程是硬件自动填充的 不需要我们手动来填充 而之所以要判断移位寄存器中的数据是否发送完成 是为了给我们程序员一个信号 告诉我们数据发送完成 可以开始进行下一步操作)

有了上面对发送的补充,我们现在来看一下单个数据的发送

数据的连续发送

我们的连续发送有如下两种书写方式,我们分别展开来讲

第一种写法如下 我在旁边打了错误符号就代表这种书写方法是错误的,为什么这么说呢 因为第一种书写方式最后表达出来并不是真正的连续发送 而是先发送一个数据保证这个数据彻底发送完成之后我们才会发送第二组数据,可以理解为 第一组数据先写入 TDR寄存器中 然后从TDR寄存器中写入到移位寄存器中 然后等待移位寄存器中这组数据向外发送完成之后我们才会重新向TDR寄存器中写入数据 那么这里就有一个问题 就是我们在等待移位寄存器中的数据发送完成的这个过程中 我们的TDR寄存器中是没有数据的 我们必须要等到移位寄存器中的数据发送完成之后我们才能向TDR寄存器中写入数据,这明显不是连续发送

而第二种书写方式是 我们先将第一组数据写入TDR寄存器中 然后等待第一组数据转移到移位寄存器中,一旦第一组数据从TDR寄存器中转移到移位寄存器中 我们就将第二组数据写入 TDR寄存器中,这样的书写方式满足了连续发送的规律

下面我们来讲如何接收数据

还是跟接收的时候同样的思路 我们先提出问题 然后在去试着解决这些问题

1.问题一 何时读取数据

因为我们的RX引脚是接的发送方的TX引脚 我们不知道 对方何时发送完成 就会导致两种情况的出现

第一种情况就是对方的数据还没发送完成 我们接收方的TDR寄存器只存储了发送发发送的前几个数据 我们就将这个数据直接搬运到接收方的RDR寄存器中 这样就会导致接收的数据有纰漏

第二种情况就是发送方给我们连续发送数据就比如发送方发送的第一组数据刚到我们接收方的移位寄存器中 还没完全写入RDR寄存器中 我们就将第二组数据写入到移位寄存器中

我们引入RXNE标志位来解决这个问题

RXNE寄存器(也可以叫标志位)为1时代表我们的RDR标志位有数据 此时我们可以读取里面的数据,而当RDR为0时代表RDR寄存器无数据 此时我们需要等待 (反映到程序层面就是卡死在while循环中)

接收单个数据

接收多个数据


http://www.ppmy.cn/news/1569776.html

相关文章

如何在 Kafka 中实现自定义分区器

今天我来给大家分享一下如何在 Kafka 中实现一个自定义分区器。Kafka 是一个分布式流处理平台,能够高效地处理海量数据。默认情况下,Kafka 使用键的哈希值来决定消息应该发送到哪个分区,但是有时我们需要根据特定的业务逻辑来定制分区策略。这…

需求分析应该从哪些方面来着手做?

需求分析一般可从以下几个方面着手: 业务需求方面 - 与相关方沟通:与业务部门、客户等进行深入交流,通过访谈、问卷调查、会议讨论等方式,明确他们对项目的期望、目标和整体业务需求,了解项目要解决的业务问题及达成的…

S4 HANA手工记账Tax Payable – FB41

本文主要介绍在S4 HANA OP中手工记账Tax Payable – FB41。具体请参照如下内容: 手工记账Tax Payable – FB41 该事务代码用于手工处理税码统驭科目的记账,一般税码科目需要设置为只能自动记账,因此无法手工对税码统驭科目记账,但…

低代码系统-产品架构案例介绍、蓝凌(十三)

蓝凌低代码系统,依旧是从下到上,从左至右的顺序。 技术平台h/iPaas 指低层使用了哪些技术,例如:微服务架构,MySql数据库。个人认为,如果是市场的主流,就没必要赘述了。 新一代门户 门户设计器&a…

mac安装wireshark

mac启动wireshark时,提示没有权限抓包,报错内容如下: “The capture session could not be initiated on interface ‘en0’ (You don’t have permission to capture on that device). Please check to make sure you have sufficient perm…

celery策略回测任务运行及金融量化数据增量更新|年化18.8%,回撤8%的组合策略(python代码)

原创内容第787篇,专注量化投资、个人成长与财富自由。 昨天我们分享了量化数据的采集与增量更新:更新数据,年化18.8%,回撤8%的组合策略 | akshare与tushare历史日线数据下载与更新(python代码) 今天讲讲量…

复杂excel表格内容数据导入 接口参数注解校验

校验代码 // 校验文件内容List<CheckResult> checkResults CheckResult.checkResultList(excelDataList);String collect checkResults.stream().map(CheckResult::getMsg).collect(Collectors.joining(","));if (!CollectionUtils.isEmpty(checkResults))…

redis简介及应用

文章目录 1.redis简介2.安装配置2.1 单机部署2.2 配置 3 主从部署4 哨兵部署5.集群部署6.客户端工具 1.redis简介 某些网站出现的问题&#xff0c;如12306、淘宝等… 2.安装配置 2.1 单机部署 安装gcc、关闭防火墙、关闭selinux等 #安装gcc yum -y install gcc #关闭防火墙…