一、串口通信的初步认识
通信,传统理解就是信息的传输与交换。单片机与单片机之间,单片机与电脑之间,以及单片机与各式各样的模块之间都可以进行通信。
如果没有通信,那么单片机的功能仅仅局限于它本身,它没办法从其他设备获取有用信息,也无法将自己产生的信息告诉其他设备,这样子单片机与外围器件的合作就会收到限制,没办法完成更多的功能,就像一个没办法拓展业务的公司。
通信分类:
1、并行通信:实现以字节为单位进行通信,同一时刻可以发送多个数据位的数据, 我们程序当中写的P0=0xFC,就是一次同时对8位进行信号的输出;习惯上,我们还称P0、P1、P2、P3为单片机的4组并行总线
2、串行通信:实现以位为单位进行通信,同一时刻只能发送一个数据位的数据,低位先发 高位在后,发送8次才能发送完一个字节
串口:串行接口的简称,一种通讯接口,也就是实现通信的工具,可以实现两个设备互相通信。 串口是一种泛称,UART、TTL、RS232、RS485都遵循类似的通信时序协议,这个协议在数据传输过程中控制数据流,包括数据位数、波特率等,因此它们都被称为串口。
(1)串口通信与串行/串口通信的区别:
所以,标题的UART串口通信指的是使用UART这个串口进行通信,也就是说串口通信也是一个泛称,即使用串口进行通信。而我们前面所说的串行和并行通信指的是通信所举行的方式。而接下来我们所说的UART串行通信指定就是:使用UART这个串口,以串行的方式进行通信。
(2)51单片机以什么为串口进行通信呢?——UART
51单片机内部自带UART(即通用异步收发器),可以实现单片机的串口通信。STC89C52中有两个引脚是专门用来做UART串行通信的,就是如下图所示的P3_0和P3_1,也叫做RXD和TXD。RXD(Receive external Data),即接收外部设备传来的数据,也称为串行接收数据的引脚。
TXD(Transmit Data),串行发送数据的引脚。
(3)两个单片机是如何通信的?
路径1:单片机1发送,单片机2接收 路径2:单片机2发送,单片机1接收
前面说到,串行信是低位先发,高位在后。如果我想要通过路径1发送一个0xE4的数据,二进制表示就是0b11100100,那么我就要先发送0,此时先让TXD拉低电平,持续一段时间,发送0;然后再继续拉低电平,持续一段时间,发送第二个0;再拉高电平,持续一段时间,发送一个1.......直到全部发送完毕。那么这里的一段时间我们该如何去定义它?——波特率(比特率)
(4)波特率(比特率)
波特率就是发射二进制数据位的数率(每秒钟发送的字节位),习惯上用baud表示,即我们发送一位二进制数据的持续时间=1/baud。常用的波特率就是9600,也就是1秒钟可以发送9600个数据,1s/9600=100us,那么这个时间间隔就是100us,也就是发送完一个数据到发送下一个数据之间需要花费100us。
(5)通信之前单片机之间需要做什么准备?
1、波特率保持一致
在通信之前,2个单片机之间都应该要明确规定好它们之间通信的波特率,必须保持一致,收发 双方才能实现正常通信。
2、数据的接受保持一致
数据什么时候开始接受?什么时候开始发送?如果数据提前接受或者是延迟接受,都会造成数据的接受错误。因此我们需要有个信号去告诉单片机我开始发送了/我发送完成了。
在UART通信的时候,我们规定当没有通信信号的时候,通信线路保持高电平,在开始发送数据的时候,先发一位0表示起始位,然后再开始发送8位数据位,数据发送完成后再发送一位1表示停止位。也就是说,我们实际上一共发送了10位数据,多出来的两位是起始位和停止位。
如下图所示,上排对应的是二进制也就是1-8;下排对应的是依次十进制,可以看到高电平输出之和为65,我们再接着查看ACSII表,65对应的是A,也就是说单片机输出A给电脑。
所以我们想要发送什么数据,就按照ACSII表上的数值去控制单片机去发送高低电平即可。
而我们其实不需要那么麻烦去一个一个查表去控制单片机输出高低电平,以Arduino开发板为例:
这是它发送“C”的程序,我们只需要规定好波特率为9600,调用下面那个函数就能实现这个功能。
二、RS232 通信接口
我们的台式电脑一般都会有这样子的9针的串行接口(如图所示),这种串口就叫做RS232接口。在物理结构上分为9针(左图下面)和9孔(左图上面)的,习惯上也称为公头和母头。这种接口已经很少见了,现在都是USB接口比较常见。
虽然RXD、TXD、GND这三个引脚的名字和单片机上的串口名字一样,但是却不能直接与单片机对接通信,因为并不是所有的电路都是5V代表高电平,0V代表低电平。对于RS232来说,它是个反逻辑,也叫做负逻辑。它的0代表高电平,1代表低电平。-3V ~ -15V电压的代表是1,+3V ~ +15V电压的代表是0;因此RS232不能和单片机串口直接进行连接,需要用一个电平转换芯片MAX232来完成。
图中红色圈起部分就是一个电平转换芯片,一端是USB接口另外一端可直接连接单片机。 右图是蓝牙串口,一端连接单片机,数据发送出来,可以通过手机进行蓝牙连接,然后手机上也会有一个串口助手帮助我们收发数据。
而我们的单片机也是通过一个USB与电脑进行通信的:
MAX232芯片起中间人的作用,从而实现标准RS232接口与单片机UART之间的通信连接。 其实SR232串口和UART串口所使用的协议类型是一样的,只是二者的电平标准不一样而已。
而常见的电平标准有以下三种:
而我们电脑端需要一个串口助手来帮助我们收发数据显示:
注意:串口助手那里的串口要和自己计算机设备管理器那里的扫描串口一致
三、通信基本类型
1、通信三种基本类型
2、通信的两种方式
同步通信: 发送端在发送串行数据的同时,提供一个时钟信号,并按照一定的约定(例如:在时钟信号的上升沿的时候,将数据发送出去)发送数据,接收端根据发送端提供的时钟信号,以及大家的约定,接收数据。
异步通信: 接收方并不知道数据什么时候会到达,收发双方可以有各自自己的时钟。发送方发送的时间间隔可以不均,接收方是在数据的起始位和停止位的帮助下实现信息同步的。这种传输通常是很小的分组,比如:一个字符为一组,数据组配备起始位和结束位。所以这种传输方式的效率是比较低的,因为额外加入了很多的辅助位作为负载,常用在低速的传输中。
异步就是约定输入输出的频率,可以同时接受或者发送;同步就相当于检测,只能靠一根线,有一端发出数据了另外一端就存入数据。
3、常见通信接口
4、UART的四种工作模式:
模式1就是我们前面提到的1位起始位,8位数据位和1位停止位。
而模式2和3是9位UART,而比模式1多出来的那一位我们用来校验,也就是校验位,用来检验前面的8位数据存放的是否正确。而校验又分为奇校验和偶校验:
①奇校验时,发送方应使数据位中 1 的个数与校验位中 1 的个数之和为奇数;接收方在接收数据时,对 1 的个数进行检查,若不为奇数,则说明数据在传输过程中出了差错。
②偶校验则检查 1 的个数是否为偶数。
51单片机的UART的串口结构由串行口控制寄存器SCON、发送和接收电路三部分组成,我们先来了解一下串行口控制寄存器SCOM:
四、串行口控制寄存器SCOM
我们需要在串口通信前告诉CPU相应的内容,所以我们要在主程序初始化位置配置好寄存器
五、串口数据缓冲寄存器SBUF
SUBF的功能是什么呢?——存放通信所接受/发送的数据
而我们在写程序的时候该如何利用它呢?如下图:(意思就是说,我把SUBF的数据赋值给jieshou)
接下来看一下串口图:
可以看到有2个SBUF,一个用来接受一个用来发送。那么我们写程序的时候,如何区别我需要的是哪里的数据呢。其实就是利用了C语言里面的赋值内容,等号左边是被赋值量,等号右边是赋值的数值。下面红线部分就是一个是接受,一个是发送。
这里可能会有点疑惑:既然直接把数据存放给SBUF了,那么起始位和停止位体现在哪里?——SBUF会自动处理这两位,我们不需要在程序当中体现,但串口会在通信的时候按帧的格式进行传输数据,这也是51单片机提供的串口功能的一个优点。
六、波特率发生器
前面说到,要保持通信的一个条件就是保持波特率一致,而在电脑上,我们可以直接通过串口助手进行波特率的一个选择,那么我要怎么告诉单片机要选择哪一个波特率呢?——51专门提供了一个波特率发生器,也就是T1(在定时器部分我们叫做定时器T1,但是在串口部分它叫做波特率发生器)
如果我们需要选择9600的一个波特率,也就是隔1s/9600=100us 就通知串口该发送一个数据了,这就需要用到T1的溢出功能,我们就需要去设置一个定时器的初值,然后开始计数,也就是按照定时器的工作原理去工作,溢出后就会告诉串口该发送数据了。
注意:51单片机默认的波特率发生器就是T1,并且只适用模式1
串口和中断系统图:
上图是收发过程,下图是申请中断。