1、单片机原理及应用 (第九章 串行通信技术),教学内容,串行通信概述 串行通信接口的结构 串行通信接口的控制 串行通信接口的编程,DATE: 2019/3/9,PAGE: 2,一、串行通信概述,计算机与外界的信息传输常被称为通信,基本通信方式有并行通信和串行通信两种。 并行通信方式指数据的各个二进制位在不同的数据线上同时传输。并行通信传输速度快,效率高,但所需的数据线多,成本高,抗干扰能力较差,适用于近距离传输。 串行通信方式指将数据拆分成多个二进制位,逐一的在同一条数据线上输出。串行通信虽然传输速度较慢,效率较低,但所需的数据线少、硬件电路简单、抗干扰能力强,且适用于远距离数据传输。,DATE
2、: 2019/3/9,PAGE: 3,一、串行通信概述,串行通信有同步通信和异步通信两种基本的通信方式。(1)同步通信同步通信是一种连续的串行传输数据的通信方式,待发送的若干个字符数据构成一个数据块,在该数据块前部添加12个同步字符,在数据块的末尾添加校验信息,以此种方式构成数据帧,以数据帧为单位进行串行通信。通信时,发送方首先发送同步字符,之后紧跟数据块,最后是校验字符。接收方在检测到同步字符后,开始逐个接收数据,直到把所有数据接收完毕,最后进行校验。,DATE: 2019/3/9,PAGE: 4,一、串行通信概述,(2)异步通信每个字符数据被封装成帧,以帧的形式发送。每一帧由四部分构成,分
3、别是起始位、数据位、校验位和停止位。起始位是数据开始传送的标志,用逻辑0表示;数据位紧跟起始位,通常是58位二进制位;校验位用于校验数据位是否发送正确,可以选择奇校验、偶校验或者不使用校验位。帧和帧之间可以连续,或者加入任意的空闲位,空闲位用逻辑1表示。,DATE: 2019/3/9,PAGE: 5,一、串行通信概述,串行通信的方向按照数据传送方向,串行通信可以分为三个种类,分别是单工、半双工和全双工。 单工:通信双方一方固定为发送方,另一方固定为接收方,数据只能是单行传输; 半双工:通信双方只使用一根数据线,每一方都有发送器和接收器,可以在两个方向上传送,但通信双方不能同时接收或发送数据,只
4、能交替进行; 全双工:通信双方使用两根数据线,分别用于不同方向的数据传输,通信双方能够同时收发数据。,DATE: 2019/3/9,PAGE: 6,一、串行通信概述,波特率 波特率是数据传输速率,指每秒钟传送二进制位的个数,单位为bit/s。 波特率是串行通信的重要指标,波特率越高,串口数据传输速度越快。 假如设定波特率为9600bit/s,而数据帧由1位起始位、8位数据位、1位停止位构成,则串口每秒钟最多传送9600/(1+8+1)=960个字节。,DATE: 2019/3/9,PAGE: 7,二、存储器扩展,RS-232C串口 计算机广泛使用DB9接口连接,DB9串口及其引脚定义如下:双机
5、近距离串口通信时,可以采用简单的三线式连接,连线方式如右图所示。,DATE: 2019/3/9,PAGE: 8,一、串行通信概述,单片机与PC机串口连接:由于RS-232C和单片机的电气标准不统一,当单片机通过串口方式与PC机通信时通常采用MAX3232等专用芯片实现两种电平的转换,连接方式如下 :,DATE: 2019/3/9,PAGE: 9,二、串行通信接口的结构,8051单片机串行通信接口的结构8051单片机的串行口主要由数据发送缓冲器SBUF、发送控制器、输出控制门、数据接收缓冲器SBUF、接收控制器、输入移位寄存器、串行口控制寄存器SCON构成。,DATE: 2019/3/9,PAG
6、E: 10,二、串行通信接口的结构,串行通信接口的结构 发送缓冲器SBUF和接收缓冲器SBUF共用同一个地址0x99,发送SBUF只能写入而不能读出,接收SBUF只能读出不能写入。 CPU将数据写入SBUF中便启动发送,数据送引脚TXD被外设接收。 数据从引脚RXD上接入到数据移位寄存器中,一帧接收完毕后再被自动送入SBUF中,CPU读取SBUF,便完成一次串口接收。,DATE: 2019/3/9,PAGE: 11,三、串行通信接口的控制,串行控制寄存器SCONSCON用于设定串口通信的工作方式、接收/发送控制以及串口工作状态指示。SCON的字节地址为0x98,可以进行位寻址,格式如下:SCO
7、N各位的意义如下: SM0、SM1:串行通信工作方式选择位。SM0和SM1共4种组合,对应4中工作方式,如下表所示,其中fosc为晶振频率。,DATE: 2019/3/9,PAGE: 12,三、串行通信接口的控制,SM2:多机通信控制位,主要用于工作方式2和工作方式3。当串行口在多机通信模式下接收数据时: 当SM2=0时,将接收到的8位数据送入到SBUF中,并产生中断请求。 若设置SM2=1,且RB8为0时,不接收主机发来的数据。 如果不是多机通信,一般将SM2设为0。,DATE: 2019/3/9,PAGE: 13,三、串行通信接口的控制,REN:串行口接收允许控制位。REN=1时,允许串行
8、口接收数据;REN=0时,禁止串行口接收数据。 TB8:在方式2和方式3下,该位为发送数据的第9位,根据需要由软件置1或清0,该位可用作奇偶校验位,还可以作为区别地址帧或数据帧的标志位,一般约定地址帧时该位为1,数据帧时该位为0。在方式0和方式1下,该位不使用。 RB8:在方式2和方式3下,该位为接收数据的第9位,可以作为奇偶校验位,或者用于区分接收的是数据帧还是地址帧。 TI:串行口发送中断标志位。在方式0下,发送完8位数据后由硬件置1,并申请中断;在其他方式下,在停止位开始发送之前由硬件置1,并申请中断。TI必须用软件清0。 RI:串行口接收中断标志位。在方式0下,接收完8位数据后由硬件置
9、1;在其他方式下,在接收到停止位时由硬件置1。RI必须用软件清0。,DATE: 2019/3/9,PAGE: 14,三、串行通信接口的控制,电源管理寄存器PCON PCON用来管理单片机的电源部分,包括上电复位检测、掉电模式、空闲模式等,PCON不可以位寻址,单片机复位时PCON全部被清0。PCON中与串口通信有关的是最高位D7,用于设置串行口波特率是否加倍,如下图所示。当SMOD=1时,方式1、2、3的波特率加倍; 当SMOD=0时,方式1、2、3的波特率不变。,DATE: 2019/3/9,PAGE: 15,三、串行通信接口的控制,串行口工作方式 1.串行口工作方式0方式0下,为8位同步移
10、位寄存器方式。波特率固定为fosc/12,以8位数据为一帧,不设起始位和停止位。 方式0发送CPU将待发送的数据写入到SBUF后,单片机自动将数据从RXD引脚输出,同步信号通过TXD引脚输出。发送数据完毕后,TI位被硬件自动置1。启动下一次发送前,TI位必须通过软件清0。 方式0接收在REN=1和RI=0的前提下允许串行口输入。串行数据通过RXD引脚一位一位接收,并被移入到SBUF中,同步信号通过TXD引脚输出。当8位数据接收完毕后,RI被硬件自动置1,CPU读取SBUF后必须通过软件将RI清0才可以进行下次接收。,DATE: 2019/3/9,PAGE: 16,三、串行通信接口的控制,串行口
11、工作方式1 串行口工作方式1为8位异步通信方式,数据帧格式为1位起始位、8位数据位、1位停止位,共10位。波特率由定时器T1溢出率决定。 方式1发送CPU将待发送的数据写入SBUF后,单片机自动将数据位从TXD引脚输出。当数据发送完毕后,硬件自动使TI置1。启动下一次发送前,TI位必须软件清0。 方式1接收REN=1时允许串口输入。数据位从RXD引脚输入,并被移入到SBUF中,当一帧数据接收完毕后,硬件自动使RI置1,CPU读取SBUF后必须将RI软件清0才可以进行下次接收。,DATE: 2019/3/9,PAGE: 17,三、串行通信接口的控制,串行口工作方式2串行口工作方式2为9位异步通信
12、方式,数据帧格式为1位起始位、8位数据位、1位控制/校验位、1位停止位,共11位。波特率为fosc/32或fosc/64。 方式2发送将要发送的数据写入到SBUF,并通过SCON中的TB8设置数据的奇偶校验。数据位从TXD引脚输出。当数据发送完毕后,硬件自动使TI置1。启动下一次发送前,TI位必须清0。 方式2接收方式2的接收过程与方式1类似,当RI=0且接收数据的第9位为1,或者RI=0且SM2=0时,前8位数据被移入到SBUF中,第9位数据被送入到SCON的RB8位,硬件自动使RI置1,CPU读取SBUF后必须将RI清0才可以进行下次接收。,DATE: 2019/3/9,PAGE: 18,
13、三、串行通信接口的控制,串行口工作方式3串行口工作方式3的波特率可变,取决于定时器T1的溢出率,除此之外与方式2相同。 方式1和方式3下波特率的设定方式1和方式3下,波特率是可变的,由定时器T1的溢出率控制。定时器T1用作波特率发生器时,通常选择工作方式2,即8位初值自动重装载方式。常用的波特率与定时器T1的初值关系见下表:,DATE: 2019/3/9,PAGE: 19,四、串行通信接口的编程,串行通信接口的编程 在使用串口收发数据之前,需要对串口相关的特殊功能寄存器进行初始化设置,其内容包括以下两个方面: 1、初始化: (1)串口工作模式SCON设置需要设置SM0和SM1选择串行口工作方式
14、,多机通信时还需要设置SM2。此外,如果需要串口接收数据,则必须设置REN为1。 (2)设置波特率对于方式0,不需要设置波特率。对于方式2,可以通过设置PCON中的SMOD位选择波特率为fosc/32或fosc/64。对于方式1和方式3,波特率设置通过定时器T1的工作方式2实现。设置波特率时,需要设置TMOD寄存器,使定时器T1工作于方式2,并需要根据波特率的值查表设置定时器T1的初值寄存器TH1和TL1。另外还需要设置PCON中的SMOD位,以决定波特率是否加倍。(3)如需中断,开总中断和串行中断,DATE: 2019/3/9,PAGE: 20,四、串行通信接口的编程,2、奇偶校验: 对于方
15、式2和方式3,需要有奇偶校验。 偶校验:发送/接收的8个数据位的1的个数为偶数时,TB8=0/ RB8=0;为奇数时,TB8=1/ RB8=1; 奇校验:发送/接收的8个数据位的1的个数为奇数时,TB8=0/RB8=0;为偶数时,TB8=1/ RB8=1; 用软件产生奇偶校验位是根据51系列单片机的状态寄存器PSW的定义:当累加器ACC中为1的个数为奇数时,P=1,否则P=0,因此在校验之前需要先将数据送入累加器ACC计算1的个数,以决定P值,然后将P值装入TB8位,与数据一起发送出去供接收方校验。默认是偶校验,如果需要改成奇校验,则在发送方需要将P值取反后再装入TB8,在接收方校验时需将RB
16、8中的值取反再与P值进行比较。,DATE: 2019/3/9,PAGE: 21,四、串行通信接口的编程,例9-1 下图是单片机8051与8位并入串出接口芯片74LS165的接口电路。使用串行口工作方式0,编程实现单片机从74LS165读取8位开关状态,并送P1口上的八个LED显示。,DATE: 2019/3/9,PAGE: 22,四、串行通信接口的编程,#include sbit P37=P37; int main(void) EA=1; /开总中断ES=1;/开串行中断SCON=0x10;/设置串口工作于方式0,允许接收数据while(1) P37=0; /锁存数据 P37=1; /允许传送
17、数据 REN=1; /允许接收 while(REN);/等待传送完成 ,DATE: 2019/3/9,PAGE: 23,四、串行通信接口的编程,void Recive() interrupt 4/串行中断程序REN=0; /禁止接收数据P1=SBUF;/显示数据RI=0;/允许再次中断,DATE: 2019/3/9,PAGE: 24,四、串行通信接口的编程,例9-2 下图是单片机与8位的串入并出接口芯片74LS164的接口电路。使用串行口工作方式0,编程实现单片机发送串行数据到74LS165控制八个LED进行流水灯显示。,DATE: 2019/3/9,PAGE: 25,四、串行通信接口的编程,
18、#include unsigned char code Tab=0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F;/流水灯码 sbit P20=P20; void delay(void) unsigned char m,n;for(m=0;m200;m+)for(n=0;n200;n+);,DATE: 2019/3/9,PAGE: 26,四、串行通信接口的编程,void Sendchar(unsigned char dat)/发送字节函数 unsigned char i=10;P20=0; /对74LS164清0while(i-); /延时,保证清0完成P20=1
19、; /结束清0SBUF=dat; /将字节写入发送缓冲器发送while(!TI); /等待发送完成 TI=0; /将TI复位 ,DATE: 2019/3/9,PAGE: 27,四、串行通信接口的编程,void main(void)unsigned char i;SCON=0x00; /串行口工作于方式0 while(1) for(i=0;i8;i+)Sendchar(Tabi);/发送数据delay(); /延时,DATE: 2019/3/9,PAGE: 28,四、串行通信接口的编程,例9-3 下图是单片机与单片机之间基于方式1串行单工通信的接口电路。使用单片机U1通过串行口TXD将数码管字型
20、码以方式1发送至单片机U2的RXD,U2根据字型码控制P1口的数码管循环显示09数字。,DATE: 2019/3/9,PAGE: 29,四、串行通信接口的编程,#include /包含单片机寄存器的头文件 unsigned char led=0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90;/字型码 void Sendchar(unsigned char dat)/发送数据函数 SBUF=dat;while(!TI);TI=0; ,DATE: 2019/3/9,PAGE: 30,四、串行通信接口的编程,int main(void) unsign
21、ed char i;int n=10000;TMOD=0x20; /TMOD=0010 0000B,定时器T1工作于方式2 SCON=0x40; /SCON=0100 0000B,串口工作方式1PCON=0x00; /TMOD=0,波特率不加倍TH1=0xfd; /T1赋初值,波特率9600TL1=0xfd; /T1赋初值TR1=1; /启动定时器T1 while(1)for(i=0;i10;i+) /Sendchar(ledi);/发送数据for(n=0;n30000;n+);/延时一段时间再发送 ,DATE: 2019/3/9,PAGE: 31,四、串行通信接口的编程,(2)单片机U2的数
22、据接收程序 #include /包含单片机寄存器的头文件unsigned char Receivechar(void) unsigned char dat;while(!RI); /等待接收完毕RI=0; /将RI复位,使数据有效dat=SBUF; return dat; ,DATE: 2019/3/9,PAGE: 32,四、串行通信接口的编程,void main(void) TMOD=0x20; /定时器T1工作于方式2 SCON=0x50; /SCON=0101 0000B,串口工作方式1,允许接收(REN=1)PCON=0x00; /SMOD=0,波特率不加倍TH1=0xfd; /T1赋
23、初值TL1=0xfd; /T1赋初值 TR1=1; /启动定时器T1 REN=1; /允许接收while(1)P0=Receivechar(); /数据显示 ,DATE: 2019/3/9,PAGE: 33,四、串行通信接口的编程,例9-4 编程实现用单片机U1通过串行口TXD将数码管字型码以方式3发送至单片机U2的RXD,U2根据字型码控制P1口的数码管循环显示09数字。,DATE: 2019/3/9,PAGE: 34,四、串行通信接口的编程,(1)单片机U1数据发送程序 #include /包含单片机寄存器的头文件 unsigned char led=0xC0,0xF9,0xA4,0xB0
24、,0x99,0x92,0x82,0xF8,0x80,0x90;/字型码 void Sendchar(unsigned char dat)/发送数据函数 ACC=dat;/数据装入累加器计算P值,奇数时P为1,偶数时P为0TB8=P;/P值装入校验位TB8SBUF=dat;/数据发送,串口自动将校验位装入while(!TI); TI=0; ,DATE: 2019/3/9,PAGE: 35,四、串行通信接口的编程,int main(void) unsigned char i;int n=10000;TMOD=0x20; /TMOD=0010 0000B,定时器T1工作于方式2 SCON=0xc0;
25、 /SCON=1100 0000B,串口工作方式1PCON=0x00; /TMOD=0,波特率不加倍TH1=0xfd; /T1赋初值,波特率9600TL1=0xfd; /T1赋初值TR1=1; /启动定时器T1 while(1)for(i=0;i10;i+) /Sendchar(ledi);/发送数据for(n=0;n30000;n+);/延时一段时间再发送 ,DATE: 2019/3/9,PAGE: 36,四、串行通信接口的编程,(2)单片机U2数据接收程序 #include /包含单片机寄存器的头文件unsigned char Receivechar(void) unsigned char
26、 dat;while(!RI); /等待接收完毕RI=0; /将RI复位,使数据有效ACC=SBUF; /数据送累加器计算p值,奇数时P为1,偶数时P为0if(RB8=P)/校验,1奇偶个数与发送的相同,则数据有效dat=ACC;return dat;elsereturn 0xFF; ,DATE: 2019/3/9,PAGE: 37,四、串行通信接口的编程,void main(void) TMOD=0x20; /定时器T1工作于方式2 SCON=0xd0; /SCON=1101 0000B,串口工作方式3,允许接收(REN=1)PCON=0x00; /SMOD=0,波特率不加倍TH1=0xfd
27、; /T1赋初值TL1=0xfd; /T1赋初值 TR1=1; /启动定时器T1 while(1)P1=Receivechar(); /数据显示 ,DATE: 2019/3/9,PAGE: 38,四、串行通信接口的编程,例9-5 编写控制程序,实现单片机和PC机串口通信,分别采用查询方式和中断方式接收PC机发送的字符并且将该字符再发送回去。,DATE: 2019/3/9,PAGE: 39,四、串行通信接口的编程,查询方式编程: #include #define BAUDRATE 9600 /定义波特率为9600 #define SYSCLK 11059200 /系统时钟频率 int main(
28、void) unsigned char temp;TMOD=0X20; /启用定时器1:8位自动重装载方式PCON=0; /设置PCON寄存器中的SMOD=0,即波特率不加倍TL1 = TH1 = 256 - SYSCLK /BAUDRATE /32/12;SCON=0X50; /设置串口工作于方式1,并允许接收,DATE: 2019/3/9,PAGE: 40,四、串行通信接口的编程,TR1=1; /启动定时器1工作dowhile(!RI); /等待串口接收数据完毕RI=0; / RI清0,为下次接收做准备temp=SBUF; /将串口数据接收到变量temp中SBUF=temp; /启动一次串
29、口数据发送while(!TI); /等待数据发送完毕TI=0; /TI清0,为下次发送做准备 while(1);,DATE: 2019/3/9,PAGE: 41,四、串行通信接口的编程,中断方式编程: #include #define BAUDRATE 9600 #define SYSCLK 11059200 int main(void) TMOD=0X20;/启用定时器1:8位自动重装载方式PCON=0; /设置PCON寄存器中的SMOD=0,即波特率不加倍TL1 = TH1 = 256 - SYSCLK /BAUDRATE/32/12;SCON=0X50;TR1=1;/启动定时器1工作EA
30、=1;ES=1;/开放串行口中断while(1);,DATE: 2019/3/9,PAGE: 42,四、串行通信接口的编程,void int(void)interrupt 4 unsigned char temp;if(RI) /接收中断处理RI=0;temp=SBUF;SBUF=temp; if(TI) TI=0; /发送中断处理,DATE: 2019/3/9,PAGE: 43,四、串行通信接口的编程,例9-6 单片机和PC机串口通信,PC机端通过串口调试助手向单片机发送一个字符串,该字符串以“#”开头,一共由6个字符,单片机再判断接收到“#”后面的字符是否都为数字,如果是返回“right”
31、,否则返回“wrong”。,DATE: 2019/3/9,PAGE: 44,四、串行通信接口的编程,#include #define BAUDRATE 9600 /定义波特率为9600 #define SYSCLK 11059200 /系统时钟频率 unsigned char sendbuf1=“right“; unsigned char sendbuf2=“wrong“; unsigned char receivebuf5; int main(void) unsigned char temp,i;bit flag;TMOD=0X20;/启用定时器1,8位自动重装载方式PCON=0; /设置P
32、CON寄存器中的SMOD=0,即波特率不加倍TL1 = TH1 = 256 - SYSCLK /BAUDRATE / 32 / 12;SCON=0X50; /设置串口工作于方式1,并允许接收TR1=1; /启动定时器1工作,DATE: 2019/3/9,PAGE: 45,四、串行通信接口的编程,while(1)while(!RI); /等待串口接收数据完毕RI=0; / RI清0,为下次接收做准备temp=SBUF; /将串口数据接收到变量temp中if(temp=#) /如果接收到#,则接收后面的5个字符flag=1;for(i=0;i9) )flag=0;/若接收的字符不是数字,则flag=0break;,DATE: 2019/3/9,PAGE: 46,四、串行通信接口的编程,if( flag )for(i=0;i5;i+) /发送“right”SBUF=sendbuf1i;while(!TI);TI=0;elsefor(i=0;i5;i+) /发送“wrong”SBUF=sendbuf2i;while(!TI);TI=0; ,DATE: 2019/3/9,PAGE: 47,