嵌入式日常学习 | 通信协议篇 Day2

前言

嵌入式日常学习 | 通信协议篇 Day1

上次讲完了通信中可能会提到的一些常用的关键名词,今天算是进入到了通信协议的详细内容。其实除了之前提到的一些常用的协议,我还是想再补充一些关于物联网的通信协议,如果有时间我会再去准备。

不多说了,开始UART的学习吧。

UART(Universal Asynchronous Receiver/Transmitter)

通用异步收发传输器,通常称为UART)

其通信的特点总结为以下的三点:

1、串行、异步通信
2、两条数据线(TX和RX)
3、全双工

硬件连接【TX1->RX2 RX1->TX2】

【图片:】
在这我先停下,可能有些同学会在网络上或是做实践时遇到 【USART】
那么USART 和 UART 有什么区别呢?

其实很简单,我们把两者的英语全称都罗列出来就好

UART(Universal Asynchronous Receiver/Transmitter,通用异步收发器)
USART(Universal Synchronous /Asynchronous Receiver / Transmitter,通用同步异步通信接口)

显而易见 USART 比 UART 多了一个同步的模式,我们从第一天的学习就知道同步的意思就是拥有相同的时间标准。
所以可以理解为 USART 是 UART 的进阶版。
【图片:】

但话说回来,我虽然也用过USART,可用的较多的也是异步模式。(就是把 USART 当成 UART 来用)
【图片】

所以我建议大家还是把先UART掌握好,学习USART自然也没用那么难。

UART帧格式

【图片】

1、空闲位: 默认为高电平
2、起始位: 由高变低(1bit)
3、数据位:【先发低位,后发高位】(5~8bit,由于计算机中,一个字节常以8位为一个单位出现,所以8bit最为常见)
4、校验位:(1bit)【奇偶校验,可有可无】
5、停止位:(1bit)由低变高

在了解完UART帧格式后,这里提出两个问题:

问题1:众所周知,我们常以高电平表示“1”,低电平表示“0”。那接下来我会给你一个电位信号图,你认为这组信号是表示什么二进制数?
【图片】

有人会说,这不就是 01 吗?,但是如果是这样的话,阁下带如何对待呢?
【图片】

所以我们会存在01,0011,000111…等很多的答案,造成这样的原因便是我们没有采取相同的时间长度到对信号进行采样,不同的单片机也如同人一样,如果没有相同的标准,会收到不同的答案

为了解决这个问题,我们引入了 【波特率】 的概念,同时也想普及一下 【比特率】 的概念

波特率 & 比特率

波特率 即单位时间内传输了码元(符号)。
比特率 即单位时间内传输了多少位(比特)。

那么两者有什么区别呢?
首先大家得明白 【码元和比特的关系】,我们相互传输的东西本质是比特,但是1位比特可以表示“0“和”1“的两个信号,2位比特的话可以表示”00“,”01“,”10“,”11“的四个信号…
所以码元和比特的关系则是:码元数 = 2^比特数,所以波特率 = 2^比特率

问题2:可能有人会问,为什么我们每次传输一次字节,都要结束一次传输过程,而不是一次性把几个字节【字符串】进行传输,多方便!!!
在这里插入图片描述

就这个问题,我有2点看法

1、考虑到单片机的资源数量:

在过去的时代,肯定没有像如今那么好的硬件条件,如果想要一次传输那么多字节,肯定得想办法存储那么多数据,但再好的硬件也一定会超过一个上限,如果是长时间传输大量数据,一定蚌埠住的。综上所述,我们才会采取以每一个字节为单位来传输数据

2、考虑到单片机之间传输的误差累积:

信息传输之间不是立即传输完毕,是存在时间差的。虽然这个时间小到微不足道,但是举个“栗子”:如果每传输1bit需要1ms,那么传输1Byte需要8ms,如果中间没有停顿。等你想要得到第126个数据时,你就要等1s…以此类推,你只会等着越来越久;而且也这是因为这个误差,会导致数据的准确性大打折扣。

综上所述,我们不能一次性传输多个字节。

讲了这么多,如果是初学者可能已经害怕了😰,为何如此复杂???
【图片:开白】

别紧张,其实我之前所说的一系列逻辑和细节是想让大家能在理论上理解 UART的一系列 (由于我是以工作为主,所以还是得注意基本功),其实大部分有串口功能的单片机中已经有对应的 【UART控制器】 虽然每个单片机的控制器可能有所不同。但最基本的参数【在UART帧格式中已经提到】每个单片机的控制器都是一样的,所以我就不展开继续讲解。
【图片:我已经干不动了】

最后在我写串口调试的工程时,总会做一件很重要的事情就是 输入输出重定向

输入输出重定向

学过C语言的小伙伴们,应该清楚 scanf() , printf() , getchar() , putchar() 等一系列关于字符处理的函数。那么单片机中是否也有类似的功能?或者与我们所学的C语言有什么区别呢?

这里我以STM32中关于串口的函数来进行类比:

1、STM32传输一个字节 
HAL_UART_Transmit() <===> putchar() 

2、STM32接收一个字节 
HAL_UART_Receive()  <===> getchar()

所以对于单片机来说,是有其对于C语言的实现的方式,但两者之间有什么区别呢???

1、来源的不同

对于电脑中的C语言来说,其实现输出字符的功能的部分是来源于你安装的C语言编译器里的库文件里的;而对于单片机来说,是通过单片机处理串口的函数来实现的。
2、输出定向的不同
对于电脑中的C语言来说,你所输入的文本,输出的方向是电脑的显卡(屏幕)或者是磁盘(文件系统);而对于单片机来说,便是串口。

最后

这便是关于UART有关的内容,下次我会讲解和UART息息相关的RS232和RS485协议,如果这篇文章对你有用,希望能点个赞或者收藏~ 你的支持是我最大的动力!

大家可以关注我的相关平台:

B站:https://space.bilibili.com/3546554459752812?spm_id_from=333.1007.0.0
GitHub:https://github.com/TackyLzs

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值