单片机学习笔记:串行口和串行通信详解(上篇)

目录

异步通信&同步通信

异步通信

一、字符帧

二、波特率

同步通信

串行通信的制式

89C51串口及应用

串行通信过程

串行口工作方式及帧格式

方式0——半双工同步通信(8位)

方式1——全双工异步通信(10位)

方式2——全双工异步通信(11位)

方式3——全双工异步通信(11位)

串行口控制

电源和波特率控制寄存器PCON

串行口控制寄存器SCON 

多机通信

串行口的工作方式以及波特率设置

方式0和方式2的波特率

方式1和方式3的波特率

T1溢出率


串行通信可以分为异步通信和同步通信两种,异步通信两字符间的时间间隔是不确定的,但是同一字符相邻位的传输的时间间隔是确定的;并行通信是一个字符的每一位都是同时发送的,但需要收发双方具有同频同相的同步时钟,此时只需在传送报文前加上特定的同步字符即可,收发双方就可建立同步

异步通信&同步通信

异步通信

异步通信通常是以字符(或字节)为单位组成字符帧传送的。字符帧由发送端一帧一帧地发送,经过传输线,接收设备一帧一帧地接收。发送端和接收端可以有各自的时钟来控制数据的发送和接收,这两个时钟相互独立,互不同步

异步通信是通过字符帧的格式来判断发送端何时开始发送以及何时结束的——平时发送线为高电平,当接受端检测到传输线上发送过来的是低电平时,就意味着发送端已经开始发送了,当接收到停止位时,就说明一帧字符信息已经发送完毕了

异步通信中,字符帧格式和波特率是两个重要指标,可由用户根据实际情况选定

一、字符帧

字符帧,也叫数据帧,由起始位,数据位,奇偶校验位,停止位组成,相邻字符帧之间可以无空闲位,也可有若干空闲位,用户可根据需要决定

  1. 起始位,位于字符帧开头,只占一位,为逻辑低电平——0,用于表示开始数据发送
  2. 数据位,紧跟起始位,用户根据情况可选择5,6,7,8位,低位在前,高位在后,若所传数据为ASCII码,一般取7位
  3. 奇偶校验位,位于数据位之后,也仅占一位,用于发送串行通信中发送数据的校验位
  4. 停止位,位于字符帧的末尾,为逻辑高电平——1,通常可取1,1.5,2位,表示信息已发送完毕

奇偶校验位通常有有奇校验,偶校验,无校验三种,可由用户自行选择——但一般都采用无奇偶校验的方式

所谓奇校验,就是确保发送的数据位中1的个数为奇数,如果数据位中1的个数是偶数,那就给校验位赋值1,如果数据位中1的个数是奇数,那就给校验位赋值0。这样就确保发送的数据中1的个数是奇数
偶校验跟奇校验相反,但处理步骤是一样的。偶检验位的计算方法是首先将数据位的各位进行“异或”操作,然后将结果与0相“异或”,得到的结果就是偶校验位的值


处理方法就是判断发送方的数据位中1的个数是否是奇数。选择奇校验时,首先将数据位的各位进行“异或”操作,然后将结果与1相“异或”,得到的结果就是奇校验位的值

为什么奇偶校验不常用
如果数据中发生多位数据错误就可能检测不出来,更检测不到错误发生在哪一位

关于TB8和RB8,这两位既可以作奇偶校验位。也可以做多机通信的数据,地址选择位

二、波特率

波特率是指每秒传送的二进制数码的位数,单位是b/s,即位/秒,表征数据传输的速度,波特率越高,数据传输的速度就越快。但实际的字符传输速率还要看字符帧的格式

字符的实际传输速率是指每秒传输的字符帧的帧数,即为 “波特率/字符帧长度=XX帧/秒”,每一位的传输时间为——波特率的倒数

波特率还和信道的频带有关,波特率越高,则频带越宽,通常异步通信的波特率在50~9600b/s,通常是时钟频率的1/16或1/64

  • 异步通信的优点:不需要先传送同步脉冲,字符帧长度也不受限制,所需设备简单
  • 缺点:字符帧中包含起始位和停止位而降低了有效数据的传输速率
  • 同步通信

    同步通信是一种连续串行传送数据的通信方式,一次通信传送一帧信息,与异步通信的字符帧不同,此处的信息帧常包含若干个数据字符

    同步字符帧包括同步字符,数据字符,校验字符CRC

    1. 同步字符,位于帧结构的开头,用于确认数据字符的开始(接收端会持续采样,直到接收到的字符和双方约定的同步字符相同时,才会保存后面接收到的字符),用于同步收发双方的时钟,通常是一个方波信号
    2. 数据字符,在同步字符的后面,个数不受限制,理论上可以接无穷多个,个数与连接线的个数有关
    3. 校验字符有1~2个,位于帧结构的末尾,用于接收端对接收到的数据字符进行正确性校验

    同步字符可采用同一标准格式,也可自定义。在单同步字符帧(只有一个同步字符)结构中,通常采用ASCII码中的SYN(16H)代码;在双同步字符帧中(两个同步字符),一般采用国际通用标准代码EB90H

    串行通信的制式

    串行通信是在两个站之间传送的,按照数据传送的方向,可以分为单工,半双工,全双工三种

    1. 单工——单方向单功能收发
    2. 半双工——双方向双功能异步收发,由软件控制电子开关进行切换,耗时一般为几十毫秒,在对时间敏感的交互式系统中会导致延迟累积,造成较大误差
    3. 全双工——双方向双功能同步收发,实际中,很少使用同步收发功能

    0ff7eba6977545fd89c7f8e82df5d1dd.jpeg

    89C51串口及应用

    串行口由两个数据缓冲器SBUF,一个移入寄存器,一个串行控制寄存器SCON和一个波特率发生器T1组成

    串行口数据缓冲器SBUF是可以直接字节寻址的专用寄存器,物理上分为发送缓冲器和接收缓冲器,逻辑上当作一个寄存器,两个缓冲器共用一个名字——SBUF,一个地址——99H,由读写信号区分:CPU写SBUF时为发送缓冲器,读SBUF时为接收缓冲器

    接收缓冲器是双缓冲的——以此避免接收下一帧数据之前,CPU未能及时响应接收器的中断把上一帧的数据读走,产生两帧数据读重叠的问题

    发送缓冲器为保持最大传输速率,一般不设置双缓冲,因为CPU是主动的,不会产生写重叠

    特殊功能寄存器SCON用来存放串口的控制和状态信息,T1作串口的波特率发生器,其波特率是否可以倍增可由特殊功能寄存器PCON的最高位控制

    串行通信过程

    接收数据的过程——CPU允许接收时(即SCON的D5位:REN位置1时——软件置1),外接数据通过引脚RXD(P3.0)串行输入,数据的最低位首先进入输入移位寄存器,一帧接收完毕之后再并行送入缓冲器SBUF中,同时将SCON的D0位:数据接收标志中断位RI置1,向CPU发送中断请求。CPU响应中断后,用软件将RI位清0,并同时读走输入的数据,然后开始下一帧的输入过程

    如果在接收完一帧数据之后,没有手动通过软件将RI清零,在REN仍为1的情况下,CPU仍会接收数据,但此时CPU处于中断状态,所以不会接收到传输的任何信息——也就是说,此时会丢包,此时的缓冲器是满的,没有数据能进来

    所有需要软件清0的——实质上都需要手工写代码清0

    数据发送的过程——CPU要发送数据时,要将数据并行写入缓冲器SBUF,同时启动数据由TXD(P3.1)引脚串行发出,当一帧数据发送完,也就是发送缓冲器为空时,由硬件自动将发送中断标志TI置1,向CPU发出中断请求。CPU响应中断请求之后,用软件将TI位清0,同时将下一帧数据写入SBUF。重复上述过程,直到所有数据发送完毕

    串行口工作方式及帧格式

    89C51可以设置四种工作方式

    方式0只有8位数据位

    方式1传输10位为一个字符帧,其中8位数据,1位起始位,1位停止位

    方式2和方式3均传输11位为一个字符帧,其中9位数据位,1位起始位,1位停止位

    方式0——半双工同步通信(8位)

    方式0是一种极端情况,又称为同步移位寄存器输入输出方式。在这种方式下,数据从P3.0口的RXD端串行输入输出,同步信号从P3.1口的TXD端输出,波特率固定不变,为震荡频率的1/12,该方式以8位数据为一帧,无起始位、停止位以及检验位,先发送或接受最低位

    方式1——全双工异步通信(10位)

    串行口采用该方式时,适用于点对点通信,发送或接受10位数据为一帧,其中8位数据,起始位,停止位各有1位,无校验位。波特率可以改变——由PCON最高位:SMOD和SCON的D1位:TI共同决定

    方式2——全双工异步通信(11位)

    此方式可以发送或接收11位数据,包含1位起始位,1位停止位,9位数据位(第九位数据有特殊的用途——可以通过软件控制,加上特殊功能寄存器SMOD中的SM2的配合,可以实现多机通信)方式2波特率固定,为震荡频率的1/64或1/32,可由PCON最高位SMOD选择——当SMOD为0时,波特率为震荡频率的1/64;当SMOD为1时,波特率为震荡频率的1/32

    方式3——全双工异步通信(11位)

    方式3和方式2类似,帧格式为11位一帧,波特率可变,也适合多机通信

    串行口控制

    串行口的工作方式,中断标志,可编程位的设置,波特率的倍增均是通过特殊功能寄存器PCON和SCON来控制的

    电源和波特率控制寄存器PCON

    PCON是为控制电源设计的特殊功能寄存器,PCON的地址为87H,只能字节寻址,不能位寻址

    PCON的最高位D7为SMOD,是串行口比特率的倍增控制位——当SMOD=1时,工作方式1、工作方式2、工作方式3下的波特率都会加倍

    如在工作方式2下,SMOD=0时,波特率为fosc/64,而当SMOD=1时,波特率就会变为fosc/32

    PCON 用来管理单片机的电源部分,包括上电复位检测、掉电模式、空闲模式等,单片机复位时PCON全部被清0。其各位的定义如下表所示

    SMOD-该位与串口通信波特率有关

    SMOD=0:串口方式1, 2,3时,波特率正常

    SMOD=1:串口方式1, 2,3时,波特率加倍

    PD-掉电模式设定位

    PD=0:单片机处于正常工作状态

    PD=1:单片机进入掉电(Power Down)模式,可由外部中断低电平触发或由下降沿触发或者硬件复位模式换醒,进入掉电模式后,外部晶振停振,CPU、定时器、串行口 全部停止工作,只有外部中断继续工作

    IDL-空闲模式设定位

    IDL=0:单片机处于正常工作状态

    IDL=1:单片机进入空闲(Idle) 模式,除CPU不工作外,其余仍继续工作,在空闲模式下可由任一个中断或硬件复位唤醒

    SMOD0、LVDF、P0F——这三位是STC单片机特有的功能,请查看相关手册,其他单片机保留未使用;GF1,GF0- -两个通用工作标志位,用户可以自由使用

    串行口控制寄存器SCON 

    SCON(Serial Control Register)串行口控制寄存器,用于控制串行通信的方式选择、接收和发送,指示串口的状态。SCON既可以字节寻址,也可以位寻址,其字节地址为98H,地址位为98H~9FH

    SM0和SM1(SCON.7,SCON.6)——串行口工作方式选择位,两个选择位对应4种通信方式  

    其中fosc为晶振频率

    一般来说,SCON的发送中断标位 TI 和接收中断标志位 RI 位在任何情况下都需要手动编程清0,方式0、1的数据位都是8位,方式2、3的数据位都是9位(包含一位可多机通信的特殊位)

    多机通信由SCON的多机通信控制位SM2,模式2和模式3涉及的第九位特殊数据位TB8以及RB8控制实现

  • 在方式0下,SM应设置为0,不用第九位数据TB8和RB8
  • 在方式1下,SM=2时,RB8是接受到的停止位
  • 在方式2和方式3下,TB8是发送的第九位数据,可用软件置1或清0,RB8是接受到的第九位数据,这两位可自定义为奇偶校验位
    1. SM2=0,此时不支持多机通信,接收到一帧数据后,不管第九位数据是0还是1,都置接收中断标志RI为1,把接受到的数据装入SBUF里面
    2. SM2=1,允许多机通信

    处于多机通信时,可以使用第九位数据位TB8,RB8作为地址数据帧标志位——一般地址帧为1,数据帧为0

    多机通信

    在多机系统中,主机只有一个,从机有多个,且每个从机都有一个地址

    设定工作方式3:主从模式+波特率可变,SCON串口功能寄存器:SM0=1;SM1=1(工作模式3)

    主从机的地址可用一个8位字符表示,大小从 000-255,主机默认是0

    电路连接为交叉线——主机的串行输入口RXD与从机的串行输出口TXD连接,主机的串行输出口TXD与从机的串行输入口RXD连接

    当一单片机与多个单片机通信时,首先置从机的多机通信控制位SM2=1(允许多机通信)

    收发过程

    主机要发送一数据块给某一从机时,它先发送一个地址字节,称为地址帧,它的第9位是“1”,此时各从机的串行口接收到第9位(RB8) 都为1,则置中断标志RI 为“1”,每一台从机都检查一下所接收的地址是否与本机相符

    若为本机地址,则清除SM2,而其余从机保持SM2=1状态。接下来主机发送数据,称为数据帧,它的第9位为“0”,各从机接收到的RB8为“0”。此时,只有与主机联系上的从机(此时SM2=0) 才会置中断标志RI 为“1”,接收主机的数据到SBUF,从而实现与主机的通信

    其余从机则因为SM2=1,且第9位RB8=0,不满足数据接收条件,从机不会发生中断,而将所接收的数据丢弃

    TI位——发送中断标志位

    在方式0中,发送完8位数据之后,TI由硬件置1,在其他方式中,在开始发送停止位时,由硬件置1,TI置1后向CPU申请中断——任何方式都必须由软件清0

    RI位——接收中断标志位

    在方式0中,接收完8位数据之后,RI由硬件置1,在其他方式中,在接收停止位的一半时,由硬件置1,还要考虑SM2的设定,RI置1后方可向CPU申请中断——任何方式下,都必须由软件清0

    串行口的工作方式以及波特率设置

    串行通信中,收发双方接收和发送的波特率(即传输数据的速率)要一样

    串行口的四种工作方式,方式0和方式2的工作波特率是固定的,方式1和方式3的工作波特率则是可变的——由定时器T1的溢出率决定

    定时器溢出率:定时器溢出的频率

    即——定时器溢出率 = 定时器溢出的次数 / 溢出所用时间 = 1 / 溢出一次所用时间(us)

    波特率 = (2^(smod)/32)* 溢出速率 

    溢出速率 = 计数速率 / (256-TH1初值) = fosc / [12 *(256-TH1初值)]    

     

    计数速率 = fosc / 12            (计数速率为震荡频率的12分频)

    溢出速率 = 1 / 溢出时间 = 1 / [(256 – TH1初值)* (12 / fosc)] = fosc / [12 *(256-TH1初值)]    

    计数速率 = 1 / 计数时间 = 1 / (12 / fosc) = fosc / 12

    方式0和方式2的波特率

    方式0中,每个机器周期发送或接收一位数据,因此波特率固定位震荡频率的1/12,与SMOD无关

    方式2中,波特率受PCON最高位SMOD控制,当SMOD=0时,波特率为震荡频率的1/64,当SMOD=1时,波特率加倍,变为震荡频率的1/32

    波特率 =(2^(smod)/64)* fosc

    方式1和方式3的波特率

    方式1和方式3的波特率由定时器T1的溢出率和SMOD位共同控制,其波特率可表示为

    波特率 = 定时器T1的溢出速率/N

    其中N为32或16,取决于PCON的最高位SMOD,当SMOD=0时,N=32,当SMOD=1时,N=16

    波特率 =(2^(smod)/32)* T1的溢出速率 

    其中,定时器的溢出率取决于计数速率和定时器的预置初值;计数速率与TMOD寄存器中的C/T的设置有关

    C/T为0时,为定时方式,计数速率为 fosc/12 ,C/T为1时,计数速率取决于外部输入时钟的频率,但不能超过震荡频率的24分频,即 fosc/24

    T1溢出率

    定时器溢出的频率,T1每溢出一次所需的时间T的倒数即为其溢出率

    若我们设定定时器T1每50ms溢出一次,那么其溢出率就为20Hz,再将20代入串口波特率计算公式中即可求出相应的波特率,当然也可根据波特率反推出定时器的溢出率,进而计算出定时器的初值

    通常单片机在通信时,波特率都较高,因此T1溢出率也必定很高,如果我们使用定时器1的工作方式1在中断中装初值的方法来求T1溢出率的话,在进入中断、装值、出中断这个过程中很容易产生时间上微小的误差,当多次操作时微小的误差不断累积,最终会产生错误

    有效的解决办法是——使用T1定时器的工作方式2,8位初值自动重装的8位定时器/计数器,定时器方式2逻辑结构图如图所示

    方式1中,当定时器计满溢出时,自动进入中断服务程序, 然后我们需要手动再次给定时器装初值;而在方式2中,当定时器计满溢出后,单片机会自动为其装初值,并且无须进入中断服务程序进行任何处理,这样定时器溢出的速率就会绝对稳定

    方式2的工作过程是:先设定TMOD的D4:M0、和D5:M1,选择定时器方式2(1、0),在THX中装入计算好的初值,启动定时器,然后由TLX寄存器作为8位计数器,在时钟的作用下开始加1计数,当TLX计满溢出后,CPU会自动将THX中的计数初值装入TLX中,继续计数——TH1中的数始终保持不变

    因此我们在启动定时器之前必须先将TLX和THX中装好合适的数值,以让定时器输出产生溢出,开始装入的TLX和THX中装的数值必须是一样的——因为每次计数溢出后TLX中装入的新值是从THX中取出的

     

    物联沃分享整理
    物联沃-IOTWORD物联网 » 单片机学习笔记:串行口和串行通信详解(上篇)

    发表评论