1、串行通信优点:便于长距离传送缺点:传送速度较慢,计算机与外界信息交换称为通信。,通信的基本方式可分为并行通信和串行通信:,并行通信是数据的各位同时发送或同时接收;,串行通信是数据的各位依次逐位发送或接收。,并行通信优点:传送速度快 缺点:不便长距离传送,并行通信:数据多位同时传送,控制简单,传输速度快,传输线较多,串行通信:数据字节一位一位在一条传输线上逐个传送。,传输线少,可利用电话网,但传送控制复杂。,异步通信对硬件要求较低,实现起来比较简单、灵活,适用于数据的随机发送/接收,但因每个字节都要建立一次同步,即每个字符都要额外附加两位,所以工作速度较低,在单片机中主要采用异步通信方式。,一、
2、异步通信和同步通信,串行通信按同步方式可分为异步通信和同步通信。,1、异步通信,异步通信依靠起始位、停止位保持通信同步。,异步通信数据传送按帧传输,一帧数据包含起始位、数据位、校验位和停止位。,异步通信是指通信的发送与接收设备使用各自的时钟控制数据的发送和接收过程。,同步通信传输速度较快,但要求有准确的时钟来实现收发双方的严格同步,对硬件要求较高,适用于成批数据传送。,2、 同步通信,同步通信依靠同步字符保持通信同步。,同步通信是由12个同步字符和多字节数据位组成,同步字符作为起始位以触发同步时钟开始发送或接收数据;多字节数据之间不允许有空隙,每位占用的时间相等;空闲位需发送同步字符。,波特率
3、的倒数即为每位传输所需的时间。相互通信的甲乙双方必须具有相同的波特率,否则无法成功地完成串行数据通信。 如每秒钟传送240个字符,而每个字符格式包含10位(1个起始位、1个停止位、8个数据位),这时的比特率为:10位240个/秒 = 2400 bps,二、串行通信波特率,波特率bps(bit per second)定义:每秒传输数据的位数,即:,1波特 = 1位/秒(1bps),三、串行通信的制式,串行通信按照数据传送方向可分为三种制式:,单工制式是指甲乙双方通信时只能单向传送数据,发送方和接收方固定。,1、单工制式(Simplex),半双工制式是指通信双方都具有发送器和接收器,既可发送也可接
4、收,但不能同时接收和发送,发送时不能接收,接收时不能发送。,2、半双工制式(Half Duplex),全双工制式是指通信双方均设有发送器和接收器,并且信道划分为发送信道和接收信道,因此全双工制式可实现甲乙双方同时发送和接收数据,发送时能接收,接收时也能发送。,3、全双工制式(Full Duplex),串行通信的目的不只是传送数据信息,更重要的是应确保准确无误地传送。因此必须考虑在通信过程中对数据差错进行校验,因为差错校验是保证准确无误地通信的关键。常用差错校验方法有奇偶校验、累加和校验以及循环冗余码校验等。,四、串行通信的校验,1、奇偶校验 在发送数据时,数据位尾随的1位为奇偶校验位(1或0)
5、。奇校验时,数据中“1”的个数与校验位“1”的个数之和应为奇数;偶校验时,数据中“1”的个数与校验位“1”的个数之和应为偶数。接收字符时,对“1”的个数进行校验,若发现不一致,则说明传输数据过程中出现了差错。,2. 累加和校验,累加和校验是指发送方将所发送的数据块求和,并将“校验和”附加到数据块末尾。接收方接收数据时也是先对数据块求和,将所得结果与发送方的“校验和”进行比较,若两者相同,表示传送正确,若不同则表示传送出了差错。“校验和”的加法运算可用逻辑加,也可用算术加。累加和校验的缺点是无法检验出字节或位序的错误。,3. 循环冗余码校验(CRC),循环冗余码校验的基本原理是将一个数据块看成一
6、个位数很长的二进制数,然后用一个特定的数去除它,将余数作校验码附在数据块之后一起发送。接收端收到该数据块和校验码后,进行同样的运算来校验传送是否出错。目前CRC已广泛用于数据存储和数据通信中,并在国际上形成规范,市面上已有不少现成的CRC软件算法。,80C51系列单片机有一个全双工的串行口,这个口既可以用于网络通信,也可以实现串行异步通信,还可以作为同步移位寄存器使用。,5.4.2 80C51串行口及控制寄存器,5.3.1串行口的基本组成,串行口的基本结构与操作方式,发送时,只需将发送数据输入SBUF,CPU将自动启动和完成串行数据的发送;接收时,CPU将自动把接收到的数据存入SBUF,用户只
7、需从SBUF中读出接收数据。,串行口特殊功能寄存器,1、串行数据缓冲器SBUF,在逻辑上只有一个,既表示发送寄存器,又表示接收寄存器,具有同一个单元地址99H,用同一寄存器名SBUF。在物理上有两个,一个是发送缓冲寄存器,另一个是接收缓冲寄存器。,2、串行控制寄存器SCON, SM0 SM1 串行口工作方式选择位。 SM2 多机通信控制位。 REN 允许接收控制位。REN=1,允许接收。 TB8 方式2和方式3中要发送的第9位数据。 RB8 方式2和方式3中要接收的第9位数据。 TI 发送中断标志。 RI 接收中断标志。,SCON 是一个特殊功能寄存器,用以设定串行口的工作方式、接收/发送控制
8、以及设置状态标志:,SM0、SM1:串行口工作方式选择位。用于选择四种工作方式,3、电源控制寄存器PCON,SMOD=1,串行口波特率加倍。PCON寄存器不能进行位寻址。,5.4.3 串行通信工作方式80C51串行通信共有4种工作方式,由串行控制寄存器SCON中SM0 SM1决定。1、串行工作方式0(同步移位寄存器工作方式)以RXD(P3.0)端作为数据移位的输入/输出端,以TXD(P3.1)端输出移位脉冲。移位数据的发送和接收以8位为一帧,不设起始位和停止位,无论输入/输出,均低位在前高位在后。波特率固定为fosc/12。,方式0可将串行输入输出数据转换成并行输入输出数据。, 数据发送,在移
9、位时钟脉冲(TXD)的控制下,数据从串行口RXD端逐位移入74HC164 SA、SB端。当8位数据全部移出后,SCON寄存器的TI位被自动置1。其后74HC164的内容即可并行输出。74HC164 CLR为清0端,输出时CLR必须为1,否则74HC164 Q0Q7输出为0。,串行口作为并行输出口使用时,要有“串入并出”的移位寄存器配合。,(2) 数据接收,串行口作为并行输入口使用时,要有“并入串出”的移位寄存器配合。,74HC165 S/L端为移位/置入端,当S/L=0时,从Q0Q7并行置入数据,当S/L=1时,允许从QH端移出数据。在80C51串行控制寄存器SCON中的REN=1时,TXD端
10、发出移位时钟脉冲,从RXD端串行输入8位数据。当接收到第8位数据D7后,置位中断标志RI,表示一帧数据接收完成。,【例1】串口方式0控制流水灯循环点亮,请编程实现,串口方式0应用举例,# include /包含特殊功能寄存器库 #include /包含函数_nop_()定义的头文件 sbit P1_7=P17; void main() unsigned char j; unsigned int i;SCON=0x00;j=0x01;for (; ;)P1_7=0;_nop_(); /延时一个机器周期_nop_(); /延时一个机器周期,保证清0完成P1_7=1;SBUF=j;while (!T
11、I) ;TI=0;for (i=0;i=30000;i+) ; /延时j=j*2;if (j=0x00) j=0x01; ,# include /包含特殊功能寄存器库 #include /包含函数_nop_()定义的头文件 sbit P1_7=P17; sbit CLK=P37 ; sbit DAT=P34; void main() unsigned char j; unsigned int i;j=0x01;P1_7=0;_nop_(); /延时一个机器周期_nop_(); /延时一个机器周期,保证清0完成P1_7=1;for (; ;)CLK=0;j=1; DAT=CY;CLK=1;for
12、 (i=0;i=19000;i+) if (j=0x00) j=0x01; ,串口方式0应用举例,通过串口读取串行数据的代码,#include #include #include #define INT8U unsigned char #define INT16U unsigned int sbit DAT = P30; /74HC165串行数据输入引脚 sbit CLK = P31; /74HC165移位时钟引脚 sbit SPL = P32; /Shift/Load void delay_ms(INT16U x) INT8U t; while(x-) for(t = 0; t 120; t
13、+); ,void main() SCON = 0x10; /设为串口模式0,允许串口接收while(1) SPL = 0; /置数(Load),读入并行输入口的8位数据SPL = 1; /移位(Shift),并口输入被封锁,串行转换开始while (RI = 0);/等待接收中断标志位被硬件置位RI = 0; /软件清0接收中断标志位P0 = SBUF; /接收到的字节显示在P0端口(与拨码开关对应)delay_ms(20); /延时 ,模拟时序串行读取1字节(高位优先),#include #include #include #define INT8U unsigned char #defi
14、ne INT16U unsigned intsbit DAT = P30; /74HC165串行数据输入引脚 sbit CLK = P31; /74HC165移位时钟引脚 sbit SPL = P32; /Shift/Load void delay_ms(INT16U x) INT8U t; while(x-) for(t = 0; t =1)if (DAT)d|=i ;CLK=0;CLK=1;return d;,void main() while(1) SPL=0; SPL=1; P0=Serial_Input(); delay_ms(20);,解决的方法只有调整单片机的时钟频率fosc,通
15、常采用11.0592MHz晶振。,波特率的计算,常用波特率通常按规范取1200、2400、4800、9600、,若采用晶振12MHz和6MHz,则计算得出的T1定时初值将不是一个整数,产生波特率误差而影响串行通信的同步性能。,在串行通信中,收发双方对发送或接收数据的速率要有约定。通过软件可对单片机串行口编程为四种工作方式,其中方式0和方式2的波特率是固定的,而方式1和方式3的波特率是可变的,由定时器T1的溢出率来决定。串行口的四种工作方式对应三种波特率。由于输入的移位时钟的来源不同,所以,各种方式的波特率计算公式也不相同。 方式0的波特率 = fosc/12 方式2的波特率 =(2SMOD/6
16、4) fosc 方式1的波特率 =(2SMOD/32)(T1溢出率) 方式3的波特率 =(2SMOD/32)(T1溢出率),串行口在不同的工作方式下。其波特率是不同的。在方式0时,每个机器周期发送或接收一位数据,因此波特率固定为fosc12。方式2的波特率也是固定的,其波特率2SMODfosc64,其中SMOD为波特率加倍位,它附设在电源控制寄存器PCON的最高位,可由软件编程选择。若SMOD0,波特率2SMODfosc64 = fosc64。若SMOD1,波特率2SMODfosc64 = fosc32。,波特率 T1溢出率,串行通讯的波特率设计,方式1和方式3的波特率可变,与定时器T1或T2
17、的溢出率有关。51子系列中常用定时器Tl作为波特率发生器,这时方式1和方式3的波特率由定时器T1的溢出率和SMOD确定如下:,其中T1溢出率就是T1定时器溢出的频率。定时时间的倒数就是它的溢出率,即T1溢出率取决于其计数速率和定时器的初值。通常采用T1的工作方式2,即自动重装载方式作为波特率发生器。,(256X),则串行口方式1或3的波特率:,实际应用中,通常是先确定波特率、再计算定时器T1的计数初值,然后进行T1的初始化。由上面波特率的计算公式,可求出定时器T1方式2的计数初值为:,T1溢出周期(定时时间)为:,T1的溢出率:,例5-1:选用定时器T1,工作方式2作波特率发生器,波特率为24
18、00波特。已知fosc11.0592MHz,求计数初值X。解:设波特率控制位SMOD0,不增倍时X256一(11.059210620)(3842400)0F4H,五、SMOD位及晶振频率对串行通讯波特率的影响可能产生误差选用各种常用波特率时,T1的工作方式、计数初值及对应fosc的选用值见表52。,当T1作为波特率发生器时,最典型的用法是使T1工作在自动再装入的8位定时器方式(即方式2,且TCON的TR1=1,以启动定时器)。这时溢出率取决于TH1中的计数值。T1 溢出率 = fosc /12256 (TH1)在单片机的应用中,常用的晶振频率为:12MHz和11.0592MHz。所以,选用的波
19、特率也相对固定。常用的串行口波特率以及各参数的关系如表所示。,2、串行工作方式1方式1是一帧10位的异步串行通信方式,包括1个起始位,8个数据位和一个停止位。其帧格式为:, 数据发送发送时只要将数据写入SBUF,在串行口由硬件自动加入起始位和停止位,构成一个完整的帧格式。然后在移位脉冲的作用下,由TXD端串行输出。一帧数据发送完毕,将SCON中的TI置1。 数据接收接收时,在REN=1前提下,当采样到RXD从1向0跳变状态时,就认定为已接收到起始位。随后在移位脉冲的控制下,将串行接收数据移入SBUF中。一帧数据接收完毕,将SCON中的RI置1,表示可以从SBUF取走接收到的一个字符。,方式一应
20、用举例,【例2】要求甲机P1口连接的八个开关控制乙机P1口连接的八个发光二极管的亮暗 ,请编程实现,1、串口方式1的设定-SCON 2、波特率的约定-9600b/s,如何设定定时器-TMOD,TH1,TL1,SMOD,解题思路:,#include /包含单片机寄存器的头文件 void main(void) TMOD=0x20; /定时器T1工作于方式2 SCON=0x40; /串口工作方式1PCON=0x00; /波特率9600TH1=0xfd; /根据规定给定时器T1赋初值TL1=0xfd; /根据规定给定时器T1赋初值TR1=1; /启动定时器T1 while(1)P1=0xff;SBUF
21、=P1;while(TI=0) ;TI=0; ,发送机程序如下:,#include void main(void) TMOD=0x20; /定时器T1工作于方式2 SCON=0x50; /串口工作方式1,允许接收(REN=1)PCON=0x00; /波特率9600TH1=0xfd; /根据规定给定时器T1赋初值TL1=0xfd; /根据规定给定时器T1赋初值 TR1=1; /启动定时器T1 REN=1; /允许接收while(1)while(RI=0) ; /等待,直至接收完毕 RI=0; /为了接收下一帧数据,需将RI清0P1=SBUF; ,接收机程序,【例3】设甲乙机以串行方式1进行数据传
22、送,fosc=11.0592MHz,波特率为1200b/s。甲机发送的16个数据存在内RAM单元中,乙机接收后存在内RAM 50H为首地址的区域中。,T1初值 = E8H,解: 串行方式1波特率取决于T1溢出率(设SMOD=0), 计算T1定时初值:,甲机发送程序如下: #include #define uchar unsigned char uchar idata buf16; uchar sum; uchar i; void main( ) TMOD=0x20; TL1=0xE8; TH1=0xE8; PCON=0x00; SCON=0x40;/工作在方式1 TR1=1;,for(i=0;
23、i16;i+) SBUF=bufi; while(TI= =0); TI=0; ,乙机接收程序如下: #include #define uchar unsigned char uchar sum; uchar i; void main( ) unsigned char *P; P=0x50; TMOD=0x20; TL1=0xE8; TH1=0xE8; PCON=0x00; SCON=0x50;/工作在方式1 TR1=1;,for(i=0;i16;i+) while(RI= =0);RI=0; *P =SBUF; /接收数据 P+; ,双机通信,#include #define uchar u
24、nsigned char #define uint unsigned int sbit LED1=P10; sbit LED2=P13; sbit K1=P17; uchar Operation_No=0; /操作代码 /数码管代码 uchar code DSY_CODE=0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90; /延时 void DelayMS(uint ms) uchar i;while(ms-) for(i=0;i120;i+); /向串口发送字符 void Putc_to_SerialPort(uchar c) SBUF=c;
25、while(TI=0);TI=0; ,void main() LED1=LED2=1;P0=0xbf;SCON=0x50; /串口模式1,允许接收TMOD=0x20; /T1工作模式2PCON=0x00; /波特率不倍增TH1=0xfd;TL1=0xfd;TI=RI=0;TR1=1;IE=0x90; /允许串口中断while(1)DelayMS(100);if(K1=0) /按下K1时选择操作代码0,1,2,3while(K1=0);Operation_No=(Operation_No+1)%4;switch(Operation_No) /根据操作代码发送A/B/C或停止发送case 0: P
26、utc_to_SerialPort(X);LED1=LED2=1;break;case 1: Putc_to_SerialPort(A);LED1=LED1;LED2=1;break;case 2: Putc_to_SerialPort(B);LED2=LED2;LED1=1;break;case 3: Putc_to_SerialPort(C);LED1=LED1;LED2=LED1;break; void Serial_INT() interrupt 4 if(RI)RI=0;if(SBUF=0 ,#include #define uchar unsigned char #define u
27、int unsigned int sbit LED1=P10; sbit LED2=P13; sbit K2=P17; uchar NumX=-1; /延时 void DelayMS(uint ms) uchar i;while(ms-) for(i=0;i120;i+); /主程序 void main() LED1=LED2=1;SCON=0x50; /串口模式1,允许接收TMOD=0x20; /T1工作模式2TH1=0xfd; /波特率9600TL1=0xfd;PCON=0x00; /波特率不倍增RI=TI=0;TR1=1;IE=0x90;while(1)DelayMS(100);if(K
28、2=0)while(K2=0);NumX=+NumX%11; /产生010范围内的数字,其中10表示关闭SBUF=NumX;while(TI=0);TI=0; void Serial_INT() interrupt 4 if(RI) /如收到则LED则动作RI=0;switch(SBUF) /根据所收到的不同命令字符完成不同动作case X: LED1=LED2=1;break; /全灭case A: LED1=0;LED2=1;break; /LED1亮case B: LED2=0;LED1=1;break; /LED2亮case C: LED1=LED2=0; /全亮 ,例4 设U1为甲机
29、发送,U2为乙机接收。试编程通过串行口将甲机上的一段流水灯控制码以方式1发送给乙机,乙机再利用该段控制码流水点亮其P1口的8位LED.,甲机发送程序: #include /包含单片机寄存器的头文件 unsigned char code Tab =0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F; /流水灯控制码,该数组被定义为全局变量 /* 函数功能:向PC发送一个字节数据 */ void Send(unsigned char dat) SBUF=dat;while(TI=0);TI=0; /* 函数功能:延时约150ms */void delay(void) u
30、nsigned char m,n;for(m=0;m200;m+)for(n=0;n250;n+);,void main(void) unsigned char i;TMOD=0x20; /定时器T1工作于方式2 SCON=0x40; /SCON=0100 0000B,串口工作方式1PCON=0x00; /PCON=0000 0000B,波特率9600TH1=0xfd; /根据规定给定时器T1赋初值TL1=0xfd; /根据规定给定时器T1赋初值TR1=1; /启动定时器T1 while(1)for(i=0;i8;i+) /模拟检测数据Send(Tabi); /发送数据idelay(); /5
31、0ms发送一次检测数据 ,乙机接收程序,#include /包含单片机寄存器的头文件 /* 函数功能:接收一个字节数据 */unsigned char receive(void) unsigned char dat; while(RI=0) ; RI=0; /为了接收下一帧数据,需将RI清0 dat=SBUF; /将接收缓冲器中的数据存于datreturn dat; ,void main(void) TMOD=0x20; /定时器T1工作于方式2 SCON=0x50; /串口工作方式1,允许接收 PCON=0x00; /波特率9600TH1=0xfd; /根据规定给定时器T1赋初值TL1=0x
32、fd; /根据规定给定时器T1赋初值 TR1=1; /启动定时器T1 REN=1; /允许接收while(1)P1=receive(); /收到的数据送P1口显示 ,方式2、3是一帧11位的串行通信方式,即1个起始位,8个数据位,1个可编程位TB8/RB8和1个停止位, 其帧格式为:,3、 串行工作方式2、方式3,可编程位TB8/RB8既可作奇偶校验位用,也可作控制位(多机通信)用,其功能由用户确定。,数据发送和接收与方式1基本相同,区别在于方式2把发送/接收到的第9位内容送入TB8/RB8。,方式2和方式3的工作原理类同,唯一的区别仅在于:方式2的波特率为fosc32 或 fosc64,而方
33、式3的波特率是可变的,取决于定时器Tl的溢出率。,1.发送过程发送前,先根据通信协议由软件设置SCON中的TB8。当CPU执行一条写入SBUF的指令后,便立即启动发送器开始发送。串行口能自动地将TB8装入到第9位数据位的位置,再逐一由TXD端发送出去 。发送完一帧信息时,置TI为1,请求中断。,2.接收过程当REN1时,若以下2个条件满足,将8位数据装入SBUF,第9位数据装入RB8并置位RI1。(1) RI0,意味着SBUF中的数据已被取走,缓冲器为空;(2) SM20或接收到的第9位数据位RB81时。,方式2和方式3的发送和接收过程:,#include /包含单片机寄存器的头文件 sbit
34、 p=PSW0; unsigned char code Tab =0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F; /流水灯控制码,该数组被定义为全局变量 /* 函数功能:向甲机发送一个字节数据 */ void Send(unsigned char dat) ACC=dat;TB8=p;SBUF=dat;while(TI=0);TI=0; ,例5 设U1为甲机发送,U2为乙机接收。试编程通过串行口将甲机上的一段流水灯控制码以方式3发送给乙机,乙机再利用该段控制码流水点亮其P1口的8位LED.加奇偶校验。,void delay(void) unsigned cha
35、r m,n;for(m=0;m200;m+)for(n=0;n250;n+); void main(void) unsigned char i;TMOD=0x20; /TMOD=0010 0000B,定时器T1工作于方式2 SCON=0xc0; /SCON=1100 0000B,串口工作方式3,/SM2置0,不使用多机通信,TB8置0PCON=0x00; /PCON=0000 0000B,波特率9600TH1=0xfd; /根据规定给定时器T1赋初值TL1=0xfd; /根据规定给定时器T1赋初值TR1=1; /启动定时器T1 while(1)for(i=0;i8;i+) /模拟检测数据Sen
36、d(Tabi); /发送数据idelay(); /50ms发送一次检测数据,解:接收程序如下:,#include sbit p=PSW0; unsigned char receive(void) unsigned char dat; while(RI=0) ; RI=0; ACC=SBUF; /将接收缓冲器中的数据存于datif(RB8=p)dat=ACC;return dat; ,void main(void) TMOD=0x20; /定时器T1工作于方式2 SCON=0xd0; /SCON=1101 0000B,串口工作方式3,允许接收(REN=1)PCON=0x00; /PCON=0000 0000B,波特率9600TH1=0xfd; /根据规定给定时器T1赋初值TL1=0xfd; /根据规定给定时器T1赋初值 TR1=1; /启动定时器T1 REN=1; /允许接收while(1)P1=receive(); /将接收到的数据送P1口显示 ,串行口四种工作方式的比较,四种工作方式的区别主要表现在帧格式及波特率两个方面。,四种工作方式比较,