200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > 51单片机(七)串行口通信

51单片机(七)串行口通信

时间:2020-12-09 16:53:52

相关推荐

51单片机(七)串行口通信

串行口通信

一、并行与串行通信1、并行通信2、串行通信3、并行通信和串行通信优缺点1)并行通信2)串行通信4、异步串行通信、同步串行通信1)异步串行通信2)异步串行通信的俩个指标——字符帧格式、波特率3)异步串行通信的常用总线类型4)异步串行通信的特点5)同步串行通信6)串行通信的奇偶校验二、MAX232实现RS232电平与TTL电平转换(板子嵌用)三、波特率与定时器初值1、波特率2、波特率计算3、溢出率、波特率、定时器综合分析4、定时器工作方式选择——工作方式2四、电源管理寄存器PCON与串行口控制寄存器SCON1、电源管理寄存器PCON(Power Control)2、串行口控制寄存器SCON(Serial Control)五、串行口方式1+面向编程1、收、发时序图2、实现流程六、经典例题

一、并行与串行通信

1、并行通信

将数据每一字节的各位用多条数据线同时进行传送。每个字节8位,由8条数据线同时传送一位,同一时间总共传送1个字节。除了8条数据线外,还有一条信号线和若干控制线。

由于发送设备和接收设备之间需要的接线较多,采用长途信号传送使得成本激增,所以并行通信一般用于短途通信。

2、串行通信

将数据的一个字节分成8位,一位一位的在一条传输线上传送,数据线只需要一条即可,此外还需一条公共信号地线和若干控制信号线。由于只需要一条数据线,在长途通信中成本不会很高,并且可以利用电话网等现有的设备。

3、并行通信和串行通信优缺点

1)并行通信

优点:控制简单,相对传输速度快

缺点:长距离传输时成本高,一个字节的8位同时发送和接收存在困难,较串行通信抗干扰能力弱

2)串行通信

优点:传输线少,长距离传输成本低,可利用现有设备进行传输,较并行通信抗干扰能力强

缺点:控制比较复杂,较并行通信控制更复杂

4、异步串行通信、同步串行通信

1)异步串行通信

通信的接收方、发送方使用各自的时钟控制数据的接收和发送。(为使双方收发协调,要求发送和接收设备的时钟尽可能一致)

2)异步串行通信的俩个指标——字符帧格式、波特率

异步串行通信中数据通常以字符或者字节为单位组成字符帧传送。字符帧在发送设备逐帧发送,接收设备逐帧接收。发送端和接收端由各自的时钟控制,俩个时钟互不影响、彼此独立。

字符与字符之间的间隔是任意的。任一字符内部的每一位之间的间隔是固定的。

波特率之后着重讲解

3)异步串行通信的常用总线类型

①RS-232

通常 RS-232 接口以9个引脚(DB-9) 或是25个引脚 (DB-25) 的型态出现

S232接口电平值较高,其任何一条信号线的电压均为负逻辑关系。即:逻辑“1”为-3V ~ -15V;逻辑“0”为+3V ~ +15V

RS232与TTL电平不兼容,故需要使用电平转换器才能让RS232与TTL电路连接。如MAX232把TTL电平从0V和5V转换到3V~15V或-3V ~ -15V

RS232传输距离较短,若距离过长,会导致信号失真、抗干扰能力较差。

②RS-485

在要求通信距离为几十米到上千米时,广泛采用RS-485串行总线。RS-485采用平衡发送和差分接收,因此具有抑制共模干扰的能力。加上总线收发器具有高灵敏度,能检测低至200mV的电压,故传输信号能在千米以外得到恢复。

RS-485采用半双工工作方式,所以收、发双方不能同时进行收和发,同一时间只有一方在发送、另一方在接收。

USB转RS485:

③USB(通用串行总线)

4)异步串行通信的特点

不要求收发双方时钟严格一致,实现容易,设备开销小,但每个字符需要附加2~3位用于起始位、校验位、停止位,各帧之间还有间隔,因此传输效率不高。

单片机与单片机、单片机与计算机之间的通信,都为异步串行通信方式

5)同步串行通信

要建立发送方时钟对接收方时钟的直接控制,使双方达到完全同步。此时,传输数据的位之间的距离均为“位间距”的整数倍,同时传送的字符间不留间隙即保持字符同步关系。

同步分为外同步和自同步。

外同步:

自同步:

6)串行通信的奇偶校验

发送数据时,在数据位后面尾随的一位是奇偶校验位。

奇校验时,数据中的1的个数+奇偶校验位中1的个数=奇数,若不为奇数,说明数据传输中出现错误。

偶校验时,数据中的1的个数+奇偶校验位中1的个数=偶数,若不为偶数,说明数据传输中出现错误

还想进一步了解的朋友可以去参考《通信原理》的【差错控制编码】——>【奇偶监督码】和【二维奇偶监督码】

二、MAX232实现RS232电平与TTL电平转换(板子嵌用)

中文参考手册:

单片机原理图:

图一可知:T1in与T2in为TTL电平输入,T1out、T2out为RS232输出。R1in与R2in为RS232电平输入,R1out与R2out为TTL电平输出。

所以MAX232可以将TTL电平转为RS232电平,也可以将RS232电平转为TTL电平

图二可知,单片机芯片P30接单片机R1out,为MAX232芯片的TTL电平输出引脚,单片机P31接T1in,为MAX芯片的TTL电平输入引脚。

信号流程:

单片机通过P31引脚发送信号,到MAX232的T1in引脚,经过转为,变为RS232电平,传输到其他设备,完成信号传送。

其他设备传送的信号,送入MAX232,进过转换,从R1out输出TTL电平,进入单片机P30引脚,单片机接收到其他设备的信号。

所以单片机P30是信号接收引脚,P31是信号发送引脚。

打开8051芯片,发现P30的确是接收引脚,P31的确是发送引脚。

再看MAX232的单片机原理图(上图二):

注:J1是焊接在板子上的接口,我的板子是公口,外插母口进行信号传送

J1的2引脚接R1in,为RS232电平的输入引脚,所以外接的母口的对应2引脚为其他设备的信号输出端。(指另一端设备备接口转换器的输出端)

J1的3引脚接T1out,为RS232电平的输出,所以J1的3引脚接外接母口的对应3引脚,接其他设备的输人端。(指另一端设备备接口转换器的输入端)

总结:

.

发送:单片机P31引脚——>MAX232的T1in引脚——>经转换在MAX232的T1out引脚输出——>J1公口的3引脚——>外插母口的3引脚——>其他设备的接口转换器输入端(若接口也为MAX232,则接R1in或R2in)

接收:其他设备的接口转换器输出端(若接口也为MAX232,则为T1out或T2out)——>外接母口引脚2——>本单片机J1的2引脚——>MAX232的R1in——>经转换后MAX232的R1out输出——>单片机P30引脚

三、波特率与定时器初值

之前总结异步串行通信的俩个指标——字符帧格式与波特率时,未对波特率进行总结,现总结波特率以及与定时器初值的关系

1、波特率

单片机或计算机在串口通信时的速率用波特率表示,它表示每秒传输二进制代码的位数,即1波特=X位/秒,单位是bps(位/秒)。如当异步串行传输包含1个起始位、1个停止位、8位数据位,每秒传输200个字符,则此时的波特率为10×200=2000bps。

《通信原理》中将传信率(又称比特率)Rb,表示传输的信息速率,单位是比特/秒,b/s或bps。传码率RB表示码元传输速率,单位为波特(Baud),简记B,有兴趣的朋友可以去了解一下。

2、波特率计算

在串行通信中,收发双方的波特率需要约定使用同一波特率。通过编程可对单片机串行口设定工作方式,从而指定波特率。

四种工作方式的波特率:

①方式0:fosc/12

②方式1:(2SMOD/32)×(T1溢出率)

③方式2:(2SMOD/64)×fosc

④方式3:(2SMOD/32)×(T1溢出率)

可以看出只有方式1的波特率是固定的

上述式子中,fosc为系统时钟频率,一般为12MHZ或者11.0592MHZ(我的板子是11.0592MHZ)。SMOD是电源管理寄存器PCON的最高位(接下来总结)

T1溢出率即定时器T1溢出的频率,即1s溢出多少次,如之前总结《(四)定时器中断》时,设置为每50ms溢出一次(和寄存器装载的初值有关系),则1s溢出20次,溢出率为20HZ。

方式0的波特率为系统晶振的12分频,之前总结的+1计数器的时钟来源之一就是系统时钟的12分频。

一般情况下,都是用方式1,其他几种方式几乎不会用。

3、溢出率、波特率、定时器综合分析

由上面的工作方式0、1、2、3的波特率计算公式可以得出工作方式1、3与计数器T1的溢出率有关系,由于实际应用中,常见的是工作方式1,现以工作方式1为例来分析。

单片机通信时,一般需要很高的波特率,如常见的9600波特率,可以先选定通信的波特率,然后再求T1溢出率,而1/(T1溢出率)为T1定时器每中断溢出的时间Xms。通过以下公式:

TH1=(65536-X)/256

TL1=(65536-X)%256

可以得出定时器的装载初值。这样,定时器中断的初值、溢出率、波特率都已解决。

51单片机只能通过这种方式规定波特率,不像Arduino、openMV这些单片机,可以在程序中直接指定波特率。

4、定时器工作方式选择——工作方式2

通信的波特率很大——>T1溢出率很大——>定时器1的中断间隔很小——>定时器装载初值很大。因为中断间隔很小,若采用之前的定时器1工作方式1,每次中断都需要软件重新装载初值,执行装载初值语句会浪费一定的时间并且不太稳定,所以定时器的工作方式1在这里不合适。采用定时器的工作方式2,使用8位初值自动装载计数器/定时器,进入中断服务函数后,无需进行任何操作,使定时器溢出速率变得绝对稳定。

使用工作方式2的8位自动重装载计数器/定时器1时,初值的计算公式也发生了变化,以波特率9600为例:(要区分定时器工作方式2和串口工作方式1)

①SMOD=0、12MHZ晶振

串口工作方式1的波特率:9600bps

SMOD=0(波特率不加倍)

T1溢出率=9600×32=307200HZ

中断间隔:1/307200=3255ms≈3.26us(即每3.26us中断一次)

12MHZ晶振的一个机器周期1us(即每计一次数1us)

每计3个数为3us

所以每计三个数中断一次,初值:256-3=253

②SMOD=1、12MHZ晶振

串口工作方式1的波特率:9600bps

SMOD=1(波特率加倍)

T1溢出率=9600×16=153600HZ

中断间隔:1/153600≈6.5us(即每6.5us中断一次)

12MHZ晶振的一个机器周期1us(即每计一次数1us)

每计5个数为5us

所以每计三个数中断一次,初值:256-5=251

12MHZ晶振时有很大误差,毕竟9600波特率是针对11.0592MHZ晶振的

③SMOD=0、11.0592MHZ晶振

串口工作方式1的波特率:9600bps

SMOD=0(波特率不加倍)

T1溢出率=9600×32=307200HZ

中断间隔:1/307200=3255ms≈3.26us(即每3.26us中断一次)

11.0592MHZ晶振的一个机器周期1.085us(即每计一次数1us)

3.26÷1.085=3

所以每计三个数中断一次,初值:256-3=253

④SMOD=1、12MHZ晶振

串口工作方式1的波特率:9600bps

SMOD=1(波特率加倍)

T1溢出率=9600×16=153600HZ

中断间隔:1/153600≈6.5us(即每6.5us中断一次)

11.0592MHZ晶振的一个机器周期1.085us(即每计一次数1us)

6.5÷1.085=6

所以每计三个数中断一次,初值:256-6=250

以上四个计算为了回顾之前博客总结的定时器内容,步骤都分开处理,使得中间公式产生约等于,导致最后结果有一点点误差,若省去中间公式,直接一个合公式导出初值,发现11.0592MHZ晶振时,SMOD=0,定时器初值为253,SMOD=1,定时器初值为250,没有误差。

常见波特率:

串口通信的波特率不能太大,否则会超过定时器的最短溢出时间,比如115200波特率就不能使用11.0592MHZ的晶振的串口通信。也正是为了使波特率为标准通信速率时计数器/定时器初值都为整数,才选用11.0592MHZ的晶振。

四、电源管理寄存器PCON与串行口控制寄存器SCON

1、电源管理寄存器PCON(Power Control)

电源管理寄存器用来管理单片机的电源部分,包括上电复位检测、掉电模式、空闲模式等,单片机复位时PCON全部清0。

电源管理寄存器:

D7——SMOD与波特率有关。SMOD=0:串口方式1、2、3波特率正常;SMOD=1,:串口方式1、2、3波特率加倍。(只需记D7位)

D6——(SMOD0):与SCON寄存器的SM0有关,为帧错误检测有效控制位,当SMOD0=1,SCON寄存器中的SM0/FE位用于FE(帧错误检测)功能;SMOD0=0,SCON寄存器中的SM0/FE位用于SM0功能,和SM1一起指定串行口的工作方式。单片机复位时SMOD0=0;

D5——(LVDF):无效

D4——(POF):上电复位标志,单片机停电后,上电复位标志为1,可由软件清零。

察看STC89C52技术手册(了解即可):

D3——GF1、D2——GF0:俩个通用工作标志位,用户可以自由使用。

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

D0——IDL:空闲模式设定位,IDL=0:单片机处于正常工作状态;IDL=1:单片机进入空闲(Idle)模式,除CPU不工作外,其余仍继续工作,在空闲模式下可由任一个中断或者硬件复位唤醒。

打开52的头文件:

定义了PCON寄存器

但是PCON寄存器的每一位没有通过sbit进行位定义,所以程序中只能对寄存器操作,而不能操作单独某一位。

若波特率不加倍,SMOD=0,程序:

PCON=0; //00000000

或者不用写上述语句,单片机上电后,PCON每一位都清零,默认SMOD=0。

若波特率加倍,SMOD=1,程序:

PCON=0x80; //10000000

2、串行口控制寄存器SCON(Serial Control)

51单片机的串行口是可编程全双工的通信接口,具有UART(通用异步收发器)的全部功能

51单片机的串行口组成:俩个串行数据缓冲寄存器SBUF(一个发送缓冲寄存器,一个接收缓冲寄存器)、发送控制器、接收控制器、输入移位寄存器及若干控制门电路组成

俩个SUBF数据缓冲寄存器共用一个地址,当执行写指令时,访问发送缓冲寄存器;当执行读指令时访问接收缓冲寄存器。从接收缓冲寄存器中读数据时,前一个字节还没有完全读出,就可以接收下一个字节,若第一个字节还没读出,下一个字节已经接收完毕,则会丢失第一个字节。

D7——SM0:工作方式选择位

D6——SM1:工作方式选择位

SM0、SM1设置串行口工作方式:

D5——SM2多机通信控制位,主要用于方式2、3,暂时不用

D4——REN——运行串行接收位,REN=1:运行串行口接收数据;REN=0:禁止串行口接收数据

D3——TB8:方式2、3中发送数据的第9位(暂时不用)

D2——RB8:方式2、3中接收数据的第9位(暂时不用),在方式1时,若SM2=0则接收数据时,停止位进RB8。

D1——TI:发送中断标志位,在串行工作方式0时,当发送第8位结束时,或在其他方式,串行发送停止位开始时,由内部硬件使TI置1,向CPU发出中断申请。在中断服务程序中,必须用软件将其清0,取消此中断申请。

D0——RI:接收中断标志位,当串行工作方式0时接收第8位数据结束,或在其他方式,串行接收停止位开始时,由内部硬件使RI值1,向CPU发出中断申请,在中断服务程序中,必须用软件将其清0,取消此中断申请。

打开52头文件:

可以看到SCON和SBUF寄存器都已经定义

SCON的每一位都已经定义,可以对每一位单独操作。

五、串行口方式1+面向编程

1、收、发时序图

串行口方式1一帧数据共10位,1位起始位、8位数据位、1位停止位(起始位为0,终止位为1)

方式1数据发送时序图:

当数据写入SBUF后,单片机开始发送数据,起始位(0)、8位数据位、停止位(1)等10位数据依次发送,当发送停止位开始时,由内部硬件使TI置1,向CPU发出中断申请。在中断服务程序中,可以软件将其清0,取消此中断申请,也可以不清零,停止数据输出。

方式1数据接收时序图:

首先需要串口接收允许,即REN=1(软件置1),当检测到RXD的电平发生负跳变,表示起始位已经开始,将其移入输入移位寄存器,并开始接收一帧的其他位(8位数据位、1位停止位),当接收到停止位时,将刚刚接收到的9位数据的前8位(即8位数据位)送入接收SBUF中,第9位(即停止位)进RB8(前提是SCON寄存器的SM2=0,之前总结过),并且RI=1,向CPU请求中断。

2、实现流程

①确定定时器T1的工作方式(TMOD寄存器)

T1计数器,所以低4位为0,高四位中,GATE=0,表示定时器开、关只收TR1控制;C/T=0,表示定时器;M1M0=10,表示工作方式2,8位自动重装载寄存器

所以程序:

TMOD=0x20;

②计算T1计数器的初值,转载TH1、TL1;

前面第三部分总结过9600波特率时初值的方法,其他波特率计算方法相似。得出11.0592MHZ晶振波特率为9600,SMOD=0时初值为253,SMOD=1时初值为250。

253——>11111101B——>0xfd

250——>11111010B——>0xfa

因为是八位寄存器,所以TH1和TL1只用到一个(不清楚用到哪个寄存器),TH1与TL1赋同样值就好了

TH1=0xfd; //9600波特率 11.0592MHZTL1=0xfd;

这里不妨算一下串口通信的最大波特率,即当+1计数器每+1就中断,根据第三部分的计算方法:

当SMOD=0时

11059200/(X×32×12)=1,解之得:X=28800bps

当SMOD=1时

11059200/(X×16×12)=1,解之得:X=57600bps

通过上述方法,可以得出可用的波特率(51全部可用波特率【全】)如下程序:

/* //11.0592MHZ晶振下//C51通用波特率配置定时器初值和PCON寄存器TH1=0xff; //SMOD=0 28800bpsTL1=0xff; //SMOD=1 57600bpsTH1=0xfe; //SMOD=0 14400bpsTL1=0xfe; //SMOD=1 28800bpsTH1=0xfd; //SMOD=0 9600bpsTL1=0xfd;//SMOD=1 19200bpsTH1=0xfa;//SMOD=0 4800bpsTL1=0xfa;//SMOD=1 9600bpsTH1=0xf4;//SMOD=0 2400bpsTL1=0xf4;//SMOD=1 4800bpsTH1=0xe8;//SMOD=0 1200bpsTL1=0xe8;//SMOD=1 2400bps*/

③启动T1计数器(TCON的TR1软件置1)

当然启动T1之前需要打开全局中断允许位,即EA

=1;打开串口中断允许位,即ES=1;

EA=1//打开全局中断允许ES=1;//打开串口中断允许位TR1=1;//打开定时器1

④确定串行口工作方式(SCON寄存器)

一般为工作方式1,即SM0=0;SM1=1;

⑤中断设置(发生中断后,需要处理什么?)

六、经典例题

例1:

在上位机(上位机为电脑端,下位机为单片机)上用串口调试助手发送一个字符X,单片机收到后返回上位机“I get X”,串口波特率为9600bps

分析:

①确定T1计数器工作方式

TMOD=0x20;//工作方式2

②确定T1的初值

TH1=0xfd;//SMOD=0TL1=0xfd;

③T1中断器配置

EA=1;//打开全局中断允许ES=1;//打开定时器1中断允许TR1=1;//启动定时器

④确定串口工作方式

SM0=0;SM1=1;//工作方式1REN=1;//允许串行口接收数据

完整程序:

#include <reg52.h>#define uchar unsigned char#define uint unsigned intuchar flag,a,i;uchar code table[]="I get ";void main(){TMOD=0x20;//工作方式2TH1=0xfd;//SMOD=0TL1=0xfd;EA=1;//打开全局中断允许ES=1;//打开串口中断允许位TR1=1;//启动定时器SM0=0;SM1=1;//工作方式1REN=1;//允许串行口接收数据while(1){if(flag==1)//表示接收缓冲区有数据{ES=0;//关闭串口中断,防止下次中断打断这次传送for(i=0;i<6;i++)//table数组里的字符串末尾还有一个空格{SBUF=table[i];//单片机发送消息while(!TI);//等待传送完成TI=0;//一位一位的传送,分6次传送,每次传送完成T1都需软件置0}SBUF=a;while(!TI);//等待传送完成TI=0;ES=1;flag=0;}}}//注意是全双工,即同时收发,只要数据写入SBUF,单片机就开始传送数据void serial() interrupt 4//串行口中断,无论接收到数据还是发生数据,都调用{RI=0;//接收数据完毕后发生中断,此时RI硬件置1,需在服务函数中软件置0a=SBUF;flag=1;//标志接收缓冲寄存器接收到一帧的数据}

打开单片机的供电电路,发现单片机的引脚TXD与RXD即P31与P30接了USB接口,所以直接使用下载/供电的USB接口即可传送信号。当然也可以使用板子上的RS232接口,不过需要一个RS232转USB接电脑的USB接口。

下载完程序后,打开串口助手

输入任何字符:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。