我们知道MCS-51中有很多的引脚,这些引脚很多一般都是用作输入或者输出口,其中有两个引脚P3.0和P3.1比较特殊,我们常将其用作串行通信的数据发送和接收端TXD、RXD。
目录
🐱通信方式
🐱串行通信的传输方式和数据通信方式
🍑数据传输方式
🍑数据通信方式
🐱串行口结构
🐱串行通信控制寄存器
🍎控制状态寄存器--SCON
🍎电源控制寄存器--PCON
🐱波特率设计
🐱串行口工作方式
🥝串行方式0
🥝串行方式1
🥝串行方式2、3
🐱通信方式举例
🐟1、同步通信
🐟2、异步通信
🐱通信方式
因为我们单片机的信息或许不只是在自己片内使用,有时候还要将一个单片机的信息发送给另外一个单片机,而发送就需要选择通信方式。所以在学习串口通信方式之前,我们很有必要先来了解一下常见的通信方式。
常见的通信方式有两种:串行通信和并行通信。
串行通信的数据传输方式是一位一位地传递过去,例如我有一个数据11101010,那么其将会被一位一位排队地传过去。而并行通信是一次性发送一个字节,例如刚才的11101010,它的发送方式是一个引脚发送一个位,如果8个引脚那么就可以一次可以发送一个字节。
🍈串行通信:
串行通信一般只需要一对两条传输线,相比较并行通信大大节约了引脚和成本,适合于远距离的通信。但是显而易见,其一位一位地传输,相较于并行通信一次传输一个比特来说其传输速率较低。
🍈并行通信:
并行通信一个最大的优点就是传输的速率快,一次8个比特位一个字节,但是其缺点也很明显,那就是需要大量的引脚,其适合速率需求高并且近距离的传输。
🐱串行通信的传输方式和数据通信方式
既然我们是以串行通信为例子,那么我们就需要注重来看看串行通信的数据传输方式。从前面的图我们可以看到串行通信真正通信的端口只有4个,包括单片机1的RXD、TXD和单片机2的RXD和TXD。接下来我们来看看串行通信的数据传输方式有哪些:
🍑数据传输方式
🍉1、单工:单工就是数据只能由单片机A传输给单片机B而不能反过来。
🍉2、半双工:半双工就是单片机A可以传输数据给单片机B,并且单片机B也可以传输数据给单片机A,但是在一个时刻只能由一个单片机发送,一个单片机接收。也就是说某个时刻里面,单片机A如果在发送数据给单片机B,那么单片机B就不能发送数据给单片机A。
🍉3、全双工:全双工就是在半双工的基础上可以允许同时双向发送数据,它需要发送端和接收端都同时具备发送和接收的能力,也就是两个方向相反的单工的叠加。而我们的AT89C51单片机正是采用全双工的通信方式
🍑数据通信方式
与数据传输方式类似,我们还需要去选择串行通信的数据通信方式,数据传输方式决定的是怎么发送数据,而通信方式决定的是数据之间传输的协议。
🍉异步通信
异步通信就是两个端的时钟不同,也就是说它们没有统一的工作节拍,所以它们之间的数据通信就需要定义协议。在异步通信里面,数据是以一帧的方式传输的,一帧所包含的内容有N个数据位(低位在前,高位在后),1个起始位和1个结束位以及奇偶校验位。所以说一帧的数据结构包含11个位。
起始位占1格,它的数值是0,而电路的等待状态位数也是1。平常状态下电路在不断检测收到的位的状态,一旦在一堆1里面突然接收到0,那么也就代表着一帧数据即将传来,那么接收端会做好接收准备。然后就是紧跟着的N个数据位,前面是低位,后面是高位(D0, D1, D2, D3, D4...),数据位可能是5、6、7、8位等。数据位后面就是奇偶校验位,这一位一般用来检验数据的完整性或者用它来将数据划分用途等(0代表用途A,1代表用途B)。最后是停止位,停止位是1,接收到停止位后,接收端就知道本次接收完毕,然后去做下次接收的准备(检测低电位)
但是呢一帧和一帧之间未必是紧挨着的,有时候一帧后面再跟几个空闲位再去开始下一帧也不是没有。而空闲位也就是异步通信的特征,它代表着在等待。
🍉同步通信
接下来我们来仔细看一下同步通信,同步通信是指接收端和发送端时钟一致的通信方式,通常情况下同步通信会规定一到两个同步字符(SYNC),同步传输的同步字符一般会选择的是ASCII中规定的16H(00010110),用来确定通信双方是否达到同步可通讯状态,在确定双方均同步后再发送数据。而在数据发送时,字符和字符之间不会像异步通信一样存在空闲位(1),也不会存在起始位和终止位,它们都是紧密相连的。
也得益于同步通信没有过多的标志位,所以其传输速率可以达到很高,但是硬件设计比较复杂。
⭐波特率(Baud rate)
波特率代表每秒钟传送的二进制代码的位数,本质上是衡量数据传输的速率的一个物理量,单位是b/s。假如数据传输的速率是100字符/秒,而每个字符包括1给起始位,1给结束位和5给数据位,那么其波特率就是7 x 100 = 700(b/s)
所以波特率就是代表着每秒传递的二进制代码的位数,即每个代码的传送时间就是1/波特率
异步通信的波特率一般在50b/s~19200b/s之间
🐱串行口结构
这里说的串行口其实就是那P3.0和P3.1这两个全双工的串行通信端,它们可以用作UART(通用异步接收和发送器)实现与另外的系统进行串行通信。
上面就是我们进行串口通信的各部件结构图,首先我们来看发送/接收数据的缓冲器SBUF,发送缓冲器和接收缓冲器本质上是一个寄存器,只是通过软件来判断不同的工作状态然后对应不同的用法而已。当其作为接收缓冲器时只能读出;而作为发送缓冲器时只能被写入。而串行数据发送和接收数据的速率则是与移位时钟同步,而波特率也是代表着数据收发速率,所以移位时钟就是波特率,而这个移位时钟则是通过定时器T1的溢出率经过分频 / 不分频后再通过16分频后得出。
在发送时,SBUF缓冲器就用来存储要发送的数据,所以我们只能对该缓冲器进行写入而不能读,当一帧数据发送完毕后,就会让发送中断标志位Tl置1;
当接收时,SBUF缓冲器用来存储接收的数据,所以我们只能对该缓冲器进行读而不能写入,而当一帧数据被接收完整后就让中断标志位Rl置1。
🐱串行通信控制寄存器
串行通信控制寄存器我们主要学习两个:控制状态寄存器SCON和电源控制寄存器PCON
🍎控制状态寄存器--SCON
SCON是一个8位寄存器,它的地址是98H,可以进行位寻址,其各个位及其意义如下表所示:
D7 |
D6 |
D5 |
D4 |
D3 |
D2 |
D1 |
D0 |
SM0 |
SM1 |
SM2 |
REN |
TB8 |
RB8 |
TI |
RI |
首先我们来看SM0和SM1,这两个位是用来选择串口的工作方式的:
SM0=0,SM1=0;此时进入工作方式0,工作模式是同步移位寄存器,波特率是晶振频率的12分频,即fosc/12。
SM0=0,SM1=1;此时进入工作方式1,工作模式是10位异步通信接受和发送器,波特率是可以变动设置的
SM0=1,SM1=0;此时进入工作方式2,工作模式是11位异步通信接受和发送器,波特率是晶振频率的64分频或者32分频,即fosc/64、fosc/32。
SM0=1,SM1=1;此时进入工作方式3,工作模式是11位异步通信接受和发送器,波特率是可以变动设置的
我们不介绍SM2,这个位用于进行多机通信(即一台单片机和多台单片机的通信),这里不展开细说。
接下来来看看REN位,该位是SCON的第四位,它是串行接收的开关,作用是控制开启允许接受控制位。当REN=1的时候才开启中断接收的开关,当REN=0,就关闭中断接收的开关。下一个我们先来看SCON.0的RI位,该位是接收中断标志位,接收到一帧数据后会将该位置为1,然后单片机检测到REN=1和RI=1就会开启中断通知CPU将数据从SBUF(接收缓存器)种拿走,并且手动清除RI位。
接下来我们才来看第三位TB8,系统会将发送的一帧数据里面的第9位装载到TB8里面,一般一帧数据的第9位就是D8位(奇偶校验位),因为这个位我们之前说过可以作为设置该帧数据的属性,所以SCON寄存器会开一个位来存储要发送的数据的奇偶校验位。
然后就是RB8位,该位的作用是将接收到的数据的第9位(奇偶校验位)放到RB8里面,然后通过判断RB8的值来确定该接收到的数据的属性。
最后是TI位,该位是发送中断标志位,当一帧数据由SBUF缓冲器发送出去后,此时就会开启中断告诉CPU说SBUF发送缓冲器已经空了(数据发出去了),需要对下一组即将发送的数据进行装填到SBUF发送缓冲器,并且将TI手动清空。
⭐SBUF的小问题
SBUF既做发送缓冲器和接收缓冲器,一般来说CPU是必须通过软件来判断当前的SBUF是处于哪种工作状态
🍎电源控制寄存器--PCON
PCON寄存器的字节地址是87H(不能位寻址,所以我们开启需要使用ORL字节或指令)。在这个寄存器中我们只看最高位SMOD,因为只有该位和我们的串行通信有关。
该位是用来控制波特率是否倍增的,只适用于工作模式1、2和3,当SMOD=1时使用的波特率会加倍
🐱波特率设计
上面我们看了一下PCON寄存器的SMOD位置1会让波特率增倍,回过头来看我们可以发现我们的四种工作方式中已经有两种:方式0和方式2是固定了波特率的,而方式1和方式3的波特率是可以改的,所以我们需要选择我们使用的波特率。但是由于振荡来源不同,所以各种工作方式的波特率计算方式又不同!
🍍方式0:
方式0的波特率是等于晶振的12分频,不受PCON中断SMOD位的影响,始终保持是fosc/12。
🍍方式1 & 方式3:
方式1和方式3都是可以自选波特率的工作模式,其移位时钟脉冲输入是由T1定时器的溢出率来决定的。所以我们通过设置SMOD和定时器初值X来具体的计算方式如下:
波特率 = ,其中init就是初值,最常见的时候定时器T1选用的是模式2,此时n=8,所以X =
🍍方式2:
相似地,方式2也是一个固定的波特率工作模式,但是它固定的波特率有两个,而这两个分别为fosc/64和fosc/32,而至于选择哪一种则有PCON的SMOD位来决定,当SMOD=0时,波特率=fosc/64;当SMOD=1时,波特率=fosc/32。
但是在通常情况下,常用的波特率以及其对应的定时器需要设计的初值我们可以通过查询下面的表格来进行设计:
🐱串行口工作方式
下面我们来仔细看看如何用串行口来实现几种通信方式。
🥝串行方式0
方式0是需要有同步移位寄存器输入 / 输出的工作方式,即它的数据通信方式是同步通信。该模式不适用于两个单片机之间通信,它的功能是用作拓展IO口,其中以RXD为要发送的数据的输入和输出引脚;而TXD输出移位的时钟。下图即为拓展的串行->并行发送电路和并行->串行拓展接收电路,分别用到了74HC164和74HC165两块芯片。发送时P3.0口一次来一帧数据,然后该数据通过AB口被74HC164接收到后按低位在前的顺序被发送出去,而P3.1口就负责发送同步移位时钟信号;当接收时数据通过RXD口从74HC165传送到单片机,同时单片机的TXD引脚依然负责发送同步移位时钟信号,数据又低位在前被接收进去
🥝串行方式1
串行方式1是用于单片机间的发送与接收,为了方便我们不考虑多机通信,只考虑单对单的通信方式。从前面了解到工作方式1是10位异步收发,包括1个起始位,8个数据位和一个停止位,无奇偶校验位,并且由于是异步收发所以此时RXD和TXD就负责接收和发送数据,并且波特率可变。
🥝串行方式2、3
串行方式2和3都是适用于两块单片机通信的串口工作模式,其每一帧会发送11位的数据,其与前面的串行方式1的区别是多了一个奇偶校验位,该多出来的第九位数据会在发送时放入TB8,而接收时被放入RB8。
🐱通信方式举例
🐟1、同步通信
我们设计一个串口扩展并口的装置,利用到74LS164芯片,该芯片能够将串行输入改为并行输出,这次我们利用这个并行输出来实现流水灯效果。
该流水灯效果的代码如下:
ORG 00H
SJMP MAIN
ORG 30H
MAIN:
MOV R1, #08H
MOV R0, #60H
MOV 60H, #0FFH
MOV SCON, #00H
MOV A, @R0
CLR C
AJMP SEND
DELAY:
MOV R5, #20
D2:
MOV R6, #20
D1:
MOV R7, #248
DJNZ R7, $
DJNZ R6, D1
DJNZ R5, D2
RET
SEND:
RRC A
MOV SBUF, A
WAIT_SEND:
JNB TI, WAIT_SEND
ACALL DELAY
CLR TI
DJNZ R1, SEND
END
电路设计如下:
最终可以实现流水灯效果,不过我们还是来看看代码把。首先是设计两个寄存器R1和R0用来分别存储要发送的次数以及发送的内容,发送的内容会被存储到R0地址寄存器所对应的地址#60H处。然后我们设计一个初值0FF放到60H处。最后再配置好SCON寄存器即可,我们选择方式0所以设置的内容是00H。
然后我们再来看发送过程,发送过程共分两步:装填和发送。装填就是SEND函数所对应的内容,将累加器A内的内容(要发送的数据)写入SBUF发送缓冲器。然后就会进行自动发送,当发送完成后TI位就会被置1,所以我们通过JNB函数来进行等待发送,当发送完成就跳出死循环。然后清除TI位,最后判断循环次数完成没有来决定是否结束总的程序。
不过这里由于设置了流水灯效果,所以在每次装填数据之前将A内的数据进行移位以实现流水灯效果,例如一开始A是0FFH,由于Cy位被置0,所以移位完装填后就变成7FH,Cy位变为1,而下一次移位就变成20H...以此类推。
🐟2、异步通信
下面我们来看看如何进行异步通信:
例子:单片机A和单片机B的晶振都是11.0592Mhz,将单片机A存储器RAM里面#50H~#51H的内容传输到单片机B#60H~#61H处,使用
首先我们先确定要规划的步骤:
1、设置定时器产生波特率;
2、开启中断
3、设置串行口
首先我们选定要使用到的是定时器1的工作模式2一个波特率:4.8Kbps,则初值为#0FAH
发送端代码:
/*TXD*/
ORG 00H
AJMP MAIN
ORG 30H
MAIN:
MOV TMOD, #20H
MOV TL1, #0FAH
MOV TH1, #0FAH
SETB TR1
MOV SCON, #0C0H
MOV R0, #02H
MOV R1, #50H
MOV 50H, #7FH
MOV 51H, #19H
MOV P1, 50H
MOV P0, 51H
SEND:
MOV A, @R1
MOV C, PSW.0
MOV SCON.3, C
MOV SBUF, A
SEND_WAIT:
JBC TI, NEXT
SJMP SEND_WAIT
NEXT:
INC R1
DJNZ R0, SEND
END
接收端代码:
/*RXD*/
ORG 00H
AJMP MAIN
ORG 30H
MAIN:
MOV TMOD, #20H
MOV TL1, #0FAH
MOV TH1, #0FAH
SETB TR1
MOV SCON, #0D0H
MOV R0, #02H
MOV R1, #60H
RECEIVE:
JBC RI, CHECK
SJMP RECEIVE
CHECK:
MOV A, SBUF
JBC RB8, CHECK_IF_1
JBC PSW.0, ERROR
LJMP SUCCESS
CHECK_IF_1:
JBC PSW.0, SUCCESS
LJMP ERROR
SUCCESS:
MOV @R0, A
INC A
DJNZ R0, RECEIVE
SJMP RESULT
ERROR:
SETB P2.0
SJMP END_FUNC
RESULT:
MOV P1, #60H
MOV P0, #61H
END_FUNC:
END
最终效果:
参考内容:文章来源:https://www.toymoban.com/news/detail-471139.html
老师上课的课件 文章来源地址https://www.toymoban.com/news/detail-471139.html
到了这里,关于【MCS-51】串行I/O接口及其通信的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!