Presentation is loading. Please wait.

Presentation is loading. Please wait.

第八章 数据通信 本章学习目标 了解通信的有关概念 掌握串行通信和并行通信的原理

Similar presentations


Presentation on theme: "第八章 数据通信 本章学习目标 了解通信的有关概念 掌握串行通信和并行通信的原理"— Presentation transcript:

1 第八章 数据通信 本章学习目标 了解通信的有关概念 掌握串行通信和并行通信的原理
第八章 数据通信 本章学习目标 了解通信的有关概念 掌握串行通信和并行通信的原理 掌握常见串行接口(RS232/RS485/SPI/I2C)的原理及应用方法 掌握单片机并行接口的扩展方法

2 §8.1 通信的有关概念 通信:计算机的CPU与外部设备之间,以及计算机和计算机之间的信息交换。 通信分类:并行通信和串行通信

3 并行通信 以字节(Byte)或字节的倍数为传输单位 一次传送一个或一个以上字节的数据,数据的各位同时进行传送
适合于外部设备与微机之间进行近距离、大量和快速的信息交换。计算机的各个总线传输数据时就是以并行方式进行的。 并行通信的特点就是传输速度快,但当距离较远、位数较多时,通信线路复杂且成本高。

4 串行通信 通信双方使用一根或两根数据信号线相连,同一时刻,数据在一根数据信号线上一位一位地顺序传送,每一位数据都占据一个固定的时间长度。
与并行通信相比,串行通信的优点是传输线少、成本低、适合远距离传送及易于扩展。缺点是速度慢、传输时间长等。 如计算机上常用的COM设备、USB设备和网络通信等设备都采用串行通信。

5 一、串行通信的相关概念 1 、串行通信的分类 (1)按照串行数据的同步方式分类 按照串行数据的同步方式,串行通信可以分为 同步通信和异步通信两类

6 1)异步通信 在异步通信(Asynchronous Communication)方式中,接收器和发送器使用各自的时钟,它们的工作是非同步的。 在异步传送中,每一个字符要用起始位和停止位作为字符开始和结束的标志,以字符为单位一个个地发送和接收。

7 典型的异步通信格式如图所示。 图8-1 异步通信的格式

8 异步传送时,每个字符的组成格式 首先用一个起始位表示字符的开始;
后面紧跟着的是字符的数据字,数据字通常是7位或8位数据(低位在前,高位在后),在数据字中可根据需要加入奇偶校验位; 最后是停止位,其长度可以是一位或两位。串行传送的数据字加上成帧信号的起始位和停止位就形成了一个串行传送的帧。 起始位用逻辑“0”低电平表示,停止位用逻辑“1”高电平表示。

9 图a所示为数据字为7位的ASCII码,第8位是奇偶校验位,加上起始位、停止位,一个字符帧由10位组成。形成帧信号后,字符便一个一个地进行传送。

10 在异步传送中,字符间隔不固定,在停止位后可以加空闲位,空闲位用高电平表示,用于等待发送。这样,接收和发送可以随时进行,不受时间的限制。图b为有空闲位的情况。

11 在异步数据传送中,通信双方必须约定好两项事宜:
字符格式。包括字符的编码形式、奇偶校验以及起始位和停止位的规定。 通信速率。通信速率通常使用比特率来表示。 比特率是数字信号的传输速率,它用单位时间内传输的二进制代码的有效位(bit)数来表示,其单位为每秒比特数bit/s(bps)、每秒千比特数(Kbps)或每秒兆比特数(Mbps)来表示。

12 波特率与比特率 波特率指数据信号对载波的调制速率,它用单位时间内载波调制状态改变次数来表示,其单位为波特(Baud)。
波特率与比特率的关系是比特率=波特率×单个调制状态对应的二进制位数。 在信息传输通道中,携带数据信息的信号单元叫码元,每秒钟通过信道传输的码元数称为码元传输速率,简称波特率。波特率是传输通道频宽的指标。

13 例如,数据传送速率为120字符/秒(这个速率可以称为波特率),而每一个字符为10位,则其传送的比特率为10×120=1200位/秒=1200比特。
在后面的描述中,为了适应习惯用法,将比特率和波特率统一使用波特率来表示。

14 2)同步通信 同步通信(Synchronous Communication)是一种连续串行传送数据的通信方式,一次通信只传送一帧信息。这里的信息帧和异步通信中的字符帧不同,通常含有若干个数据字符。 根据控制规程,数据格式分为面向字符及面向比特两种。

15 面向字符型的同步通信数据格式可采用单同步、双同步和外同步三种数据格式,如图所示。
①面向字符型的数据格式 面向字符型的同步通信数据格式可采用单同步、双同步和外同步三种数据格式,如图所示。 图8-2 面向字符型同步通信数据格式

16 单同步、双同步 单同步和双同步均由同步字符、数据字符和校验字符CRC等三部分组成。
单同步是指在传送数据之前先传送一个同步字符“SYNC”,双同步则先传送两个同步字符“SYNC”。

17 外同步 外同步通信的数据格式中没有同步字符,而是用一条专用控制线来传送同步字符,使接收端及发送端实现同步。当每一帧信息结束时均用两个字节的循环控制码CRC为结束。

18 根据同步数据链路控制规程(SDLC),面向比特型的数据每帧由六个部分组成。
②面向比特型的数据格式 根据同步数据链路控制规程(SDLC),面向比特型的数据每帧由六个部分组成。 第一部分是开始标志“7EH”; 第二部分是一个字节的地址场; 第三部分是一个字节的控制场; 第四部分是需要传送的数据,数据都是位(bit)的集合; 第五部分是两个字节的循环控制玛CRC; 最后部分又是“7EH”,作为结束标志。

19 面向比特型的数据格式如图所示。 注意:在SDLC规程中不允许在数据段和CRC段中出现六个“1”,否则会误认为是结束标志。要求在发送端进行检验,当连续出现五个 “1”时,则立即插入一个“0”,到接收端要将这个插入的“0”去掉,恢复原来的数据,保证通信的正常进行。 图8-3 面向比特型同步通信数据格式

20 同步通信优缺点 数据传输速率较高,通常可达56000bps或更高,适用于传送信息量大、传送速率高的系统中,
缺点是要求发送时钟和接收时钟保持严格同步,故发送时钟除应和发送波特率保持一致外,还要求把它同时传送到接收端去。

21 (2)按照数据的传送方向分类 按照数据传送方向,串行通信可分为单工、半双工和全双工三种方式。

22 图a为单工通信方式(Simplex)。A为发送站,B为接收站,数据只能能由A发至B,而不能由B传送到A。
单工通信类似无线电广播,电台发送信号,收音机接收信号,收音机永远不能发送信号。

23 图b为半双工通信方式(Half Duplex)。数据可以从A发送到B,也可以由B发送到A。不过,由于使用一根线连接,发送和接收不可能同时进行,同一时间只能作一个方向的传送,其传送方向由收发控制开关K来控制。 半双工通信方式类似对讲机,某时刻A发送B接收,另一时刻B发送A接收,双方不能同时进行发送和接收。

24 图c为全双工通信方式(Full Duplex)。在这种方式中,分别用2根独立的传输线来连接发送方和接收方,A、B既可同时发送,又可同时接收。
全双工通信工方式类似电话机,双方可以同时进行数据的发送和接收。

25 图所示为主从多终端通信方式。A可以向多个终端(B、C、D…)发出信息。在A允许的条件下,可以控制管理B、C、D等在不同的时间向A发出信息。
根据数据传送的方向又分为多终端半双工通信和多终端全双工通信。

26 2、串行接口 作用:串行通信中的数据是一位一位依次传送的,而计算机中数据是并行传送的。因此,发送端必须把并行数据变成串行才能传送,接收端接收到的串行数据又需要变换成并行数据才可以送给计算机。上述并→串或串→并的转换既可以用软件实现,也可用硬件实现。 由于用软件实现会使CPU的负担增加,目前往往用硬件(串行接口)完成这种转换。

27 串行接口通过系统总线和CPU相连,如图所示。

28 串行接口主要由4部分组成 数据输入寄存器。在输入过程中,串行数据一位一位地从传输线进入串行接口的接收移位寄存器,经过串入并出电路的转换,当接收完一个字符之后,数据就从接收移位寄存器传送到数据输入缓冲器,等待CPU读取。 数据输出寄存器。当CPU输出数据时,先送到数据输出缓冲器,然后,数据由输出寄存器传到发送移位寄存器,经过并入串出电路转换一位一位地通过输出传输线送到外设。

29 串行接口主要由4部分组成 状态寄存器。状态寄存器用来存放外设运行的状态信息,CPU通过访问这个寄存器来了解某个外设的状态,进而控制外设的工作,以便与外设进行数据交换。 控制寄存器。串行接口中有一个控制寄存器,CPU对外设设置的工作方式命令、操作命令都存放在控制寄存器中,通过控制寄存器控制外设运行。

30 串行接口基本工作原理 串行发送时,CPU通过数据总线把8位并行数据送到数据输出寄存器,然后送给并行输入/串行输出移位寄存器,并在发送时钟和发送控制电路控制下通过串行数据输出端一位一位串行发送出去。起始位和停止位是由串行接口在发送时自动添加上去的。串行接口发送完一帧后产生中断请求,CPU响应后可以把下一个字符送到发送数据缓冲器。

31 串行接口基本工作原理 串行接收时,串行接口监视串行数据输入端,并在检测到有一个低电平(起始位)时就开始一个新的字符接收过程。串行接口每接收到一位二进制数据位后就使接收移位寄存器(即串行输入并行输出寄存器)左移一次,连续接收到一个字符后将其并行传送到数据输入寄存器,并产生中断促使CPU从中取走所接收的字符。

32 常见的串行接口芯片称为通用异步接收器/发送器UART(Universal Asynchronous Receiver/Transmitter),其内部结构如图8-7所示。

33 UART中3种出错标志: 奇偶错误(Parity error)。为了检测传送中可能发生的错误,UART在发送时会检查每个要传送的字符中的“1”的个数,自动在奇偶校验位上添加“1”或“0”,使得“1”的总和(包括奇偶校验位)在偶校验时为偶数,奇校验时为奇数。UART在接收时会检查字符中的每一位(包括奇偶校验位),计算其“1”的总和是否符合奇偶检验的要求,以确定是否发生传送错误。

34 UART中3种出错标志: 帧错误(Frame error),表示字符格式不符合规定。虽然接收端和发送端的时钟没有直接的联系,但是因为接收端总是在每个字符的起始位处进行一次重新定位,因此,必须要保证每次采样都对应一个数据位。如果接收时钟和发送时钟的频率相差太大,引起在起始位之后刚采样几次就造成错位时,会出现采样造成的接收错误。如果遇到这种情况,就会出现停止位(按规定应为高电平)为低电平(此情况下,未必每个停止位都是低电平),从而引起信息帧格式错误,帧错误标志FE置位。

35 UART中3种出错标志: 溢出(丢失)错误(Overrun error)。UART是一种双缓冲器结构。UART接收端在接收到第一个字符后便放入接收数据缓冲器,然后就继续从RXD线上接收第二个字符,并等待CPU从接收数据缓冲器中取走第一个字符。如果CPU很忙,一直没有机会取走第一个字符,以致接收到的第二字符进入接收数据缓冲器而造成第一个字符被丢失,于是产生了溢出错误,UART自动使溢出错误标志OE置位。

36 二、并行通信中的相关概念 1、并行接口 定义:实现并行通信的接口电路 分类:输入并行接口、输出并行接口和输入/输出并行接口。 并行通信以同步方式传输,其特点是:传输速度快;硬件开销大;适合近距离传输。

37 并行接口传输信息 状态信息。状态信息表示外设当前所处的工作状态。例如,准备好信号“READY”=1表示输入接口已经准备好,可以和CPU交换数据;忙信号“BUSY”=1表示接口正在传输信息,CPU需要等待。 控制信息。控制信息是由CPU发出的,用于控制外设接口的工作方式以及外设的启动和复位等。 数据信息。CPU与并行接口交换的主要内容。

38 一个典型的并行接口与CPU、外设连接图如图所示。
图8-8 典型并行接口电路图

39 2、并行接口电路组成 输入缓冲寄存器。输入数据缓冲器主要功能是负责接收设备送来的数据,CPU通过读操作指令IN执行读操作,从输入数据缓冲器读取数据。 输出缓冲寄存器。输出数据缓冲器主要功能是负责接收CPU送来的数据,如果设备处于空闲状态,则从输出数据缓冲器取走数据,接口通知CPU进行下一次输出操作。

40 2、并行接口电路组成 状态寄存器。状态寄存器用来存放外设运行状态信息,CPU通过访问状态寄存器来了解外设状态,进而控制外设的工作。

41 3、并行通信接口的基本输入/输出工作过程 (1)输入过程
外设首先将并行传输的数据放到外设与接口之间的数据总线上,并使“数据输入准备好”状态选通信号有效,该选通信号使数据输入到接口的输入数据缓冲器内。 当数据写入输入数据缓冲器后,接口使“数据输入应答”信号有效,作为对外设输入的响应。 外设收到此信号后,便撤销输入数据和“数据输入准备好”信号。

42 数据到达接口后,接口在状态寄存器中设置“输入准备好”状态位,以便CPU进行查询;接口也可以在此时向CPU发送中断请求,表示数据已输入到接口。

43 (2)输出过程 当外设从接口取走数据后,接口就会将状态寄存器中“输出准备好”状态位置1,表示CPU当前可以向接口输出数据,这个状态位可供CPU进行查询。 接口此时也可以向CPU发中断请求。CPU既可以用查询程序方式,也可以用程序中断方式向接口输出数据。 当CPU将数据送到输出缓冲器后,接口自动清除“输出准备好”状态位,并将数据送往外设的数据线上,同时,接口将给外设发送“启动信号”来启动外设接收数据。

44 外设被启动后,开始接收数据,并向接口发“数据输出应答”信号。
接口收到此信号,便将状态寄存器中的“输出准备好”状态位置1,以便CPU输出下一个数据。

45 §8.2 串行接口 一、单片机的串行接口 STC15F2K60S2单片机具有2个采用UART工 作方式的全双工串行通信接口(串口1和串口
2)。 每个串口由2个数据缓冲器、1个移位寄存 器、1个串行控制寄存器和一个波特率发生器等 组成。

46 每个串口的数据缓冲器由串行接收缓冲器和发送缓冲器构成,它们在物理上是独立的,既可以接收数据也可以发送数据,还可以同时发送和接收数据。
接收缓冲器只能读出,不能写入,而发送缓冲器则只能写入,不能读出。它们共用一个地址号。 串口1的接收缓冲器和发送缓冲器共用一个地址号(99H); 串口2的接收缓冲器和发送缓冲器共用一个地址号(9BH)。

47 STC15F2K60S2的串行口既可以用于串行异步通信,也可以构成同步移位寄存器。
如果在串行口的输入/输出引脚上加上电平转换器,可以方便地构成标准的RS-232接口。 STC15F2K60S2单片机的串行口有4种工作方式,有的工作方式的波特率是可变的。用户用软件编程的方法在串行控制寄存器中写入相应的控制字节,即可改变串行口的波特率和工作方式。

48 1、串行接口的寄存器 与串行接口1相关的寄存器有:CON、PCON、AUXR、SBUF、TMOD、TL1、TH1、TCON、IE、IP、CLK_DIV、P_SW2、SADEN和SADDR。 与串行接口2相关的寄存器有:S2CON、S2BUF、T2H、T2L、AUXR、IE2、IP2和AUXR1。

49 (1)串口1控制寄存器SCON SCON(地址为98H,复位值为00H)用于确定串口1的操作方式和控制串口1的某些功能,也可用于发送和接收第9个数据位(TB8、RB8),并设有接收和发送中断标志(RI及TI)位。 SCON各位的定义如下 : 位号 D7 D 6 D 5 D 4 D 3 D 2 D 1 D 0 位名称 SM0/FE SM1 SM2 REN TB8 RB8 TI RI

50 PCON寄存器中的SMOD0=1时,该位用于帧错误检测,当检测到一个无效停止位时,FE置1。它必须由软件清零。
位号 D7 D 6 D 5 D 4 D 3 D 2 D 1 D 0 位名称 SM0/FE SM1 SM2 REN TB8 RB8 TI RI 1)SM0/FE: PCON寄存器中的SMOD0=1时,该位用于帧错误检测,当检测到一个无效停止位时,FE置1。它必须由软件清零。 PCON寄存器中的SMOD0=0时, SM0/FE位和SM1一起指定串行通信的工作方式。(如下表) 表中SYSclk为振荡器频率

51 表8-1 串行通信的工作方式

52 2)SM2:多机通信控制位。 多机通信时单片机工作于方式2或方式3。SM2位是进行主-从多机通信的控制位。
位号 D7 D 6 D 5 D 4 D 3 D 2 D 1 D 0 位名称 SM0/FE SM1 SM2 REN TB8 RB8 TI RI 2)SM2:多机通信控制位。 多机通信时单片机工作于方式2或方式3。SM2位是进行主-从多机通信的控制位。 当进行主从式通信时,开始各个从机都应置SM2=1。主机发出的第一帧信息是地址帧信息(数据帧的第9数据位为1),此时各个从机接收到地址帧信息后都能产生中断,并进入各自的中断服务程序。

53 只有被寻址的从机(地址与从主机发出的地址号相符)在中断服务程序中使SM2=0,为从机接收主机发出的数据帧信息(第9数据位为0)作准备。而其他从机仍然维持SM2=1,对主机以后发出的数据帧信息,将不会产生中断申请,从而不会接收后续的数据帧信息。 在方式1时,如SM2=1,则只有在接收到有效停止位时才能激发中断标志(RI=1),如没有接收到有效停止位,则RI仍然为0。如果使用方式0,则SM2应为0。

54 3)REN:允许接收控制位。 1:允许串行口接收数据; 0:禁止串行口接收数据。 位号 D7 D 6 D 5 D 4 D 3 D 2 D 1
位名称 SM0/FE SM1 SM2 REN TB8 RB8 TI RI 3)REN:允许接收控制位。 1:允许串行口接收数据; 0:禁止串行口接收数据。

55 在方式2和3时,它是要发送的第9个数据位,按需要由软件进行置位或清零。
位号 D7 D 6 D 5 D 4 D 3 D 2 D 1 D 0 位名称 SM0/FE SM1 SM2 REN TB8 RB8 TI RI 4)TB8 在方式2和3时,它是要发送的第9个数据位,按需要由软件进行置位或清零。 该位可用作数据的奇偶校验位,或在多机通信中用作地址帧/数据帧的标志位。 5)RB8 在方式2和3时,它是接收到的第9位数据,作为奇偶检验位或地址帧/数据帧标志位。 在方式1时,若SM2=0,则RB8是接收到的停止位。在方式0时,不使用RB8。

56 在方式0时,当串行发送数据字第8位结束时由内部硬件置位,向CPU申请发送中断。CPU响应中断后,必须用软件清零。
位号 D7 D 6 D 5 D 4 D 3 D 2 D 1 D 0 位名称 SM0/FE SM1 SM2 REN TB8 RB8 TI RI 6)TI:发送中断标志位。 在方式0时,当串行发送数据字第8位结束时由内部硬件置位,向CPU申请发送中断。CPU响应中断后,必须用软件清零。 在其他方式时,在停止位开始发送时由硬件置位。同样,必须用软件清零。

57 在方式0时,当串行接收到第8位结束时由内部硬件置位。
位号 D7 D 6 D 5 D 4 D 3 D 2 D 1 D 0 位名称 SM0/FE SM1 SM2 REN TB8 RB8 TI RI 7)RI:接收中断标志位。 在方式0时,当串行接收到第8位结束时由内部硬件置位。 在其他方式时,RI在接收到停止位的中间时刻由硬件置位(例外情况见SM2说明)。RI也必须用软件清0。

58 TI与RI使用时需注意 当一帧数据发送完成时,发送中断标志TI被置位,接着发生串口中断,进入串口中断服务程序。但CPU事先并不能分辨是TI还是RI的中断请求,因此,必须在中断服务程序中用位测试指令加以判别。 两个中断标志位TI及RI均不能自动复位,必须在中断服务程序中使用清中断标志位指令,撤销中断请求状态,否则原先的中断标志位状态又将表示有中断请求。

59 (2)串口2控制寄存器S2CON 寄存器S2CON(地址为9AH,复位值为00H)用于确定串口2的操作方式和控制串口2的某些功能,也可用于发送和接收第9个数据位(S2TB8、S2RB8),并设有接收和发送中断标志(S2RI及S2TI)位。 S2CON各位的定义如下: 位号 D7 D 6 D 5 D 4 D 3 D 2 D 1 D 0 位名称 S2SM0 S2SM2 S2REN S2TB8 S2RB8 S2TI S2RI

60 其中,S2SM0用于指定串口2的工作方式,如表所示
当T2x12=1时,定时器2的溢出率= SYSclk / ( [RL_TH2,RL_TL2]) 当T2x12=0时,定时器2的溢出率= SYSclk / 12 / ( [RL_ TH2,RL_TL2]) 式中RL_TH2是T2H的重装载寄存器,RL_TL2是T2L的重装载寄存器。 S2SM0 工作方式 功能说明 波特率 方式0 8位UART,波特率可变 (定时器2的溢出率)/4 1 方式1 9位UART,波特率可变

61 PCON(地址为87H,复位值为30H)中的SMOD用于设置方式1、方式2和方式3的波特率是否加倍。
各位的定义如下: 位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 SMOD SMOD0 LVDF POF GF1 GF0 PD IDL

62 SMOD:串行口波特率系数控制位。复位时,SMOD=0。 1:使方式1、方式2和方式3的波特率加倍。 0:各工作方式的波特率不加倍。
位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 SMOD SMOD0 LVDF POF GF1 GF0 PD IDL SMOD:串行口波特率系数控制位。复位时,SMOD=0。 1:使方式1、方式2和方式3的波特率加倍。 0:各工作方式的波特率不加倍。

63 SMOD0:帧错误检测有效控制。复位时,SMOD0=0。 1:SCON寄存器中的SM0/FE位用于FE(帧错误检测)功能。
位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 SMOD SMOD0 LVDF POF GF1 GF0 PD IDL SMOD0:帧错误检测有效控制。复位时,SMOD0=0。 1:SCON寄存器中的SM0/FE位用于FE(帧错误检测)功能。 0:SCON寄存器中的SM0/FE位用于SM0功能,和SM1一起指定串行通信的工作方式。

64 辅助寄存器AUXR(地址为8EH,复位值为01H) 各位的定义如下:
位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 T0x12 T1x12 UART_M0x6 T2R T2_C/ T2x12 EXTRAM S1S2

65 1)UART_M0x6:串行口模式0的通信速度设置位。 0:UART串口模式0的速度是传统12T的8051速度,12分频。
位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 T0x12 T1x12 UART_M0x6 T2R T2_C/ T2x12 EXTRAM S1S2 1)UART_M0x6:串行口模式0的通信速度设置位。 0:UART串口模式0的速度是传统12T的8051速度,12分频。 1:UART串口模式0的速度是传统12T的8051的6倍,2分频。

66 2)S1S2:串口1波特率发生器选择位。 0:选择定时器1作为串口1波特率发生器。 1:选择定时器2作为串口1波特率发生器。 位号 D7
位名称 T0x12 T1x12 UART_M0x6 T2R T2_C/ T2x12 EXTRAM S1S2 2)S1S2:串口1波特率发生器选择位。 0:选择定时器1作为串口1波特率发生器。 1:选择定时器2作为串口1波特率发生器。

67 注意: 对于具有串口2的STC15F2K60S2单片机,串口2只能使用独立波特率发生器作为波特率发生器,不能够选择定时器1作为波特率发生器;
串口1可以选择定时器1作为波特率发生器,也可以选择独立波特率发生器作为波特率发生器。

68 (5)定时器2寄存器 定时器2时间常数寄存器T2H和T2L(地址分别为0D6H和0D7H,复位值为00H)用于保存重装时间常数,从而作为波特率发生器使用。 可以配合辅助寄存器AUXR中的T2R、T2_C/和T2x12位进行时间常数的确定。

69 (6)从机地址控制寄存器 为了方便多机通信,STC15F2K60S2单片机设置了从机地址控制寄存器SADEN和SADDR。 SADEN是从机地址掩模寄存器(地址为B9H,复位值为00H),SADDR是从机地址寄存器(地址为A9H,复位值为00H)。

70 主机可以用从机地址来选择性的访问从机。可以用广播的方式来寻址所有的从机。
从机的地址由SADDR和SADEN寄存器定义,从机地址是由SADDR设定的8位数据,如果SADEN中相应的位置0,则SADDR中对应的位无效。只有当SADEN中的相应位为1,SADDR中的数据才有效。也就是说,SADEN寄存器使能串口的自动地址识别功能,当SADEN中的某位被置为1,那么SADDR寄存器中的相应位会与接收到的数据进行比较。 如果SADEN.n被设为0,那么系统会忽略对该位的比较。如果SADEN为全0,那么对于所有的地址帧系统都会产生中断。

71 数据缓冲器用于保存要发送的数据或者从串口接收到的数据。串口1的数据缓冲器是SBUF,串口2的数据缓冲器是S2BUF。
(7)数据缓冲器 数据缓冲器用于保存要发送的数据或者从串口接收到的数据。串口1的数据缓冲器是SBUF,串口2的数据缓冲器是S2BUF。 对于串口1,当一个字符接收完毕,移位寄存器中的数据字节装入串行接收数据缓冲器SBUF中,其第9位则装入SCON寄存器的RB8位。如果SM2使得已接收的数据无效,则RB8位和SBUF缓冲器中的内容不变。

72 对于串口2,当一个字符接收完毕,移位寄存器中的数据字节装入串行接收数据缓冲器S2BUF中,其第9位则装入S2CON寄存器的S2RB8位。如果S2SM2使得已接收的数据无效,则S2RB8位和S2BUF缓冲器中的内容不变。 无论对于串口1还是串口2,发送缓冲器只能写入,不能读出;接收缓冲器只能读出,不能写入。因此,串口1的两个缓冲器共用一个地址号(99H),串口2的两个缓冲器共用一个地址号(9BH)。

73 CLK_DIV寄存器中的Tx_Rx位用于串口1的中继广播方式设置。
(8)串口1的中继广播方式设置 CLK_DIV寄存器中的Tx_Rx位用于串口1的中继广播方式设置。 0:串口1为正常工作方式 1:串口1为中继广播方式,即将RxD端口输入的电平状态实时输出在TxD外部管脚上。

74 STC15F2K60S2单片机的串行口1有4种工作方式,通过设置SCON寄存器的SM0和SM1进行选择 。现分别加以介绍。
2、串行接口的工作方式 STC15F2K60S2单片机的串行口1有4种工作方式,通过设置SCON寄存器的SM0和SM1进行选择 。现分别加以介绍。 方式0:移位寄存器方式 方式1:8位可变波特率方式 方式2:9位固定波特率方式 方式3:9位可变波特率方式

75 (1)方式0:移位寄存器方式 方式0为半双工方式,又称为同步移位寄存器输出方式。
在这种方式下,TXD引脚输出同步移位时钟,RXD用于发送和接收串行数据。串行口输出端可直接与移位寄存器相连,也可用作扩展I/O口或外接同步输入输出设备。 该方式下的数据帧为8位,低位在先,高位在后,没有起始位和停止位。

76 发送过程 当CPU将数据写入到发送缓冲区SBUF时,串行口即把8位二进制数以SYSclk/12或SYSclk/2(由UART_M0x6确定是12分频还是2分频)的波特率由RXD引脚输出(SYSclk为系统工作时钟),同时由TXD引脚输出同步移位脉冲。字符发送完毕,置中断标志TI为1。 当写SBUF信号有效后,相隔一个时钟,发送控制端有效,允许RxD发送数据,同时允许TxD输出同步移位脉冲。一帧数据(8位)发送完毕时,各控制端均恢复原状态,只有TI保持高电平,呈中断申请状态。在再次发送数据前,必须用软件将TI清0。

77 接收过程 控制字除方式0外,还应置允许接收控制位REN=1,并清除RI中断标志。接收过程启动后,RXD为数据输入端,TXD为同步信号输出端。串行接收的波特率为SYSclk/12或SYSclk/2(由UART_M0x6确定是12分频还是2分频)。接收完8位数据后重新置RI=1。当再次接收时,必须通过软件将RI清0。

78 工作于方式0使用时需注意 必须使SCON控制字的SM2位为0,从而不影响TB8和RB8位。
在该方式下,波特率仅取决于系统时钟,无需使用定时器控制。 以中断方式传送数据时,CPU响应中断并不会自动清除TI、RI标志,在中断服务程序中必须由指令清零。如CLR TI及CLR RI。

79 (a)串行口1方式0功能结构图

80 (b)串行口1方式0时序图

81 (1)串口1的UART方式 ①方式1:8位可变波特率方式 方式1提供异步全双工通信,适合于点到点的通信。
每个数据帧长度为10位:1个起始位(低电平)、8个数据位和1个停止位(高电平)。 传输的数据位首先是起始位,然后是8位数据(低位在前),最后一位是停止位。起始位和停止位是在发送时自动插入的。接收时,停止位进入SCON的RB8位。

82 (a)串行口1方式1功能结构图

83 发送过程 发送数据时,数据由串行发送端TxD输出。当单片机执行一条写SBUF的指令时,就启动串行通信的发送,写SBUF信号还把1装入发送移位寄存器的第9位,并通知TX控制器开始发送。发送各位的定时时间由16分频计数器同步。 移位寄存器将数据不断右移送TxD端口发送,在数据的左边不断移入0作补充。当数据的最高位移到移位寄存器的输出位置,紧跟其后的是第9位“1”,在它的左边各位全为“0”,这个状态条件,使TX控制器作最后一次移位输出,然后使允许发送信号“SEND”失效,完成一帧信息的发送,并置位中断请求位TI,即TI=1,向CPU请求中断处理。

84 接收过程 当软件置位接收允许标志位REN,即REN=1时,接收器便以选定波特率的16分频的速率采样串行接收端口RxD,当检测到RxD端口从1→0的负跳变时就启动接收器准备接收数据,并立即复位16分频计数器,将1FFH值装入移位寄存器。复位16分频计数器的目的是使它与输入位时间同步。

85 16分频计数器的16个状态是将每位的接收时间均为16等份,在每位时间的7、8、9状态由检测器对RxD端口进行采样,经“三中取二”后的值作为本次所接收的值,即3次采样至少2次相同的值,以此消除干扰影响,提高可靠性。在起始位,如果接收到的值不为0(低电平),则起始位无效,复位接收电路,并重新检测1→0的跳变。如果接收到的起始位有效,则将它输入移位寄存器,并接收本帧的其余信息。

86 接收的数据从接收移位寄存器的右边移入,已装入的1FFH向左边移出,当起始位0移到移位寄存器的最左边时,使RX控制器作最后一次移位,完成一帧的接收。若同时满足以下两个条件:
RI=0; SM2=0或接收到的停止位为1。 则接收到的数据有效,数据载入SBUF,停止位进入RB8,置位RI,向CPU请求中断,若上述两条件不能同时满足,则接收到的数据作废并丢失,无论条件满足与否,接收器重新检测RxD端口上的1→0的跳变,继续下一帧的接收。接收有效,在响应中断后,必须由软件将RI清0。 通常情况下,串行口工作于方式1时,SM2设置为0。

87 串行通信方式1的波特率是可变的,波特率由定时器1或定时器2的溢出率决定。
定时/计数器的溢出率定义为: 单位时间(秒)内定时器/计数器溢出的次数 串行口1用定时器1作为波特率发生器且定时器1工作于模式0(16位自动重装模式)时,波特率=(定时器1的溢出率)/4。 注意:此时波特率与SMOD无关。

88 = SYSclk/12/( 65536 - [RL_TH1,RL_TL1])/4
当定时器1工作于模式0(16位自动重装模式)且T1x12 = 0时 定时器1的溢出率 = SYSclk/12/( [RL_TH1,RL_TL1]); 此时,串口1的波特率 = SYSclk/12/( [RL_TH1,RL_TL1])/4

89 此时,串口1的波特率=× SYSclk/12/( 256 - TH1)
当串行口1用定时器1作为波特率发生器且定时器1工作于模式2(8位自动重装模式)时 波特率=×(定时器1的溢出率) 当定时器1工作于模式2(8位自动重装模式)且T1x12 = 0时 定时器1的溢出率= SYSclk/12/( TH1); 此时,串口1的波特率=× SYSclk/12/( TH1)

90 当T2x12=0时 当定时器1工作于模式2且T1x12 = 1时 定时器1的溢出率= SYSclk / ( 256 - TH1)
定时器2的溢出率=SYSclk/12/( [RL_TH2,RL_TL2] ) 此时,串口1的波特率= SYSclk/12/( [RL_TH2,RL_TL2])/4 当T2x12 = 1时,定时器2的溢出率=SYSclk/( [RL_TH2,RL_TL2] )。 此时,串口1的波特率= SYSclk/ ( [RL_TH2,RL_TL2])/4。 其中,RL_TH2是TH2的自动重装寄存器,RL_TL2是TL2的自动重装寄存器。

91 其中,RL_TH1是TH1的自动重装载寄存器,RL_TL1是TL1的自动重装载寄存器。
定时器1工作于模式0(16位自动重装模式)且T1x12 = 1时 定时器1的溢出率 = SYSclk / ( [RL_TH1,RL_TL1])。 此时,串口1的波特率= SYSclk/ ( [RL_TH1,RL_TL1])/4。 其中,RL_TH1是TH1的自动重装载寄存器,RL_TL1是TL1的自动重装载寄存器。

92 方式1的发送、接收工作波形图如图所示。 (b)串行口1方式1时序图

93 ②串口方式2:9位固定波特率方式 方式2提供异步全双工通信,适合于固定波特率的多机通信。
每个数据字节长度为11位:1个起始位、8个数据位(低位在前)、1个可编程的第9位(TB8/RB8)和1个停止位。与方式1相比,每帧增加了一个第9位。 发送时,第9位数据由TB8确定,可以置位也可以清0。 接收时,第9位进入RB8位。

94 PCON寄存器中的SMOD为波特率加倍位
方式2的波特率为: 串行通信方式2波特率= SYSclk为系统工作时钟频率 PCON寄存器中的SMOD为波特率加倍位 当SMOD=1时,波特率为SYSclk/32; 当SMOD=0时,波特率为SYSclk/64。

95 (a)串行通信方式2的功能结构示意图

96 (b)串行通信方式2的接收/发送时序图

97 2)串口2的工作方式0 串行数据通过RXD2/P1.2(RXD2/P4.2)接收和发送,TXD2/P1.3(TXD2/P4.3)输出同步移位时钟,发送接收的是8位数据,低位在先,波特率固定在Fosc/12。 串口2的模式0操作和串口1的模式0操作方式相同。

98 当接收器接收完一帧信息后必须同时满足下列条件:
RI=0 SM2=0或者SM2=1,并且接收到的第9数据位RB8=1 当上述两条件同时满足时,才将接收到的移位寄存器的数据装入SBUF和RB8中,并置位RI,向CPU请求中断处理。如果上述条件有一个不满足,则刚接收到移位寄存器中的数据无效而丢失,也不置位RI。无论上述条件满足与否,接收器又重新开始检测RxD输入端口的跳变信息,接收下一帧的输入信息。

99 在方式2中,接收到的停止位与SBUF、RB8和RI无关。
通过软件对SCON中的SM2、TB8的设置以及通信协议的约定,为多机通信提供了方便。

100 ③串口方式3:9位可变波特率方式 该方式也适合于多机通信。
方式3的每个数据字节长度为11位:1个起始位、8个数据位(低位在前)、1个可编程的第9位(TB8/RB8)和1个停止位。 发送时,第9位数据由TB8确定,可以置位也可以清0。 接收时,第9位数据进入RB8位。 方式3和方式1一样,其波特率可通过软件对定时器/计数器1或定时器2的设置进行波特率的选择,是可变的。

101 (a)工作方式3的功能结构

102 (b)工作方式3的数据接收/发送时序图

103 发送过程 CPU执行数据写入发送缓冲区SBUF的指令即可启动发送(如MOV SBUF,A)。
串行口自动将发送缓冲区中的内容送入发送移位寄存器。发送移位寄存器先发送一个起始位,接着按程序设定每个字符的代码,先低位后高位。数据字加上奇偶校验位或可控位(方式2、3中即为程序设定的TB8位的值),再发送停止位,从而完成一帧的发送。 串行数据均由TXD端输出,发送完毕,将发送中断标志位TI置1,以供查询及向CPU申请中断之用。CPU的响应中断后必须在中断服务程序中使TI清0。

104 接收过程 接收数据由RXD输入,串行口以所选定波特率的16倍速率采样RXD端状态。当RXD端电平由1到0跳变时,就启动接收器。
串行口按程序规定的格式接收一帧代码,并把此码的数据位拼成并行码送入接收缓冲寄存器中(在方式1时,把停止位送入RB8;在方式2、3时,把程控的第9位数据送入RB8),等待CPU取走。为保证可靠无误,对每一数据位进行连续3次采样,取3次采样中至少两次相同的值。 接收完毕,置接收中断标志RI=1。CPU的响应中断后必须在中断服务程序中使RI清0。

105 当接收器接收完一帧信息后必须同时满足下列条件:
RI=0 SM2=0或者SM2=1,并且接收到的第9数据位RB8=1。 当上述两条件同时满足时,才将接收到的移位寄存器的数据装入SBUF和RB8中,并置位RI,向CPU请求中断处理。如果上述条件有一个不满足,则刚接收到移位寄存器中的数据无效而丢失,也不置位RI。无论上述条件满足与否,接收器又重新开始检测RxD输入端口的跳变信息,接收下一帧的输入信息。

106 在方式3中,接收到的停止位与SBUF、RB8和RI无关。
通过软件对SCON中的SM2、TB8的设置以及通信协议的约定,为多机通信提供了方便。

107 几种常用的典型帧格式。 图8-13 串行通信典型帧格式

108 总结 在实际应用中,应根据实际需要选择串行口 的工作方式。由于方式1和方式3的波特率可以 通过定时器1控制,通信波特率的设定比较灵 活,因此,方式1和方式3使用较多,其中,方 式1常用于点对点通信的情况;而方式3常用语 多机通信的情况。

109 串行口工作方式一览表。

110 方式1与方式2、3的区别 方式1中,数据字是8位异步通信接口,串行口发送/接收共10位信息,第0位为起始位,1~8位是数据位,最后是停止位;方式2、3中,数据字为9位的异步通信接口,1位起始位,8位数据位,第9位是可程控位“1”或“0”,最后是停止位,共有11位信息。 方式1、3的波特率是可变的,其波特率取决于定时器1的溢出率或BRT的溢出率和特殊功能寄存器PCON中的SMOD位的值。

111 由上述公式可以看出,PCON寄存器中的SMOD是“1”还是“0”决定波特率是否加倍。
方式1、3的波特率=2SMOD×(定时器1的溢出率或BRT的溢出率)/32 方式2的波特率=2SMOD×(振荡器频率)/64 由上述公式可以看出,PCON寄存器中的SMOD是“1”还是“0”决定波特率是否加倍。

112 在方式2和方式3中还可通过控制TB8位的方法,使其传送中附加的第9位数据可以作为多机通信中的地址/数据标志位,或作为数据的奇偶校验位。若以TB8位作为奇偶校验位,在数据写入SBUF之前,先将数据的奇偶位写入TB8。

113 MOV A,R2 ;取数据 MOV C,P MOV TB8,C MOV SBUF,A ;数据写入到发送缓冲器,启动发送器

114 ②对方式2、3:SM2=0或接收到的第九个数据=1
编写接收程序时,均应使REN=1,允许串行接 收。只有在最后的移位脉冲产生并同时满足下列条 件时,接收数据才会装入SBUF和RB8并置位RI: ①对于方式1:SM2=0或接收到的停止位=1 ②对方式2、3:SM2=0或接收到的第九个数据=1

115 2)串口2的UART方式 ①方式0 10位数据通过TXD2/P1.0(TXD2/P46)发送,通过TxD2/P1.1(TxD2_2/P4.7)发送。 一帧数据包含一个起始位(0),8个数据位和一个停止位(1)。接收时,停止位进入特殊功能寄存器S2CON的S2RB8位。 波特率由独立波特率发生器BRT的溢出率决定。

116 此时,串行口2的波特率=SYSclk / ( 65536 - [RL_TH2, RL_TL2]) / 4
当T2工作在1T模式(T2x12=1)时 T2的溢出率=SYSclk/(65536-[RL_TH2, RL_TL2] ); 此时,串行口2的波特率=SYSclk / ( [RL_TH2, RL_TL2]) / 4 当T2工作在12T模式(T2x12=0)时 T2的溢出率=SYSclk/12/(65536-[RL_TH2, RL_TL2]); 此时,串行口2的波特率=SYSclk /12/( [RL_TH2, RL_TL2]) / 4 其中,RL_TH2是T2H的重装载寄存器,RL_TL2是T2L的重装载寄存器。

117 ②方式1 11位数据通过TxD2/P1.1(TxD2_2/P4.7)发送,通过RxD2/P1.0(RxD2_2/P4.6)接收。
一帧数据包含一个起始位(0),8个数据位,一个可编程的第9位和一个停止位(1)。 发送时,第9位数据由特殊功能寄存器S2CON的S2TB8位确定;接收时,第9位数据进入特殊功能寄存器S2CON的S2RB8位。 波特率的计算方法与方式0相同,在此略。

118 3、多处理机通信 串行口控制寄存器SCON中的SM2位为方式2和方式3工作时进行多机通信的控制位。
以使用串口1为例,说明多机通信的过程。 串行口控制寄存器SCON中的SM2位为方式2和方式3工作时进行多机通信的控制位。 这种多机通信方式一般为“一台主机,多台从机”系统,主机发送的信息可被各从机接收,而从机只能对主机发送信息,从机间互相不能直接通信。

119 典型的多机通信结构图如图所示。 图8-14 多机通信系统示意图

120 多机系统设置需注意 多机系统中,从机串行口必须在方式2或方式3下工作。
应使SM2及REN控制位置“1”。从而使从机先处于只能接收地址帧信息(第9数据位为1)的状态,当从机接收到主机发出的地址帧信息后,串行口可向CPU申请中断。

121 多机系统通信过程 当主机和某一从机通信时,主机应先发出一帧包含某从机地址的信息给各从机(TB8=1)。
当各从机接收到主机发出的地址帧信息后,自动将第9数据位状态“1”送到SCON控制寄存器的RB8位,并将中断标志RI置1,产生中断。 各CPU响应中断后均进入中断服务程序,在服务程序中把主机送来的地址号与本从机的地址号相比较。

122 若地址相等,则使本机的SM2置“0”,为接收主机接着发送来的数据帧(第9数据位为0)作准备。而地址号不符的其他从机仍然维持SM2=1的状态,对主机以后发出的数据帧信息不予理睬,不产生中断标志RI,直到与主机发出的地址信息相符后,才可接收以后的数据信息,从而实现了主从一对一通信。 主机在发送完呼叫地址帧后(TB8=1),接着发送一连串的数据帧(TB8=0)。

123 当主机要和另一个从机通信时,则再发呼叫地址帧(TB8=1),呼叫其他从机,原先被寻址的从机经分析得知主机在呼叫其他从机时,恢复其SM2=1,对其后主机发送的数据帧不予理睬。
使用串行口2进行多机通信的方法与此类似,仅把SCON中的SM2、REN、TB8和RB8换成对应的S2CON中的S2SM2、S2REN、S2TB8和S2RB8即可。

124 4、波特率的设定 (1)串行口1的波特率设定 方式0的波特率 方式2的波特率 方式1和3的波特率
当UART_M0x6=0时,波特率为SYSclk/12;当UART_M0x6=1时,波特率为SYSclk/2。 方式2的波特率 当SMOD=0时,波特率为SYSclk/64;当SMOD=1时,为SYSclk/32。 方式1和3的波特率 串行口1工作于方式1和3时,波特率是可变的,可以通过编程改变定时器1的溢出率或者定时器2的溢出率来确定波特率。

125 编程时应注意 当定时器作为波特率发生器使用时,应禁止定时器产生中断(ET1=0或者ET2=0 )。
典型用法是定时器1工作在自动再装入时间常数的定时方式2。设置完成后,启动定时器1(TR1=1或T2R=1 )。 STC15F2K60S2单片机是“一个时钟周期”的8051单片机,选用定时器1作为波特率发生器时,应注意时钟分频的设置与波特率之间的关系,1T模式下的波特率时相同条件下12T模式的12倍。

126 其中,12T模式时,T1x12=0,n=1;1T模式时,T1x12=1,n=0(下同)。
总结波特率的计算方法: 串行口1用定时器1作为波特率发生器时,且定时器1工作于模式0(16位自动重装模式)作为波特率发生器时 波特率=(定时器1的溢出率)/4= SYSclk/12n/( [RL_TH1,RL_TL1])/4。 其中,12T模式时,T1x12=0,n=1;1T模式时,T1x12=1,n=0(下同)。 RL_TH1是TH1的自动重装载寄存器,RL_TL1是TL1的自动重装载寄存器。 注意:此时波特率与SMOD无关。

127 当串行口1用定时器1作为波特率发生器且定时器1工作于模式2(8位自动重装模式)时
波特率= ×(定时器1的溢出率) = × SYSclk/12n/( TH1)

128 其中,RL_TH2是TH2的自动重装寄存器,RL_TL2是TL2的自动重装寄存器。
定时器2只有一种工作方式,即16位自动重装方式,因此使用定时器2作为波特率发生器时,串口1的波特率为: 串口1的波特率= SYSclk/12n/( [RL_TH2,RL_TL2])/4。 其中,RL_TH2是TH2的自动重装寄存器,RL_TL2是TL2的自动重装寄存器。 在实际应用中,一般选用串行方式1或串行方式3。此时,波特率的设置,关键在于定时器/计数器1和定时器2的溢出率的计算。

129 (2)串行口2波特率的设定 对于串行口2,只能通过编程改变定时器2的溢出率来确定波特率。 串行口2只有两种工作方式:S2SM0=0为方式0
(的8位数据位的UART工作方式);S2SM0=1 为方式1(9位数据位的UART工作方式),它们的波特率计算方法相同,都是如下公式所示: 串行口2的波特率 = SYSclk/12n/( [RL_TH2,RL_TL2])/4

130 常用的串行口波特率、系统时钟以及定时器1(工作于方式2时)重装时间常数之间的关系如表8-4所示。
可以直接从表中查得所需设置的时间常数。 定时器1工作于方式0时以及使用定时器T2作为波特率发生器时的重装时间常数,可根据计算公式自行计算。

131 5、串行接口通信应用举例 下面分别说明STC15F2K60S2单片机使用串口1和串口2的串行通信程序编程要点。在编程应用中,虽然可以采用查询方式进行通信,但是,为了有效进行实时任务处理,一般采用中断方式进行串行通信。 (1)串口1的编程要点 1)设置串口的工作模式 设置SCON寄存器的内容。若要串口接收,需将其中的REN位置1。

132 2)设置正确的波特率 ①使用定时器1作为波特率发生器时,需要设置定时器1的工作方式和时间常数(设定TMOD和TH1、TL1寄存器的内容);启动定时器1(置位TR1)。 ②使用定时器2作为波特率发生器时,需要设置定时器2寄存器和相应的位,包括:定时器2自动重装寄存器T2H和T2L,T2_C/ 位,T2x12位,SMOD位。启动T2(置位T2R),T2开始计数。

133 3)设置串口的中断优先级(设置PS寄存器的内容,也可以不设置,取默认值),设置相应的中断控制位(ES和EA)。
4)如要串口1发送,将数据送入SBUF。 5)编制串行中断服务程序,在中断服务程序中要有清除中断标志指令(将TI和RI清0)。

134 (2)串口2的编程要点 1)设置串口2的工作模式 设置S2CON寄存器中的S2SM0位。如要串口2接收,将S2REN置1。 2)设置串口2的波特率相应的寄存器和位。 包括:T2H和T2L,T2_C/ 位,T2x12位。启动T2(置位T2R),T2开始计数。

135 3)设置串口2的中断优先级(设置PS2和PS2H,也可以不设置,取默认值),设置打开相应的中断控制位(ES2和EA)。
4)如要串口2发送,将数据送入S2BUF。 5)编制串行中断服务程序,在中断服务程序中要设置清除中断标志指令(分别是接收完成标志S2RI和发送完成标志S2TI)。

136 下面举例说明12T模式下,STC15F2K60S2单片机串行通信程序的编制方法。
【例8-1】 设有甲、乙两台单片机,编写程序,使两台单片机间实现如下串行通信功能。(假设系统时钟为 MHz。) 甲机(发送机):将首址为ADDRT的128字节外部RAM数据块顺序向乙机发送; 乙机(接收机):将接收的数据,顺序存放在以首址为ADDRR的外部RAM中。

137 硬件电路连接 进行双机通信时,二者的TxD和RxD信号线应交叉连接,即甲机的TxD连接乙机的RxD;

138 解:甲机发送数据的程序流程如图所示。 图8-15 甲机发送程序流程图

139 甲机(发送机)汇编语言程序: $INCLUDE (STC15.INC) ;包含单片机寄存器定义文件 ORG 0000H LJMP MAINT ;主程序入口 ORG 0023H LJMP INTSE ;串口1中断服务程序入口 ORG 0100H MAINT: MOV SP,#60H ;设置堆栈指针 MOV SCON,# B ;置串行口工作方式1 MOV AUXR,#00H ;选择定时器1作为波特率发生器 MOV TMOD,#20H ;定时器1为工作方式2 MOV TH1,#0FDH ;9600bps的时间常数 MOV TL1,#0FDH SETB TR1 ;启动定时器1 SETB ES ;串行口开中断 SETB EA ;开中断 MOV DPTR,#ADDRT ;ADDRT是首址,可以使用EQU定义 MOV R0,#00H ;传送字节数初值 MOVX ;取第一个发送字节 MOV SBUF,A ;启动串行口发送 SJMP $ ;等待中断

140 ;中断服务程序 INTSE1: CLR TI ;将中断标志清零 CJNE R0,#7FH,LOOPT ;判断128B是否发送完,若没完,则转 CLR ES ;全部发送完毕,禁止串行口中断 LJMP ENDT ;转中断返回 LOOPT: INC R0 ;修改计数值 INC DPTR ;修改地址指针 MOVX ;取发送数据 MOV SBUF,A ;启动串行口 ENDT: RETI ;中断返回 END

141 甲机的C语言程序: #include “stc15.h” //包含单片机寄存器定义文件 unsigned char xdata ADDRT[128]; //在外部RAM区定义128个单元 unsigned char num=0; //声明计数变量 unsigned char *psend; //指向发送数据区的指针 void main (void) //主程序 { SCON=0x40; //置串行口工作方式1 AUXR=0x0; //选择定时器1作为波特率发生器 TMOD=0x20; //定时器1为工作方式2 TH1=0xfd; //产生9600bps的时间常数 TL1=0xfd; TR1=1; //启动定时器1 ES=1; //串行口开中断 EA=1; //开中断 psend=ADDRT; //设置发送数据缓冲区指针 SBUF=*psend; //发送第一个数据 while(1); //等待中断 }

142 void UART_ISR(void) interrupt 4 //中断号4是串口1中断
{ TI = 0; //清发送中断标志 num++; //修改计数变量值 if(num==0x7F) ES=0; //判断是否发送完,若已完,则关中断 else //否则,修改指针,发送下一个数据 psend++; SBUF=*psend; }

143 乙机接收数据的程序流程如图所示。 图8-16 乙机接收数据流程图

144 注意,接收方的波特率必须和发送方的波特率相同。乙机接收汇编语言程序:
$INCLUDE (STC15.INC) ;包含单片机寄存器定义文件 ORG 0000H LJMP MAINR ;转主程序 ORG 0023H LJMP INTSE ;串口1中断服务程序入口 ORG 0100H MAINR:MOV SP,#60H ;设置堆栈指针 MOV SCON,# B ;置串行口工作方式1,允许接收 MOV AUXR,#00H ;选择定时器1作为波特率发生器 MOV TMOD,#20H ;定时器1为工作方式2 MOV TH1,#0FDH ;产生9600bps的时间常数 MOV TL1,#0FDH SETB TR1 ;启动定时器1 SETB ES ;串行口开中断 SETB EA ;开中断 MOV DPTR,#ADDRR ;数据缓冲区首址送DPTR MOV R0,#00H ;置传送字节数初值 SJMP $ ;等待中断

145 ;中断服务程序 INTSE2:CLR RI ;清接收中断标志 MOV A,SBUF ;取接收的数据 ;接收的数据送缓冲区 CJNE R0,#7FH,LOOPR ;判别接收完没有 ;若没有,转LOOPR继续接收 CLR ES ;若接收完,则关串行口中断 LJMP ENDR LOOPR:INC R0 ;修改计数值 INC DPTR ;修改地址指针 ENDR: RETI ;中断返回 END 乙机对应的C语言程序请读者参照主机的C语言程序自行编写。

146 【例8-2】 设有甲、乙两台单片机,以工作方式2进行串行通信。每帧为11位,可程控的第9位数据为奇偶校验用的补偶位。编程实现如下所述的应答通信功能:
甲机取一数据,进行奇偶校验后发送。 乙机对收到的数据进行奇偶校验,若补偶正确则乙机向甲机发出应答信息“00H”,代表“数据发送正确”,甲机接收到此信息后再发送下一个字节。若奇偶校验错误,则乙机向甲机发出应答信息“0FFH”,代表“数据不正确”,要求甲机再次发送原数据,直至数据发送正确。 甲机发送128字节数据后停止发送。乙机接收128字节数据。

147 解:甲机与乙机串行通信的流程如图所示。 (a)甲机发送数据流程图

148 (b)乙机接收数据流程图

149 甲机汇编源程序: $INCLUDE (STC15.INC) ;包含STC15F2K60S2单片机寄存器定义文件 ADDRT EQU H ORG 0000H LJMP MAINT ;跳至主程序入口地址 ORG 0023H ;串口1中断服务程序入口 LJMP INTSET ORG 0100H MAINT: MOV SP,#60H MOV PCON,#80H ;波特率加倍 MOV SCON,# B;置工作方式2,并允许接收 MOV DPTR,#ADDRT ;设置数据块首址ADDRT的地址指针 MOV R0,#00H ;设置发送字节初值 SETB ES ;允许串行口中断 SETB EA ;CPU开中断 MOVX ;取第一个发送数据 MOV C,P ;数据补偶 MOV TB8,C MOV SBUF,A ;启动串行口,发送数据 SJMP $

150 ;中断服务程序 INTSET: JB RI,LOOPT1;接收中断?若RI=1,则转接收乙机发送的应答信息 CLR TI ;因RI=0,则必有TI=1,表明是甲机发送数据的中断请求 LJMP ENDT ;甲机发送一数据完毕跳至中断返回程序 LOOPT1: CLR RI ;清接收中断标志 MOV A,SBUF ;取乙机的应答数据 SUBB A,#01H ;判断乙机应答信息是否为“00H” JC LOOPT2 ;数据传送正确,则转LOOPT2 MOVX ;数据传送不正确时,要求重新发送 MOV C,P MOV TB8,C MOV SBUF,A ;启动串行口,重发一次数据 LJMP ENDT ;跳至中断返回程序 LOOPT2:INC DPTR ;修改地址指针,发送下一个数据 INC R0 ;修改发送字节数计数值 MOVX MOV TB8,C ;不能直接使用MOV TB8,P MOV SBUF,A ;启动串行口,发送新的数据 CJNE R0,#80H,ENDT ;数据发送完?若没有发送完,则中断返回 CLR ES ;全部发送完毕,禁止串行口中断 ENDT: RETI ;中断返回 END

151 甲机的C语言程序: #include “stc15.h” //包含STC15F2K60S2单片机寄存器定义文件 unsigned char xdata ADDRT[128]; unsigned char num=0,retval; unsigned char *mypdata; void main (void) { PCON=0x80; SCON=0x90; ES=1; EA=1; mypdata=ADDRT; ACC=*mypdata; //将要发送的数据送到ACC中,以反映奇偶性 TB8=P; //数据补偶,在汇编语言中不能这样用,但在C语言中可以 SBUF=ACC; while(1); }

152 void Serial_ISR(void) interrupt 4
{ if(RI) //若RI=1,说明是接收中断 RI=0; //将中断标志清零 retval = SBUF; //将串行口缓冲器中的内容读到retval中 if(retval!=0) //如果retval不等于0,重新发送原数据 ACC=*mypdata; TB8 = P; SBUF = ACC; } else mypdata++; TB8=P; SBUF=ACC; if(num++ == 0x7F) ES=0; TI = 0;

153 乙机汇编语言程序: $INCLUDE (STC15.INC) ;包含STC15F2K60S2单片机寄存器定义文件 ADDRR EQU 0000H ORG 0000H LJMP MAINR ;主程序入口 ORG 0023H ;串行中断入口地址 LJMP INTSER ;转至串行口中断服务程序 ORG 0100H MAINR:MOV SP,#60H MOV PCON,#80H ;波特率加倍 MOV SCON,# B ;置串行口为工作方式2,允许接收 MOV DPTR,#ADDRR ;数据指针首址 MOV R0,#00H ;接收数据字节数初值 SETB ES ;串行口开中断 SETB EA ;CPU开中断 SJMP $ ;等待中断

154 ;串行口中断服务程序 INTSER: JB RI,LOOPR1 ;若RI=1,则转接收程序入口 CLR TI ;若RI=0,必有TI=1,是发送中断,故应清零 LJMP ENDR ;跳至中断返回程序 LOOPR1:CLR RI ;清接收中断标志 MOV A,SBUF ;读取接收的数据 MOV C,P ;奇偶校验 JC LOOPR2 ;如8位数为奇,则转LOOPR2再检测RB8位 ORL C,RB8 JC LOOPR ;奇偶校验错误时,转LOOPR3 LJMP LOOPR4 ;补偶正确,转LOOPR4 LOOPR2:ANL C,RB8 ;8位数为奇,再检测RB8位 JC LOOPR4 ;RB8=1,补偶正确,转LOOPR4 LOOPR3:MOV A,#0FFH ;发出应答信息“0FFH”给甲机,表明数据不正确 MOV SBUF,A ;将接收的正确数据送数据缓冲区 MOV A,#00H ;数据传送正确,发出应答信息“00H”给甲机 MOV SBUF,A INC R0 ;修改指针 INC DPTR CJNE R0,#80H,ENDR ;若数据没有接收完毕,则跳至中断返回 CLR ES ;接收完毕,关串行口中断 ENDR: RETI ;中断返回 END

155 乙机的C语言程序: #include “stc15.h” //包含STC15F2K60S2单片机寄存器定义文件 unsigned char xdata ADDRR[128]; unsigned char num=0; unsigned char *mypdata; void main (void) { PCON=0x80; SCON=0x90; mypdata=ADDRR; ES=1; EA=1; while(1); }

156 void Serial_ISR(void) interrupt 4
{ if(RI) RI=0; ACC = SBUF; if(P==RB8) //P=RB8时,奇偶校验正确 *mypdata = ACC; //保存数据 SBUF=0x00; //发出信息“0x00” mypdata++; if (num++ == 0x80) ES = 0; } else SBUF = 0xff; //奇偶校验错误,发出信息“0xFF” TI = 0;

157 【例8-3】 多机通信编程举例。 现用简单实例说明多机串行通信中从机的基本工作过程。而实际应用中还需要考虑通信的规范协议。有些协议很复杂,在此不加以考虑。并且,一般情况下,最好使用RS485接口进行多机通信。 假设系统晶振频率为 MHz。

158 设多机单工通信示意图如图所示。 编程实现如下功能: 主机:先向从机发送一帧地址信息,然后再向从机发送10个数据信息。
从机:接收主机发来的地址帧信息,并与本机的地址号相比较,若不符合, 仍保持SM2=1不变;若相等, 则使SM2清零,准备接收后 续的数据信息,直至接收完 10个数据信息。 图 多机单工通讯连线图

159 解:主机和从机的程序流程如图所示。 图8-19 多机单工通信流程图

160 主机汇编语言程序: $INCLUDE (STC15.INC) ;包含STC15F2K60S2单片机寄存器定义文件 ADDRT EQU 0000H SLAVE EQU 5 ;从机地址号 ORG 0000H LJMP MAINT ;主程序入口地址 ORG 0023H LJMP INTST ;串口1中断入口地址 ORG 0100H MAINT:MOV SP,#60H MOV SCON,#0C0H ;串行口方式3 MOV AUXR,#00H ;选择定时器1作为波特率发生器 MOV TMOD,#20H ;置T1工作方式2 MOV TH1,#0FAH ;置4800波特率 MOV TL1,#0FAH ;相应的时间常数 MOV DPTR,#ADDRT ;置数据地址指针 MOV R0,#00H ;发送数据字节计数清0 MOV R2,#SLAVE ;从机地址号→R2 SETB TR1 ;启动T1 SETB ES 串行口开中断 SETB EA ;CPU开中断 SETB TB8 ;置位TB8,作为地址帧信息特征 MOV A,R2 ;发送地址帧信息 MOV SBUF,A SJMP $ ;等待中断

161 ;串行口中断服务程序: INTST:CLR TI ;清发送中断标志 CLR TB8 ;清TB8位,为发送数据帧信息做准备 MOVX ;发送一个数据字节 MOV SBUF,A INC DPTR ;修改指针 INC R0 CJNE R0,#0AH,LOOPT ;判数据字节是否发送完 CLR ES LOOPT:RETI END

162 主机的C语言程序: #include “stc15.h” //包含STC15F2K60S2单片机寄存器定义文件 unsigned char xdata ADDRT[10]; //保存数据的外部RAM单元 unsigned char SLAVE; //保存从机地址号的变量 unsigned char num=0, *mypdata; void main (void) { SCON=0xC0; AUXR=0x0; TMOD=0x20; TH1=0xfa; TL1=0xfa; mypdata=ADDRT; SLAVE=5; //定义从机地址,在此假设从机地址为5 TR1=1; ES=1; EA=1; TB8=1; SBUF=SLAVE; //发送从机地址 while(1); //等待中断 }

163 void Serial_ISR(void) interrupt 4
{ TI=0; TB8=0; SBUF=*mypdata; //发送数据 mypdata++; //修改指针 num++; if(num==0x0a) ES=0; }

164 从机汇编语言程序: $INCLUDE (STC15.INC) ;包含STC15F2K60S2单片机寄存器定义文件 ADDRR EQU 0000H SLAVE EQU 5 ;从机地址号 ORG 0000H LJMP MAINR ;从机主程序入口地址 ORG 0023H LJMP INTSR ;串口1中断入口地址 ORG 0100H MAINR:MOV SP,#60H MOV SCON,#0F0H ;串行口方式3,SM2=1,REN=1,接收状态 MOV AUXR,#00H ;选择定时器1作为波特率发生器 MOV TMOD,#20H ;置T1为工作方式2 MOV TH1,#0FAH ;置4800波特率 MOV TL1,#0FAH ;相应的时间常数 MOV DPTR,#ADDRR ;置数据地址指针 MOV R0,#0AH ;置接收数据字节数指针 SETB TR1 ;启动T1 SETB ES ;串行口开中断 SETB EA ;CPU开中断 SJMP $ ;等待中断

165 INTSR: CLR RI ;清接收中断标志 MOV A,SBUF ;取接收信息 MOV C,RB8 ;取RB8(信息特征位)→C JNC LOOPR1 ;RB8=0为数据帧信息,转 LOOPR1 XRL A,#SLAVE ;RB8=1为地址帧信息,与本机地址号SLAVE比较 JZ LOOPR2 ;地址相等,则转LOOPR2 LJMP ENDR ;地址不相等,则转中断返回ENDR LOOPR2:CLR SM2 ;清SM2,为后面接收数据帧信息做准备 LJMP ENDR ;中断返回 ;接收的数据→数据缓冲区 INC DPTR ;修改地址指针 DJNZ R0,ENDR ;数据字节没全部接收完,则转LOOPR2 SETB SM2 ;全部接收完,置SM2=1 ENDR: RETI ;中断返回 END

166 对应的C语言程序: #include “stc15.h” //包含STC15F2K60S2单片机寄存器定义文件 unsigned char xdata ADDRR[10]; unsigned char SLAVE,num=0x0a,rdata,*mypdata; void main (void) { SCON=0xf0; AUXR=0x0; TMOD=0x20; TH1=0xfa; TL1=0xfa; mypdata=ADDRR; SLAVE=5; //设定从机地址 TR1=1; ES=1; EA=1; while(1); //等待中断 }

167 void Serial_ISR(void) interrupt 4
{ RI=0; rdata=SBUF; //将接收缓冲区的数据保存到rdata变量中 if(RB8) //RB8=1说明收到的信息是地址 if(rdata==SLAVE) //如果地址相等,则SM2=0 SM2=0; } else //接收到的信息是数据 *mypdata=rdata; mypdata++; num--; if(num==0x00) //所有数据接收完毕 SM2=1; //令SM2=1,为下一次接收地址信息做准备

168 进行多机通信时应注意,只有在从机启动以后,处于接收状态,主机才能开始发送信息。
【例8-4】串口1使用独立波特率发生器作串行通信的实例。 #include “stc15.h” //包含STC15F2K60S2寄存器定义文件 #include “intrins.h” #define RELOAD_COUNT 0xfb //Fosc=18.432MHz,12T,SMOD=0,9600bps unsigned char array[9]={0,2,4,6,8,10,12,14,16}; void UART_send(unsigned char i); void delay(void);

169 void main(void) { unsigned char i; //串口初始化 SCON = 0x50; //0101, 位可变波特率,无奇偶校验位 T2H = 0; T2L = RELOAD_COUNT; AUXR = 0x19; // T2R = 1,启动定时器2 // T2_C/ =0,定时器方式 //S1ST2 = 1,选择定时器2作为波特率发生器 ES = 1; //允许串口中断 EA = 1; //开总中断 UART_send(0x34); //串口发送数据表示单片机串口正常工作 UART_send(0xa7); //串口发送数据表示单片机串口正常工作 for(i = 0;i<9;i++) UART_send(array[i]); while(1); }

170 void UART_send(unsigned char i)
{ ES = 0; //关串口中断 TI = 0; //清零串口发送完成中断请求标志 SBUF = i; while(TI ==0); //等待发送完成 ES = 1; //允许串口中断 }

171 void UART_Receive(void) interrupt 4
{ unsigned char k; if(RI==1) RI=0; k=SBUF; UART_send(k+1); } else TI=0;

172 【例8-5】串行口2的使用实例。 利用串行口2发送一组数据。假设晶振频率SYSclk=18.432MHz,波特率为115200bps。发送数据以0作为结束标志。

173 解:假设使用1T方式,汇编语言程序如下: $INCLUDE (STC15.INC) ;包含STC15F2K60S2单片机寄存器定义文件
;定义奇偶校验模式 NONE_PARITY EQU ;无校验 ODD_PARITY EQU ;奇校验 EVEN_PARITY EQU ;偶校验 MARK_PARITY EQU ;Mark校验 SPACE_PARITY EQU ;空检验 PARITYBIT EQU EVEN_PARITY ;测试偶校验 S2RI EQU 01H S2TI EQU 02H S2RB8 EQU 04H S2TB8 EQU 08H BUSY BIT 20H ;传输忙标志

174 ORG H LJMP MAIN ORG H LJMP UART2_ISR ORG H MAIN:CLR BUSY CLR EA MOV SP, #7FH IF PARITYBIT==NONE_PARITY MOV S2CON, #50H ;8位UART ELSEIF (PARITYBIT==ODD_PARITY)||(PARITYBIT==EVEN_PARITY) ||(PARITYBIT==MARK_PARITY) MOV S2CON, #0DAH ;9位UART, 校验位初始值设为1 ELSEIF PARITYBIT==SPACE_PARITY MOV S2CON, #0D2H ;9位UART, 校验位初始值设为0 ENDIF

175 MOV AUXR, #05H ;T2工作于1T模式,T2作为波特率发生器
MOV T2L, #0D8H ;设置波特率发生器自动重装常数低节 MOV T2H, #0FFH ;设置波特率发生器自动重装常数高字 ORL AUXR, #10H ORL IE2, #01H ;允许UART2中断 SETB EA MOV DPTR, #TESTSTR ;数字串首址送DPTR LCALL SENDSTRING ;调用发送子程序 SJMP $ TESTSTR: ;测试数字串 DB "STC15F Uart2 Test!",0DH,0AH,0

176 ;UART2 中断服务子程序 UART2_ISR: PUSH ACC PUSH PSW MOV A, S2CON ;读取UART2控制寄存器 JNB ACC.0, CHECKTI ;检查S2RI位 ANL S2CON, #NOT S2RI ;将S2RI位清0 MOV P0, S2BUF ;在P0口上显示接收到的数据 ANL A, #S2RB ;获得S2RB8 MOV P2, A ;在P2.2上显示奇偶校验位 LJMP ISR_EXIT CHECKTI: JNB ACC.1, ISR_EXIT ;检查S2TI位 ANL S2CON, #NOT S2TI ;将S2TI位清0 CLR BUSY ;将传输忙标志清0 ISR_EXIT: POP PSW POP ACC RETI

177 ;发送一个字节子程序(发送字节存放在ACC中)
SENDDATA: JB BUSY, $ ;等待前一个数据发送结束 JNB P, EVEN1INACC ;根据P标志设置奇偶校验位 ODD1INACC: IF PARITYBIT==ODD_PARITY ANL S2CON, #NOT S2TB8 ;设置奇偶校验位为0 ELSEIF PARITYBIT==EVEN_PARITY ORL S2CON, #S2TB ;设置奇偶校验位为1 ENDIF SJMP PARITYBITOK EVEN1INACC: ANL S2CON, #NOT S2TB8 ;设置奇偶校验位为0 PARITYBITOK: ;奇偶校验位设置完毕 SETB BUSY MOV S2BUF, A ;写数据到UART2缓冲器 RET

178 ;发送数字串子程序(DPTR是数字串的首地址)
SENDSTRING: CLR A MOVC A, @A+DPTR ;读取当前数据 JZ STRINGEND ;检查数字串是否发送完毕(以0作为标志) INC DPTR ;修改地址指针 LCALL SENDDATA ;调用发送字节子程序发送当前字符 SJMP SENDSTRING ;发送下一个字符 STRINGEND: RET END

179 对应的C语言程序如下: #include "stc15.h" #include "intrins.h" typedef unsigned char BYTE; typedef unsigned int WORD; //定义奇偶校验模式 #define NONE_PARITY //无校验 #define ODD_PARITY //奇校验 #define EVEN_PARITY //偶校验 #define MARK_PARITY //Mark校验 #define SPACE_PARITY //空检验 #define PARITYBIT EVEN_PARITY //测试偶校验 #define S2RI 0x01 #define S2TI 0x02 #define S2RB8 0x04 #define S2TB8 0x08 bit busy; void SendData(BYTE dat); void SendString(char *s);

180 void main(void) { #if (PARITYBIT == NONE_PARITY) S2CON = 0x50; //8位可变波特率UART #elif (PARITYBIT == ODD_PARITY) || (PARITYBIT == EVEN_PARITY) || (PARITYBIT == MARK_PARITY) S2CON = 0xda; //9位波特率可变UART, 奇偶校验位设置初值为1 #elif (PARITYBIT == SPACE_PARITY) S2CON = 0xd2; //9位波特率可变UART, 奇偶校验位设置初值为0 #endif AUXR = 0x05; //T2工作于1T模式 T2L=0xD8; //设置波特率发生器自动重装常数低字节 T2H=0xFF; //设置波特率发生器自动重装常数高字节 AUXR|=0x10; IE2 = 0x01; //允许UART2中断 EA = 1; SendString("STC15F\r\nUart2 Test !\r\n"); while(1); }

181 //UART2中断服务程序 void Uart2(void) interrupt 8 using 1 { if (S2CON & S2RI) S2CON &= ~S2RI; //接收中断标志清0 P0 = S2BUF; //在P0口上显示接收到的数据 P2 = (S2CON & S2RB8); //在P2.2上显示奇偶校验位 } if (S2CON & S2TI) S2CON &= ~S2TI; //发送中断标志清0 busy = 0; //发送忙标志清0

182 //发送一个字节子程序 void SendData(BYTE dat) { while (busy); //等待前一个数据发送完毕 ACC = dat; //检测P标志位(PSW.0) if (P) //根据P标志设置奇偶校验位 #if (PARITYBIT == ODD_PARITY) S2CON &= ~S2TB8; //设置奇偶校验位为0 #elif (PARITYBIT == EVEN_PARITY) S2CON |= S2TB8; //设置奇偶校验位为1 #endif } else busy = 1; S2BUF = ACC; //将数据写入UART2缓冲器

183 //发送字符串子函数 void SendString(char *s) { while (*s) //检查字符串结束标志 SendData(*s++); //发送当前字符并修改字符串指针 }

184 二、RS232串行通信接口 在以计算机为中心的数据采集与自动控制系 统中,通常需要用单片机采集数据,然后将数据 用异步串行通信方式传给计算机;要完成的控制 命令由计算机通过串行通信方式传给单片机,由 单片机进行控制。 计算机和单片机之间的串行通信一般采用RS- 232或RS-485总线标准接口。这里介绍RS-232 接口串行通信的设计方法。

185 下面通过一个实例,介绍计算机与单片机进行RS232通信的硬件接口设计和软件设计。
是早期为公用电话网络数据通信而制定的标准。 其逻辑电平与TTL/CMOS电平完全不同。逻辑“0”规定为+5~+15V之间,逻辑“1”规定为-5~-15V之间。 由于RS-232发送和接收之间有公共地,传输采用非平衡模式,因此共模噪声会耦合到信号系统中,标准中建议的最大通信距离为15米。 下面通过一个实例,介绍计算机与单片机进行RS232通信的硬件接口设计和软件设计。

186 【例8-6】 计算机向单片机发送一个数据,单片
机接收到数据后,将接收到的数据按位取反后回 发给计算机。 假设单片机的系统时钟为 MHz,通信 参数为“9600,n,8,1”(这是常见的通信参数 表示方法,即波特率为9600bit/s,8个数据位, 1个停止位,没有奇偶校验)。在计算机上显示 从单片机发送过来的数据。在这种方式中,计算 机通常称为上位机。

187 1、硬件接口设计 从硬件上讲,计算机的串行口是RS-232电平的,而单片机的串口是TTL电平的。因此,必须通过电路实现TTL电平和RS-232电平的转换。 常用的电平转换集成电路是MAX232或者与它兼容转换芯片。该芯片采用单电源(+5V)供电,RS232电平由内部电荷泵产生。

188 图8-20 单片机与计算机进行串行通信的硬件连接
单片机与计算机进行串行通信的硬件连接如图所示。 图8-20 单片机与计算机进行串行通信的硬件连接

189 目前,较新的个人计算机都没有了DB9串行口,特别是笔记本电脑,而USB接口较多。在这种情况下,我们可以使用USB转串口的芯片进行转换,
常见的USB转串口芯片有CH340T、CP2010等。

190 CH340T与单片机的接口电路如图所示。 图8-21 CH340T与单片机的接口电路

191 USB转串口电路只是实现USB传输协议和UART传输协议之间的转换,对于用户而言,程序设计上没有本质的改变,相当于一个串口使用。
唯一需要注意的是,在计算机上编程选择串口的时候,串口号的选择要正确。

192 2、软件设计 软件设计往往因应用系统要求的不同而不同。软件设计分为上位机程序设计和单片机程序设计两部分。如果仅仅为了测试串口的电路连接以及单片机通信程序设计正确与否,上位机程序可以直接使用现成的串口调试助手软件。当然,也可以使用Visual C++等可视化程序开发环境自行设计。 串口调试助手软件可以从

193 如果采用串行口1进行通信,则可以选择定时器1作为波特率发生器,也可以选择定时器2作为波特率发生器,程序设计方法与此类似,请读者自行实验。
下面的单片机程序设计中,利用STC15F2K60S2单片机的串口2和上位计算机通信。 如果采用串行口1进行通信,则可以选择定时器1作为波特率发生器,也可以选择定时器2作为波特率发生器,程序设计方法与此类似,请读者自行实验。

194 汇编语言程序如下(假设系统晶振为11.0592MHz,波特率为9600bit/s):
$INCLUDE (STC15.INC) ;包含STC15F2K60S2单片机寄存器定义文件 BITTEST DATA 20H S2TIbit BIT 01H S2RIbit BIT 00H ORG 0000H LJMP MAIN ORG 0043H LJMP UART2_ISR ORG 0100H MAIN: MOV SP,#60H ;设置堆栈 MOV S2CON,#50H ;8位可变波特率,无奇偶校验位,允许接收 MOV T2L,#0FDH MOV T2H, #0FFH MOV AUXR,#11H ;T2R = 1(启动T2), S1S2 = 1 MOV IE2, #01H ;允许串口2中断,ES2=1 SETB EA SJMP $

195 UART2_ISR: MOV BITTEST,S2CON;将S2CON保存到20H单元以便位寻址 JBC S2RIbit,RDATA;若是接收中断,则将S2RI清零 CLR S2TIbit ;否则就是发送中断,将S2TI清零 LJMP RETURN RDATA: MOV A,S2BUF ;读取收到的数据 CPL A MOV S2BUF ,A ;将收到的数据发送回去 RETURN: MOV S2CON,BITTEST ;该语句可以起到中断标志清零的作用 RETI END

196 对应的C语言程序如下: #include “stc15.h” //包含STC15F2K60S2单片机寄存器定义文件 char bdata bittest; //为了保存中断标志 sbit TIbit=bittest^1; //第1位 sbit RIbit=bittest^0; //第0位 void main(void) { S2CON=0x50; T2L=0xFD; T2H-0xFF; AUXR=0x11; IE2=0x01; EA=1; while(1); }

197 void UART2_ISR(void) interrupt 8
{ unsigned char tmpdata; bittest=S2CON; if (RIbit) RIbit = 0; tmpdata=S2BUF; S2BUF=~tmpdata; } else TIbit=0; S2CON=bittest; //清0中断标志

198 三、RS485串行通信接口 RS-485串行数据接口是为弥补RS-232通信距离短、速率低等缺点而产生的。 在RS-422基础上制定的标准,增加了多点、双向通信能力,即允许多个发送器连接到同一条总线上,同时增加了发送器的驱动能力和冲突保护特性。RS-485标准只规定了平衡发送器和接收器的电特性,而没有规定接插件、传输电缆和应用层通信协议。

199 RS-485 RS-485数据信号采用差分传输方式,也称作平衡传输,它使用一对双绞线,将其中一线定义为A,另一线定义为B,A、B之间的正电平在+2V~+6 V,表示逻辑状态“l”;负电平在-2V~-6 V,表示逻辑状态“0”。 RS-485标准的最大传输距离约为1200米,最大传输速率为10Mbps。

200 RS-485 通常,RS-485网络采用平衡双绞线作为传输介质。平衡双绞线的长度与传输速率成反比,只有在20 kbps速率以下,才可能使用规定最长的电缆长度。只有在很短的距离下才能获得最高速率传输。 一般来说,100米长的双绞线最大传输速率仅为1Mbps。如果采用光电隔离方式,则通信速率一般还会受到光电隔离器件响应速度的限制。

201 RS-485 利用RS-485标准,可以建立一个相对经济、具有高噪声抑制、高传输速率的通信平台,该平台同时具有传输距离远、宽共模范围、控制方便等优点。 目前,在工程应用的现场网络中,RS-485半双工异步通信总线被广泛应用在集中控制枢纽与分散控制单元之间通信的场合。

202 一台计算机作为主机,通过RS-485连接现场的控制单元,系统结构如图所示。

203 图8-24 MAX3082的结构及典型的半双工通信电路图
RS-485接口芯片可以使用半双工传输的MAX3082(或者其他RS485接口芯片,如MAX487)。 MAX3082的结构及典型的半双工通信电路图如图所示。 在图中,单片机接收 数据时,应通过指令将 P1.0清0;单片机发送 P1.0置1。 图8-24 MAX3082的结构及典型的半双工通信电路图

204 连接计算机的RS-232和RS-485转换电路如图所示。

205 四、SPI通信接口 1、SPI接口简介 STC15F2K60S2集成了串行外设接口(Serial Peripheral Interface,简称SPI)。 SPI接口既可以和其他微处理器通信,也可以与具有SPI兼容接口的器件,如存储器、A/D转换器、D/A转换器、LED或LCD驱动器等进行同步通信。

206 SPI接口有两种操作模式:主模式和从模式。
在主模式中支持高达3Mbit/s的速率; 从模式时速度无法太快,速度在SYSclk/8以内较好。 此外,SPI接口还具有传输完成标志和写冲突标志保护功能。

207 图8-26 STC15F2K60S2单片机的SPI功能方框图

208 说明 SPI的核心是一个8位移位寄存器和数据缓冲器,数据可以同时发送和接收。在SPI数据的传输过程中,发送和接收的数据都存储在缓冲器中。
对于主模式,若要发送一个字节数据,只需将这个数据写到SPIDAT寄存器中。主模式下/SS信号不是必须的。 在从模式下,必须在/SS信号变为有效并接收到合适的时钟信号后,方可进行数据的传输。在从模式下,如果一个字节传输完成后,/SS信号变为高电平,这个字节立即被硬件逻辑标志为接收完成,SPI接口准备接收下一个数据。

209 3、SPI接口的数据通信 (1)SPI接口的信号 MISO(与P1.4共用) MOSI(与P1.3共用) SCLK(与P1.5) /SS(与P1.2共用) 4根信号线构成。SPI接口的引脚可以切换。

210 MOSI(Master Out Slave In,主出从入)
主器件的输出和从器件的输入,用于主器件到从器件的串行数据传输。 根据SPI规范,多个从机共享一根MOSI信号线。在时钟边界的前半周期,主机将数据放在MOSI信号线上,从机在该边界处获取该数据。

211 MISO(Master In Slave Out,主入从出)
从器件的输出和主器件的输入。用于实现从器件到主器件的数据传输。 SPI规范中,一个主机可连接多个从机,因此,主机的MISO信号线会连接到多个从机上,或者说,多个从机共享一根MISO信号线。 当主机与一个从机通信时,其他从机应将其MISO引脚驱动置为高阻状态。

212 SCLK(SPI Clock,串行时钟信号)
串行时钟信号是主器件的输出和从器件的输入,用于同步主器件和从器件之间在MOSI和MISO线上的串行数据传输。 当主器件启动一次数据传输时,自动产生8个SCLK时钟周期信号给从机。在SCLK的每个跳变处(上升沿或下降沿)移出一位数据。 一次数据传输可以传输一个字节的数据。

213 SCLK、MOSI和MISO通常用于将两个或更多个SPI器件连接在一起
如果SPI接口被禁止,即特殊功能寄存器SPCTL中的SPEN=0(复位值),这些管脚都可作为I/O口使用。

214 (Slave Select,从机选择信号)
这是一个输入信号。主器件用它来选择处于从模式的SPI模块。 在主模式下,SPI接口只能有一个主机,不存在主机选择问题。在该模式下/SS不是必须的。主模式下通常将主机的/SS引脚通过10kΩ的电阻上拉高电平。每一个从机的/SS接主机的I/O口,由主机控制电平高低,以便主机选择从机。 在从模式下,不论发送还是接收,/SS信号必须有效。因此在一次数据传输开始之前必须将/SS拉为低电平。SPI主机可以使用I/O口选择一个SPI器件作为当前的从机。

215 SPI从器件通过其/SS脚确定是否被选择。如果满足下面的条件之一,就被忽略:
如果SPI功能被禁止,即SPEN位为0(复位值); 如果SPI配置为主机,即MSTR位为1,并且P1.4配置为输出(P1M0.4=0、P1M1.4=1); 如果/SS脚被忽略,即SSIG位为1,该脚配置用于I/O口功能。 注:即使SPI被配置为主机(MSTR=1),仍然可以 通过拉低/SS脚配置为从机(如果P1.4配置为输入且 SSIG=0)。要使能该特性,应当置位SPIF (SPSTAT.7)。

216 STC15F2K60S2单片机的SPI接口的数据通信方式有3种:
单主机-单从机方式 双器件方式(器件可互为主机和从机) 单主机-多从机方式。

217 1)单主机-单从机方式 单主机-单从机方式的连接如图所示。 图8-27 SPI接口的单主机-单从机连接方式

218 在图中,从机的SSIG(SPCTL.7)为0,用于选择从机。 SPI主机可使用任何端口位(包括P1.4/ )来控制从机的 脚。

219 主机SPI与从机SPI的8位移位寄存器连接成一个循环的16位移位寄存器。
当主机程序向SPDAT写入一个字节时,立即启动一个连续的8位移位通信过程:主机的SCLK引脚向从机的SCLK引脚发出一串脉冲,在这串脉冲的驱动下,主机SPI的8位移位寄存器中的数据移到了从机SPI的8位移位寄存器中。与此同时,从机SPI的8位移位寄存器中的数据移到了主机SPI的8位移位寄存器中。由此,主机既可向从机发送数据,又可读从机中的数据。

220 双器件方式也称为互为主从方式,其连接方式如图所示。
2)双器件方式 双器件方式也称为互为主从方式,其连接方式如图所示。 图8-28 SPI接口的双器件连接方式

221 在图中,两个器件可以互为主从。当没有发生SPI操作时,两个器件都可配置为主机(MSTR=1),将SSIG清零并将P1
在图中,两个器件可以互为主从。当没有发生SPI操作时,两个器件都可配置为主机(MSTR=1),将SSIG清零并将P1.4( )配置为准双向模式。当其中一个器件启动传输时,可将P1.4配置为输出并驱动为低电平,这样就强制另一个器件变为从机。

222 双方初始化时将自己设置成忽略/SS脚的SPI从模式。当一方要主动发送数据时,先检测/SS脚的电平,如果/SS脚是高电平,就将自己设置成忽略/SS脚的主模式。
通信双方平时将SPI置成没有被选中的从模式。在该模式下,MISO、MOSI、SCLK均为输入,当多个MCU的SPI接口以此模式并联时不会发生总线冲突。这种特性在互为主从、一主多从等应用中很有用。 注意,互为主从模式时,双方的SPI速率必须相同。如果使用外部晶体振荡器,双方的晶体频率也要相同。

223 3)单主机-多从机方式 单主机-多从机方式的连接如图所示。 图8-29 SPI接口的单主机-多从机连接方式

224 在图中,从机的SSIG(SPCTL.7)为0,从机通过对应的/SS信号被选中。SPI主机可使用任何端口位(包括P1.4)来控制从机的/SS。

225 STC15F2K60S2单片机进行SPI通信时,主机和从机的选择由SPEN、SSIG、引脚(P1
STC15F2K60S2单片机进行SPI通信时,主机和从机的选择由SPEN、SSIG、引脚(P1.2)和MSTR联合控制。主机和从机的选择如表所示。 表8-5 主机和从机的选择 SPEN SSIG P1.2 MSTR 主或从模式 MISO P1.4 MOSI P1.3 SCLK P1.5 备 注 X SPI功能禁止 SPI禁止。P1.4/P1.5/P1.6/P1.7作为普通I/O口使用 1 从机模式 输出 输入 选择作为从机 未被选中 高阻 未被选中。MISO为高阻状态,以避免总线冲突 1→0 处于输入模式时,如被驱动为低电平且SSIG=0,MSTR位自动清零。 主 (空闲) 当主机空闲时MOSI和SCLK为高阻态以避免总线冲突。用户必须将SCLK上拉或下拉(根据CPOL的取值)以避免SCLK出现悬浮状态。 主 (激活) 作为主机激活时,MOSI 和SCLK 为推挽输出

226 (3)SPI接口的数据通信过程 作为从机时,若CPHA=0,SSIG必须为0,/SS引脚必须取反并且在每个连续的串行字节之间重新设置为高电平。 如果SPDAT寄存器在/SS有效(低电平)时执行写操作,那么将导致一个写冲突错误,WCOL标志被置1。CPHA=0且SSIG=0时的操作未定义。 当CPHA=1时,SSIG可以为1或0。如果SSIG=0,/SS引脚可在连续传输之间保持有效(即一直为低电平)。当系统中只有一个SPI主机和一个SPI从机时,这是首选配置。

227 在SPI通信中,数据传输总是由主机启动的。如果SPI使能(SPEN=1),主机对SPI数据寄存器的写操作将启动SPI时钟发生器和数据的传输。在数据写入SPDAT之后的半个到一个SPI位时间后,数据将出现在MOSI引脚。 需要注意的是,主机可以通过将对应器件的/SS引脚驱动为低电平实现与之通信。写入主机SPDAT寄存器的数据从MOSI引脚移出发送到从机的MOSI引脚。同时,从机SPDAT寄存器的数据从MISO引脚移出发送到主机的MISO引脚。

228 传输完一个字节后,SPI 时钟发生器停止,传输完成标志(SPIF)置位并产生一个中断(如果SPI中断使能)。
主机和从机CPU的两个移位寄存器可以看作是一个16位循环移位寄存器。当数据从主机移位传送到从机的同时,数据也以相反的方向移入。这意味着在一个移位周期中,主机和从机的数据相互交换。

229 (4)通过/SS改变模式 如果SPEN=1,SSIG=0且MSTR=1,SPI使能为主机模式。/SS引脚可配置为输入或准双向模式。这种情况下,另外一个主机可将该引脚驱动为低电平,从而将该器件选择为SPI从机并向其发送数据。

230 为了避免争夺总线,SPI系统执行以下动作:
MSTR清0并且CPU变成从机。这样SPI就变成从机。MOSI和SCLK强制变为输入模式,而MISO则变为输出模式。 SPSTAT的SPIF标志位置位。如果SPI中断已被使能,则产生SPI中断。 用户程序必须一直对MSTR位进行检测,如果该位被一个从机选择清零而用户想继续将SPI作为主机,就必须重新置位MSTR,否则将进入从机模式。

231 (5)SPI中断 如果允许SPI中断,发生SPI中断时,CPU就会跳转到中断服务程序的入口地址004BH处执行中断服务程序。 注意,在中断服务程序中,必须把SPI中断请求标志清0。

232 (6)写冲突 SPI在发送时为单缓冲,在接收时为双缓冲。这样在前一次发送尚未完成之前,不能将新的数据写入移位寄存器。 当发送过程中对数据寄存器进行写操作时,WCOL位将置位以指示数据冲突。在这种情况下,当前发送的数据继续发送,而新写入的数据将丢失。

233 当对主机或从机进行写冲突检测时,主机发生写冲突的情况是很罕见的,因为主机拥有数据传输的完全控制权。但从机有可能发生写冲突,因为当主机启动传输时,从机无法进行控制。
接收数据时,接收到的数据传送到一个并行读数据缓冲区,这样将释放移位寄存器以进行下一个数据的接收。但必须在下个字符完全移入之前从数据寄存器中读出接收到的数据,否则,前一个接收数据将丢失。 WCOL可通过软件向其写入“1”清0。

234 (7)数据格式 时钟相位控制位CPHA用于设置采样和改变数据的时钟边沿。 时钟极性控制位CPOL用于设置时钟极性。

235 不同的CPHA,主机和从机对应的数据格式如图所示。
图8-30 CPHA=0时SPI从机传输格式

236 CPHA=1时SPI从机传输格式 图8-31 CPHA=1时SPI从机传输格式

237 CPHA=0时SPI主机传输格式 图8-32 CPHA=0时SPI主机传输格式

238 CPHA=1时SPI主机传输格式 图8-33 CPHA=1时SPI主机传输格式

239 (8)SPI时钟预分频器选择 SPI时钟预分频器选择是通过SPCTL寄存器中的SPR1-SPR0位实现的。 详见特殊功能寄存器SPCTL的介绍。

240 SPICTL(地址为CEH,复位值为00H)各位的定义如下:
1)SPI控制寄存器(SPCTL) SPICTL(地址为CEH,复位值为00H)各位的定义如下: 位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 SSIG SPEN DORD MSTR CPOL CPHA SPR1 SPR0

241 0:由/SS脚用于确定器件为主机还是从机。/SS脚可作为I/O口使用。
位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 SSIG SPEN DORD MSTR CPOL CPHA SPR1 SPR0 ①位7:SSIG,引脚忽略控制位。 1:由MSTR位确定器件为主机还是从机。 0:由/SS脚用于确定器件为主机还是从机。/SS脚可作为I/O口使用。

242 0:SPI被禁止,所有SPI管脚都作为I/O口使用。
位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 SSIG SPEN DORD MSTR CPOL CPHA SPR1 SPR0 ②位6:SPEN,SPI使能位。 1:SPI使能。 0:SPI被禁止,所有SPI管脚都作为I/O口使用。

243 ③位5:DORD,设定数据发送和接收的位顺序。 1:数据字的最低位(LSB)最先传送; 0:数据字的最高位(MSB)最先传送。
位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 SSIG SPEN DORD MSTR CPOL CPHA SPR1 SPR0 ③位5:DORD,设定数据发送和接收的位顺序。 1:数据字的最低位(LSB)最先传送; 0:数据字的最高位(MSB)最先传送。 ④位4:MSTR,SPI主/从模式选择位。

244 1:SPI空闲时SCK=1。SCK的前时钟沿为下降沿而后沿为上升沿。 0:SPI空闲时SCK=0。SCK的前时钟沿为上升沿而后沿为下降沿。
位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 SSIG SPEN DORD MSTR CPOL CPHA SPR1 SPR0 ⑤位3:CPOL,SPI时钟极性。 1:SPI空闲时SCK=1。SCK的前时钟沿为下降沿而后沿为上升沿。 0:SPI空闲时SCK=0。SCK的前时钟沿为上升沿而后沿为下降沿。

245 ⑥位2:CPHA,SPI时钟相位选择控制。 1:数据在SCK的前时钟沿驱动到SPI口线,SPI模块在后时钟沿采样。
位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 SSIG SPEN DORD MSTR CPOL CPHA SPR1 SPR0 ⑥位2:CPHA,SPI时钟相位选择控制。 1:数据在SCK的前时钟沿驱动到SPI口线,SPI模块在后时钟沿采样。 0:数据在/SS为低(SSIG=0)时驱动到SPI口线,在SCK的后时钟沿被改变,并在前时钟沿被采样。(注:SSIG=1时的操作未定义)

246 ⑦位1:SPR1,与SPR0联合构成SPI时钟速率选择控制位。 ⑧位0:SPR0,与SPR1联合构成SPI时钟速率选择控制位。
位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 SSIG SPEN DORD MSTR CPOL CPHA SPR1 SPR0 ⑦位1:SPR1,与SPR0联合构成SPI时钟速率选择控制位。 ⑧位0:SPR0,与SPR1联合构成SPI时钟速率选择控制位。

247 SPI时钟选择如表8-6所示。 表8-6 SPI时钟频率的选择 SPR1 SPR0 时钟(SCLK) tCLK/4 1 tCLK/16
tCLK/4 1 tCLK/16 tCLK/64 tCLK/128

248 SPSTAT(地址为CDH,复位值为00XXXXXXB)各位的定义如下:
2)SPI状态寄存器(SPSTAT) SPSTAT(地址为CDH,复位值为00XXXXXXB)各位的定义如下: 位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 SPIF WCOL -

249 位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 SPIF WCOL - ①位7:SPIF,SPI传输完成标志。 当一次传输完成时,SPIF被置位。此时,如果SPI中断被打开(即ESPI(IE2.1)=1,EA(IE.7)=1),将产生中断。当SPI处于主模式且SSIG=0时,如果为输入并被驱动为低电平,SPIF也将置位,表示“模式改变”。 SPIF标志通过软件向其写入1而清0。

250 当一个数据还在传输时,又向数据寄存器SPDAT写入数据,WCOL将被置位。 WCOL 标志通过软件向其写入1而清0。 ③位5-位0:保留。
位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 SPIF WCOL - ②位6:WCOL,SPI写冲突标志。 当一个数据还在传输时,又向数据寄存器SPDAT写入数据,WCOL将被置位。 WCOL 标志通过软件向其写入1而清0。 ③位5-位0:保留。

251 SPDAT(地址为CFH,复位值为00H)各位的定义如下:
3)SPI数据寄存器(SPDAT) SPDAT(地址为CFH,复位值为00H)各位的定义如下: 位7-位0:保存SPI通信数据字节。其中,MSB为最高位,LSB为最低位。 位号 D7 D6 D5 D4 D3 D2 D1 D0 位名称 MSB LSB

252 SPI接口的使用包括SPI接口的初始化和SPI中断服务程序的编写。 SPI接口的初始化包括以下几个方面:
(2)编程实例 SPI接口的使用包括SPI接口的初始化和SPI中断服务程序的编写。 SPI接口的初始化包括以下几个方面: 通过SPI控制寄存器SPCTL设置:/SS引脚的控制、SPI使能、数据传送的位顺序、设置为主机或从机、SPI时钟极性、SPI时钟相位、SPI时钟选择。具体内容请参见SPI控制寄存器SPCTL介绍。

253 清0寄存器SPSTAT中的标志位SPIF和WCOL(向这两个标志位写1即可清零)。
开放SPI中断(IE2中的ESPI=1,IE2寄存器不能位寻址,可以使用“或”指令)。 开放总中断(IE中的EA=1)。 SPI中断服务程序根据实际需要进行编写。唯一需要注意的是,在中断服务程序中首先需要将标志位SPIF和WCOL清0。因为SPI中断标志不会自动清除。

254 从单片机的SPI口收到数据后,把收到的数据放到自己的SPDAT寄存器中,当下一次主单片机发送一个字节时把数据发回到主单片机。
【例8-7】 单主机-多从机通信方式应用举例。 计算机向主单片机发送一串数据,主单片机的RS-232串口每收到一个字节就立刻将收到的字节通过SPI口发送到从单片机中,与此同时主单片机收到从单片机发回的一个字节,主单片机把收到的这个字节通过RS-232口发送到计算机。可以使用串口助手观察结果。 从单片机的SPI口收到数据后,把收到的数据放到自己的SPDAT寄存器中,当下一次主单片机发送一个字节时把数据发回到主单片机。

255 硬件连接如图所示。 图8-34 单主机-单从机SPI通信实验电路图

256 晶振频率SYSclk=18.432MHz,计算机RS232串口波特率设置为57600bps。
解:经计算,当SYSclk=18.432MHz,PCON.7=0(波特率不加倍),波特率为57600bps时的重装时间常数为F6H。在主机的主程序中,使用查询的方法查询UART口是否接收到数据。

257 汇编语言程序如下: $INCLUDE (STC15.INC) ;包含STC15F2K60S2寄存器定义文件 ;定义常量,根据MASTER_SLAVE的值,选择下载不同的程序 MASTER_SLAVE EQU ;汇编后的程序代码下载到主单片机中 ;MASTER_SLAVE EQU ;汇编后的程序代码下载到从单片机#1中 ;MASTER_SLAVE EQU ;汇编后的程序代码下载到从单片机#2中 ;定义变量 Flags EQU 20H SPI_Receive EQU Flags ;SPI 端口收到数据标志位 T0_10MS EQU 30H ;该变量用于保存 10 毫秒计数(T0 中断次数) SPI_buffer EQU 31H ;该变量用于保存 SPI 端口收到的数据

258 ORG 0000H LJMP MAIN ORG 000BH ;定时器0 中断服务程序入口 LJMP T0_ISR ORG 004BH ;SPI中断服务程序入口 LJMP SPI_ISR ORG 0060H MAIN: MOV SP, #70H ;设置堆栈指针 ; 初始化串口和定时器 MOV SCON, #50H ;0101,0000 8位可变波特率, 无奇偶校验 MOV TMOD, #21H ;T1为自动重装模式,T0为16位定时器模式 MOV TH0, #0C4H MOV TL0, #00H ;重装数 = = = C400H ;晶振频率=18.432MHz时,每10mS中断1次 MOV TH1, #0F6H MOV TL1, #0F6H MOV AUXR, # B ;T1 以 1T 的速度计数,是普通8051的12倍 ;即波特率 = 4800*12=57600 SETB TR ;启动定时器1 开始计数 SETB TR ;启动T0 SETB ET ;开T0中断

259 ;----------------初始化SPI--------------------------------
IF MASTER_SLAVE == ;主机SPI控制字设置 MOV SPCTL,# B ;0FCH, 忽略脚, 设为主机 ;SSIG=1: 忽略脚;SPEN=1:允许SPI工作 ;DORD=1:先传低位LSB;MSTR=1:设为主机 ;CPOL=0:SPI 空闲时SCLK=0,前跳变沿是上升沿,后跳变沿是下降沿。 ;CPHA=0:数据由SCLK后跳变沿驱动到SPI口线,SPI模块在前跳变沿采样 ;SPR1,SPR0=00:主模式时SPI时钟源选择为Fosc/4 ELSE ;从机SPI控制字设置 MOV SPCTL,# B ;6CH, 设为从机, 由脚决定是否已被选中 ;SSIG=0: 由脚决定主模式或从模式;SPEN=1:允许 SPI 工作 ;DORD=1:先传低位 LSB;MSTR=0:设为从机 ;SPR1,SPR0 = 00:主模式时 SPI 时钟源选择为 Fosc/4 ENDIF

260 MOV SPSTAT,#11000000B ;清零标志位SPIF和WCOL
ORL IE2, # B ;令ESPI(IE2.1)=1,允许SPIF产生中断 MOV Flags, # ;清标志字 SETB EA ;开总中断 MOV T0_10MS,# ;T0中断计数(10ms×200=2秒) IF MASTER_SLAVE == 0 CLR Slave1_SS ;选择从单片机 #1 为当前的从单片机 Check_RS232: JNB RI, Check_SPI ;判断RS232串口中收到数据否 MOV A, SBUF ;取RS232串口中收到的数据累加器A CLR RI

261 ;主单片机将累加器 A 中的数据发送到从机SPI
ANL IE2,#0FDH ; 令ESPI(IE2.1)=0,禁止SPIF产生中断 MOV SPDAT, A ;SPI 发送数据 SPI_Wait: MOV A, SPSTAT ;等待SPIF=1, 即等待SPI发送完毕 ANL A, #80H JZ SPI_Wait ORL IE2, # B ;令ESPI(IE2.1)=1,允许SPIF产生中断 LJMP Check_RS232 Check_SPI: JNB SPI_Receive, Check_RS232 ;判是否收到从机SPI发回数据

262 ;主单片机SPI端口收到新的数据 MOV A, SPI_buffer ;将"从机SPI发回的数据"送到累加器A CLR SPI_Receive ;清零主单片机SPI端口收到数据标志位 ;将累加器 A 中的数据发送到计算机 CLR TI ;清零串口发送中断标志 MOV SBUF, A RS232_Wait: JNB TI, RS232_Wait ;等待发送完毕 CLR TI ;清零串口发送中断标志 LJMP Check_RS232 ELSE Slave_Check_SPI: JNB SPI_Receive, Slave_Check_SPI ;判收到主 SPI 发回的数据否

263 ;从单片机SPI端口收到新的数据 MOV A, SPI_buffer ;取 "主单片机 SPI 端口发的数据" CLR SPI_Receive ;清零从单片机 SPI 端口收到数据标志位 IF MASTER_SLAVE == 2 ADD A, # ;如果是从单片机 #2,就把收到的数据加1 ENDIF MOV SPDAT, A ;将收到数据送 SPDAT,下一次通讯时发回 SJMP Slave_Check_SPI

264 ;-------------- T0中断服务程序 --------------------------------
IF MASTER_SLAVE == 0 T0_ISR: PUSH PSW ;保存断点现场 PUSH ACC MOV TH0, #0C4H ;重装时间常数 MOV TL0, #00H DJNZ T0_10MS,T0_Exit MOV T0_10MS,# ;恢复T0中断计数值 CPL Slave1_SS ;改变当前选择的从单片机 CPL Slave2_SS T0_Exit: POP ACC ;恢复断点现场 POP PSW RETI

265 ELSE ;从机程序不需要定时器T0 T0_ISR: RETI ENDIF ; SPI中断服务程序 SPI_ISR: ;SPI中断服务程序 MOV SPSTAT, # B ;0C0H,清零标志位SPIF和WCOL MOV A, SPDAT ;保存收到的数据 MOV SPI_buffer, A SETB SPI_Receive ;设置SPI 端口收到数据标志 ; END 思考:将上述程序改编为C语言版本。

266 【例8-8】 单主机-多从机通信方式应用举例。
主单片机用P5.1和P5.2选择当前选中的从单片机,每一时刻只有一个从单片机被选中。 P5.1用于选中#1从单片机; P5.2用于选中#2从单片机。 计算机向主单片机发送一串数据,主单片机的RS-232串行口每收到一个字节就立刻将收到的数据字节通过SPI口发送到当前选中的从单片机中,#1单片机将SPI口收到的数据再放到自己的SPDAT寄存器中,当下一次主单片机发送一个字节时把数据发回到主单片机;#2从单片机将SPI口收到的数据加1以后再放到自己的 SPDAT寄存器中,当下一次主单片机发送一个字节时把数据发回到主单片机。 #1从单片机和#2从单片机每隔2秒钟轮换一次。主单片机把收到的这个字节通过 RS-232口发送到计算机。在串行口调试助手接收区观察接收的数据。

267 硬件连接如图8-35所示。 图8-35 单主机-多从机SPI通信实验电路图

268 晶振频率SYSclk=18.432MHz,计算机RS232串行口波特率设置为57600bps。
解:经计算,当SYSclk=18.432MHz,PCON.7=0(波特率不加倍),波特率为57600bps时的重装时间常数为F6H。在主机的主程序中,使用查询的方法查询UART口是否接收到数据。

269 汇编语言程序如下: $INCLUDE (STC15.INC) ;包含STC15F2K60S2寄存器定义文件 ;定义常量,根据MASTER_SLAVE的值,选择下载不同的程序 MASTER_SLAVE EQU ;汇编后的程序代码下载到主单片机中 MASTER_SLAVE EQU ;汇编后的程序代码下载到从单片机#1中 MASTER_SLAVE EQU ;汇编后的程序代码下载到从单片机#2中 ;定义变量 Slave1_SS EQU P5.1 Slave2_SS EQU P5.2 Flags EQU 20H SPI_Receive EQU Flags ;SPI 端口收到数据标志位 T0_10MS EQU 30H ;该变量用于保存 10 毫秒计数(T0 中断次数) SPI_buffer EQU 31H ;该变量用于保存 SPI 端口收到的数据

270 ORG 0000H LJMP MAIN ORG 000BH ;定时器0 中断服务程序入口 LJMP T0_ISR ORG 004BH ;SPI中断服务程序入口 LJMP SPI_ISR ORG 0060H MAIN: MOV SP, #70H ;设置堆栈指针 ; 初始化串行口和定时器 MOV SCON, #50H ;0101,0000 8位可变波特率, 无奇偶校验 MOV TMOD, #21H ;T1为自动重装模式,T0为16位定时器模式 MOV TH0, #0C4H MOV TL0, #00H ;重装数 = = = C400H ;晶振频率=18.432MHz时,每10mS中断1次 MOV TH1, #0F6H MOV TL1, #0F6H MOV AUXR, #40H ;T1以1T速度计数,波特率=4800*12=57600 SETB TR ;启动定时器1 开始计数 SETB TR ;启动T0 SETB ET ;开T0中断

271 ;----------------初始化SPI--------------------
IF MASTER_SLAVE == ;主机SPI控制字设置 MOV SPCTL,# B ELSE ;从机SPI控制字设置 MOV SPCTL,# B ENDIF MOV SPSTAT,# B ;清0标志位SPIF和WCOL ORL IE2, # B ;令ESPI(IE2.1)=1,允许SPIF产生中断 MOV Flags, # ;清标志字 SETB EA ;开总中断 MOV T0_10MS,# ;T0中断计数(10ms×200=2秒) IF MASTER_SLAVE == 0 CLR Slave1_SS ;选择从单片机 #1 为当前的从单片机 Check_RS232: JNB RI, Check_SPI ;判断RS232串行口中收到数据否 MOV A, SBUF ;取RS232串行口中收到的数据累加器A CLR RI

272 ;主单片机将累加器 A 中的数据发送到从机SPI
ANL IE2,#0FDH ;令ESPI(IE2.1)=0,禁止SPIF产生中断 MOV SPDAT, A ;SPI 发送数据 SPI_Wait: MOV A, SPSTAT ;等待SPIF=1, 即等待SPI发送完毕 ANL A, #80H JZ SPI_Wait ORL IE2, # B ;令ESPI(IE2.1)=1,允许SPIF产生中断 LJMP Check_RS232 Check_SPI: JNB SPI_Receive, Check_RS232 ;判是否收到从机SPI发回数据

273 ;主单片机SPI端口收到新的数据 MOV A, SPI_buffer ;将"从机SPI发回的数据"送到累加器A CLR SPI_Receive ;清0主单片机SPI端口收到数据标志位 ;将累加器 A 中的数据发送到计算机 CLR TI ;清0串行口发送中断标志 MOV SBUF, A RS232_Wait: JNB TI, RS232_Wait ;等待发送完毕 CLR TI ;清0串行口发送中断标志 LJMP Check_RS232 ELSE Slave_Check_SPI: JNB SPI_Receive, Slave_Check_SPI;收到主SPI发回的数据否 ;从单片机SPI端口收到新的数据 MOV A, SPI_buffer ;取 "主单片机 SPI 端口发的数据" CLR SPI_Receive ;清0从单片机 SPI 端口收到数据标志位 IF MASTER_SLAVE == 2 ADD A, # ;如果是从单片机 #2,就把收到的数据加1 ENDIF MOV SPDAT, A ;将收到数据送SPDAT, 准备下一次通讯时发回 SJMP Slave_Check_SPI

274 ;-------------- T0中断服务程序 ----------------------
IF MASTER_SLAVE == 0 T0_ISR: PUSH PSW ;保存断点现场 PUSH ACC MOV TH0, #0C4H ;重装时间常数 MOV TL0, #00H DJNZ T0_10MS,T0_Exit MOV T0_10MS,# ;恢复T0中断计数值 CPL Slave1_SS ;改变当前选择的从单片机 CPL Slave2_SS T0_Exit: POP ACC ;恢复断点现场 POP PSW RETI

275 ELSE ;从机程序不需要定时器T0 T0_ISR: RETI ENDIF ; SPI中断服务程序 SPI_ISR: ;SPI中断服务程序 MOV SPSTAT, # B ;0C0H,清0标志位SPIF和WCOL MOV A, SPDAT ;保存收到的数据 MOV SPI_buffer, A SETB SPI_Receive ;设置SPI 端口收到数据标志 ; END

276 双器件通信方式就是可以互为主机和从机的通信方式。
【例8-9】 双器件通信方式应用举例。 双器件通信方式就是可以互为主机和从机的通信方式。 主单片机用P1.2和P1.3选择当前选中的从单片机,每一时刻只有一个从单片机被选中。 P1.2用于选中#1从单片机;P1.3用于选中#2从单片机。

277 计算机向主单片机发送一串数据,主单片机的RS-232串口每收到一个字节就立刻将收到的字节通过SPI口发送到当前选中的从单片机中,#1单片机将SPI口收到的数据再放到自己的SPDAT寄存器中,当下一次主单片机发送一个字节时把数据发回到主单片机; #2从单片机将SPI口收到的数据加1以后再放到自己的 SPDAT寄存器中,当下一次主单片机发送一个字节时把数据发回到主单片机。#1从单片机和#2从单片机每隔2秒钟轮换一次。 主单片机把收到的这个字节通过 RS232口发送到计算机。在串口调试助手接收区观察接收的数据。

278 晶振频率SYSclk=18.432MHz,计算机RS232串口波特率设置为57600bps。 硬件连接如图8-36所示。
图8-36 互为主/从通信方式电路图

279 解:经计算,当SYSclk=18.432MHz,PCON.7=0(波特率不加倍),波特率为57600bps时的重装时间常数为F6H。
在主机的主程序中,使用查询的方法查询UART口是否接收到数据。

280 $INCLUDE (STC15.inc) ;包含STC15F2K60S2寄存器定义文件
SS EQU P ;定义SPI的脚 ; 定义 SPI 模式常量 CONFIG_MASTER EQU B ;忽略 SS 脚的主模式 CONFIG_SLAVE EQU B ;SS脚用于确定器件为主机还是从机。 ;SS=1时为未选从模式,没有总线冲突,MISO、MOSI和SPICLK为输入 ;SS=0时为从模式,MISO为输出,MOSI和SPICLK为输入 ; 定义变量 Flags EQU 20H SPI_Receive EQU Flags ;收到数据标志 TimeOver EQU Flags ;RS232 接收下一个字节超时 Rec_buffer EQU 21H ;缓冲区指针 Rec_Number EQU 22H ;已接收数据长度 SPI_buffer EQU 23H ;保存 SPI 接口收到的数据 Time_Over EQU 24H ;超时计数

281 ORG H LJMP MAIN ORG BH ;定时器0中断服务程序入口 LJMP T0_ISR ORG BH ;SPI中断服务程序入口 LJMP SPI_ISR ORG H MAIN: MOV SP, #70H ; 初始化串口 MOV SCON, #50H ;8位可变波特率, 无奇偶校验 MOV TMOD, #21H ;T1 为自动重装模式 MOV TH1, #0F6H MOV TL1, #0F6H MOV AUXR, #40H ;定时器1以1T的速度计数 ;波特率=4800*12=57600 SETB TR1

282 ;-----------初始化 SPI------------------
MOV SPCTL,#CONFIG_SLAVE MOV SPSTAT,# B ;清零标志位SPIF和WCOL ORL IE2,#02H ;ESPI=1,允许SPIF产生中断 ; MOV Flags, # ;清标志字 SETB ET ;开 T0 中断 SETB EA ;开总中断

283 ;-------------------------------------------------
Check_Receive: JB RI, RS232_GetFirstByte ;RS232收到第一个字节 JB SPI_Receive, SPI_GetFirstByte ;SPI收到第一个字节 LJMP Check_Receive ;循环 RS232_GetFirstByte: ;RS232收到第一个字节 MOV Rec_buffer, #30H MOV Rec_Number, #0B0H ;最多接收176个字节, ;否则会破坏栈的内容 RS232_Received: ;RS232 收到一个字节 MOV R0, Rec_buffer ;保存收到的字节 MOV @R0, SBUF CLR RI DJNZ Rec_Number, RS232_Rec_Next ;判断接收缓冲区是否已满 LJMP SPI_Send ;接收缓冲区满,跳转 RS232_Rec_Next: ;准备接收下一个字节 INC Rec_buffer MOV TH0, #0 SETB TR ;启动 T0 CLR TimeOver RS232_GetNextByteWait: ;等待 RS232 传来的下一个字节 JB TimeOver, SPI_Send ;超时,用SPI发送RS232收到的字节 JB RI, RS232_Received LJMP RS232_GetNextByteWait

284 ; SPI_Send: ;用SPI口发送RS232收到的字节 MOV A, #0B0H ;计算收到的字节数-->R2 CLR C SUBB A, Rec_Number MOV R2, A MOV R0, #30H LCALL ChangeToMast ;切换到忽略 SS 脚的主模式 JC ExitMast ;切换失败, 跳转 SPI_Send_Loop: MOV LCALL SPI_Send_Byte ;将 A 中的数据发送到从 SPI INC R0 DJNZ R2, SPI_Send_Loop ExitMast: CLR TR0 LCALL ChangeToSlave ;SPI 接口切换到未选中的从模式 LJMP Check_Receive

285 ;------------------------------------------------
SPI_GetFirstByte: ;SPI 收到第一个字节 MOV Rec_buffer, #30H MOV Rec_Number, #0B0H ;最多接收176个字节 SPI_Received: ;SPI 收到一个字节 MOV R0, Rec_buffer ;保存收到的字节 MOV @R0, SPI_buffer CLR SPI_Receive DJNZ Rec_Number, SPI_Rec_Next ;判断接收缓冲区是否已满 LJMP RS232_Send ;接收缓冲区满,跳转 SPI_Rec_Next: ;准备接收下一个字节 INC Rec_buffer MOV TH0, #0 SETB TR ;启动 T0 CLR TimeOver SPI_GetNextByteWait: ;等待 SPI 传来的下一个字节 JB TimeOver, RS232_Send ;超时,用RS232发送SPI收到的字节 JB SPI_Receive, SPI_Received LJMP SPI_GetNextByteWait

286 ;---------------------
RS232_Send: ;用 RS232口发送SPI收到的字节 MOV A, #0B0H ;计算收到的字节数-->R2 CLR C SUBB A, Rec_Number MOV R2, A MOV R0, #30H RS232_Send_Loop: MOV LCALL RS232_Send_Byte ;将 A 中的数据发送到计算机 INC R0 DJNZ R2, RS232_Send_Loop LJMP Check_Receive

287 ;------------------------------------------------
ChangeToMast: ;切换到忽略 SS 脚的主模式 SETB SS ;如果 SS 脚未被拉低, 就切换 JB SS, ChangeToMast_a SETB C ;切换到主模式失败 RET ChangeToMast_a: ANL IE2,#0FDH ;ESPI(IE2.1)=0,禁止SPIF产生中断 MOV SPCTL,#CONFIG_MASTER ;忽略 SS 脚, 设为主机。 MOV SPSTAT,# B ;清标志位 SPSTAT CLR SS ;拉低 SS 脚, 使对方成为从模式 CLR C ;本机切换到主模式成功

288 ;------------------------------------------------
ChangeToSlave: ;SPI 接口切换到未选中的从模式 SETB SS ;释放SS脚 MOV SPCTL,#CONFIG_SLAVE MOV SPSTAT,# B ;清标志位 SPSTAT ORL IE2,#02H ;ESPI=1,允许SPIF产生中断 RET

289 ;------------ 将A中的数据发送到计算机 -----------------
RS232_Send_Byte: CLR TI ;清零串口发送中断标志 MOV SBUF, A JNB TI, $ ;等待发送完毕, 未发送完毕跳回本行 CLR TI ;清0串口发送中断标志 RET ; 将A中的数据发送到从机SPI SPI_Send_Byte: MOV SPDAT, A SPI_Send_Byte_Wait: MOV A, SPSTAT ANL A, #80H JZ SPI_Send_Byte_Wait;等待 SPIF=1 即等待 SPI 发送完毕 MOV SPSTAT,# B ;清标志位SPSTAT ; 定时器0中断服务程序 T0_ISR: SETB TimeOver RETI

290 ;---------------- SPI 中断服务程序 ------------------
SPI_ISR: MOV SPI_buffer, SPDAT ;保存收到的数据 MOV SPSTAT, # B ;0C0H, 清0标志位 SPIF 和 WCOL SETB SPI_Receive ;设置SPI端口收到数据标志 RETI ; END

291 五、I2C通信接口 1、I2C总线简介 I2C(Inter-Integrated Circuit)总线是由PHILIPS公司开发的串行总线,用于连接微控制器及其外围设备。 I2C总线产生于二十世纪80年代,最初为音频和视频设备开发,如今主要在服务器管理中使用,其中包括单个组件状态的通信。 例如,管理员可对各个组件进行查询,以管理系统的配置或掌握组件的功能状态,如电源和系统风扇。可随时监控内存、硬盘、网络、系统温度等多个参数,增加了系统的安全性,方便了管理。

292 2、I2C总线特点  I2C总线最主要的优点是其简单性和有效性。由于接口直接在组件之上,因此I2C总线占用的空间非常小,减少了电路板的空间和芯片管脚的数量,降低了互联成本。 总线的长度可高达25英尺,并且能够以10Kbps的最大传输速率支持40个组件。

293 I2C总线的另一个优点是,它支持多个主器件(Multimastering),主器件也称为主机,其中任何能够进行发送和接收的设备都可以成为主机。一个主机能够控制信号的传输和时钟频率。当然,在任何时间点上只能有一个主机。 I2C总线有3种模式:标准模式(100Kbits/s),快速模式(400Kbits/s)和高速模式(3.4Mbits/s),寻址方式有7位和10位方式。

294 3、I2C术语 I2C的一些术语列于表8-7中。 表8-7 I2C术语 名称 描述 Transmitter 发送者:向总线发送数据的电路
Receiver 接收者:从总线上接收数据的电路 Master 主机:启动数据传输、产生时钟信号和结束数据传输的电路 Slave 从机:被主机寻址的电路 Multi-master 多主机结构:在不破坏信息的情况下,同一时刻有多个主机试图控制总线 Arbitration 仲裁:在有多个主机试图同时控制总线时,为了不破坏信息,在某一时刻确保只有一个主机控制总线的过程 Synchronization 同步:同步两个或更多电路时钟信号的过程

295 4、I2C总线工作原理  I2C是一种串行总线的外设接口,采用同步方式串行接收或发送信息,两个设备在同一个时钟下工作。 I2C总线只用两根线:串行数据SDA(Serial Data)、串行时钟SCL(Serial Clock)。 由于I2C只有一根数据线,因此其发送信息和接收信息不能同时进行。信息的发送和接收只能分时进行。

296 I2C总线上的所有器件的SDA线并接在一起,所有器件的SCL线并接在一起,且SDA线和SCL线必须通过上拉电阻连接到正电源。当总线空闲时,两条线都是高电平。
I2C总线的数据传输协议比SPI总线复杂,因为I2C总线器件没有片选控制线,所以I2C总线数据传输的开始必须由主器件产生通信的开始条件(START条件);通信结束时,由主器件产生通信的停止条件(STOP条件)。

297 当SCL为高时,使用SDA的变化标识开始条件和停止条件。
如果SDA由1变到0,则产生START条件; 如果SDA由0变到1,则产生STOP条件。 START条件和STOP条件时序如图所示。 图8-37 START条件和STOP条件时序

298 SDA线上的数据在SCL高电平期间必须保持稳定,否则会被误认为开始条件或结束条件,只有在SCL低电平期间才能改变SDA线上的数据。
I2C总线的数据传输波形图如图所示。 图8-38 I2C总线的数据传输波形图

299 数据传输的时序如图所示。 图8-39 数据传输的时序

300 I2C的确认位时序如图所示。 图8-40 I2C的确认位时序

301 目前,有很多半导体集成电路上都集成了I2C接口。
带有I2C接口的单片机有:CYGNAL的C8051F0XX系列,PHILIPSP87LPC7XX系列,MICROCHIP的PIC16C6XX系列等。很多外围器件如存储器、监控芯片等也提供I2C接口。如ATmel的串行EEPROM AT24CXX系列。

302 5、总线基本操作  I2C规程运用主/从双向通讯。器件发送数据到总线上,则定义为发送器,器件接收数据则定义为接收器。主器件和从器件都可以工作于接收和发送状态。  总线必须由主器件(通常为微控制器)控制,主器件产生串行时钟(SCL)控制总线的传输方向,并产生起始和停止条件。

303 (1)控制字节  在起始条件之后,必须是器件的控制字节,其中高四位为器件类型识别符(不同的芯片类型有不同的定义,EEPROM一般应为1010),接着三位为片选,最后一位为读写位,当为1时为读操作,为0时为写操作。如图所示。 图8-41 控制字节配置

304 (2)写操作  写操作分为字节写和页面写两种操作,对于页面写根据芯片的一次装载的字节不同有所不同。

305 字节写指令 每次只能向芯片中的一个地址写入一个字节 的数据。 首先发送开始位来通知芯片开始进行指令传输
然后传送设置好的器件地址字节,R/W位应置0 接着是分开传送十六位地址的高低字节,再传送要写入的数据 最后发送停止位表示本次指令结束 每次只能向芯片中的一个地址写入一个字节 的数据。

306 写入单个字节的时序图如图所示。 图8-42 写入单个字节的时序图

307 页面写模式 页写入的时序图如图所示。 需要发送第一个字节的地址 然后一次性发送多个字节的写入数据后 再发送停止位。
写入过程中其余的地址增量自己由芯片内部完成。 页写入的时序图如图所示。 图8-43 页写入的时序图

308 注意 无论那种写入方式,指令发送完成后,芯片内部开始写入,这时SDA会被芯片拉高,直到写入完成后SDA才会重新变的有效,在编写用户程序时可以在写入的时候不停发送伪指令并查询是否有ACK返回,如果有ACK返回则可以进行下一步操作 。

309 读操作有三种基本操作:读当前地址、读任意地址和连续读取。 1)读当前地址
(3)读操作  读操作有三种基本操作:读当前地址、读任意地址和连续读取。 1)读当前地址 这种读取模式是读取当前芯片内部的地址指针指向的数据。 每次读写操作后,芯片会把最后一次操作过的地址作为当前的地址。 注意:在CPU接收完芯片传送的数据后不必发送低电平的ACK给芯片,直接拉高SDA等待一个时钟后发送停止位。

310 读当前地址时序图如图所示。 图8-44 读当前地址时序图

311 2)读任意地址 “读当前地址”可以说是读的基本指令。
读任意地址时只是在这个基本指令之前加一个“伪操作”,这个伪操作传送一个写指令,但这个写指令在地址传送完成后就要结束,这时芯片内部的地址指针指到这个地址上,再用读当前地址指令就可以读出该地址的数据。

312 读任意地址的时序图如图所示。 图8-45 读任意地址的时序图

313 3)连续读取 连续读取操作时只要在上面二种读取方式中芯片传送完读取数据后,CPU回应给芯片一个低电平的ACK应答,那么芯片地址指针自动加一并传送数据,直到CPU不回应(NOACK)并停止操作。

314 连续读取的时序图如图所示。 图8-46 连续读取的时序图

315 下面以单片机对X24C04的操作为例说明I2C接口的应用。
6、实例 下面以单片机对X24C04的操作为例说明I2C接口的应用。 X24C04是XICOR公司的CMOS 4096位串行EEPROM,内部组织成512×8位,16字节页面写。与单片机的接口如图所示。 图8-47 X24C04与单片机的接口

316 下面通过I2C接口对X24C04进行单字节写操作的流程图如图所示。

317 源程序如下: ;子名称:BYTE-WR ;功能描述:写一个字节 ;输入参数:累加器A ;输出参数:无 SCL EQU P3.2 SDA EQU P3.3 BYTE-WR: MOV R2,#08H ;1字节8位 SENDA: CLR SCL RLC A ;左移一位 MOV SDA,C ;写一位 SETB SCL DJNZ R2,SENDA ;写完8个字节? CLR SCL ;应答信号 SETB SDA RET

318 使用I2C总线时应注意以下几点: 严格按照时序图的时序要求进行操作; 若与口线上带内部上拉电阻的单片机接口连接,可以不外加上拉电阻;
为了配合相应的传输速率,在对口线操作的指令后可用NOP指令加一定的延时; 为了减少意外的干扰信号将EEPROM内的数据改写可用外部写保护引脚(如果有),或者在EEPROM内部没有用的空间写入标志字,每次上电时或复位时做一次检测,判断EEPROM是否被意外改写。

319 §8.3 并行接口的扩展方法 在需要检测或者控制较多的开关量时,单片 机的I/O口可能无法满足数量上的要求。在这种
常见的扩展方法有使用8255进行并行口的扩 展以及使用串行输入并行输出接口芯片扩展输出 控制I/O等方法。下面分别加以介绍。

320 8255A是Intel公司生产的可编程并行I/O接口芯片,有3个8位并行I/O接口,用+5V单电源供电,能在以下三种方式下工作:
方式 0—基本输入/出方式; 方式 1—选通输入/出方式; 方式 2—双向选通工作方式。 8255A 8255A内部结构分为3个部分:与CPU连接部分、与外设连接部分和控制部分。

321 8255A的引脚图和内部结构如图所示。 图 A的引脚图和内部结构

322 (1)A口、B口和C口 A口、B口和C口均为8位I/O数据口,但结构上略有差别。
三个端口都可以和外设相连,分别传送外设的输入/输出数据或控制信息。 各个端口用于输入和输出时,均具有锁存功能;用于输出时,均具有缓冲功能。

323 PA口的各个口线通过编程可以分别设置成单向输出、单向输入或者分时输入输出。
PB口的各个口线通过编程可以分别设置成单向输出和单向输入。 PC端口可以分为高4位PC7~4和低4位PC3~0两个独立部分。PC端口可否独立控制取决于PA端口和PB端口的工作方式。

324 图8-50 PA口某个口线的输出锁存和缓冲、输入锁存结构

325 图8-51 PB口某个口线的输出锁存和缓冲、输入缓冲结构

326 (2)A、B组控制电路 这是两组根据CPU的命令字控制8255A工作方 式的电路。A组控制A口及C口的高4位,B组控 制B口及C口的低4位。 (3)数据缓冲器 这是一个双向三态8位的驱动口,用于和单片 机的数据总线相连,传送数据或控制信息。 (4)读/写控制逻辑 这部分电路接收单片机送来的读/写命令和选 口地址,用于控制对8255A的读/写。

327 (5)数据线(8条) D0~D7为数据总线,用于传送CPU和8255A 之间的数据、命令和状态字。 (6)控制线和寻址线(6条) RESET:复位信号,输入,高电平有效。一 般和单片机的复位相连,复位后,8255A所有内 部寄存器清0,所有口都为输入方式。 和 :读/写信号线,输入,低电平有 效。

328 (7) 片选线,输入,低电平有效。 (8)A0、A1:地址输入线。 当芯片被选中(=0)时,这两位的4种组合 00、01、10、11分别用于选择A、B、C口和控 制寄存器。

329 (9)I/O口线(24条) PA0~PA7、PB0~PB7、PC0~PC7为24条双 向三态I/O总线,分别与A、B、C口相对应,用 于8255A和外设之间传送数据。 (10)电源线(2条) VCC为+5 V,GND为地线。

330 对8255A操作的真值表如表所示 表8-8 对8255A操作的真值表

331 2、8255A控制字 8255A的三个端口具体工作在什么方式下,是通过CPU对控制口的写入控制字来决定的 8255A有两个控制字:方式选择控制字和C口置/复位控制字。用户通过程序把这两个控制字送到8255A的控制寄存器(A0A1=11)中,这两个控制字以D7来作为区别标志。

332 方式选择控制字和C口置/复位控制字分别如图a和b所示。
图 A控制字和C口按位置位/复位控制字

333 注意 C口具有位操作功能,把一个置/复位控制字送入8255A的控制寄存器,就能将C口的某一位置1或清0而不影响其它位的状态。

334 三个端口的数据传送模式 PA端口具有3种传送模式可供选用。 PB端口具有2种传送模式可供选用。
PC端口的传送模式取决于PA端口和PB端口的传送模式。

335 (1)传送模式0 模式0的功能特点: 是直接控制输入或输出传送。不需要查询和中断控制。 PA、PB和PC端口都可以编程设置为模式0传送。
PA、PB、PC7~PC4、PC3~PC0这4个端口最多有16种输入输出组合。 模式0传送在计算机系统中很多有实际应用的例子。例如在个人计算机系统中,8255A并行接口电路的PA端口被设置成模式0输入,接收键盘输入的按键扫描码。 又如,在半导体数码管显示控制电路中,通常设置8255A并行接口电路的PA和PB端口为模式0输出,分别进行位控制和段控制。

336 ③INTR是中断请求信号,输出到主机电路,要求CPU读取PA端口数据。INTR信号也可以作为查询信号使用。
④INTR信号能否激活,受8255A内部的中断允许触发器INTE的控制。INTE=1,允许激活INTR信号。INTE=0,禁止激活INTR信号。

337 (2)传送模式1 模式1的功能特点: 采用查询或者中断控制的输入或输出传送。 PA端口编程为模式1传送后,要占用PC端口的部分资源。
PB端口编程为模式1传送后,也要占用PC端口的部分资源。 PC端口的剩余资源仍然可以独立操作。

338 PA端口模式1输入传送的逻辑结构,如图所示。

339 功能说明: ① 是选通输入信号,来自外设电路,低有效,表示数据已经打入PA端口锁存器。 ②IBF是输入缓冲器满信号,由8255A输出,高有效,表示PA端口数据尚未被CPU读取,不能再接收新数据。当IBF为低电平时,表示输入缓冲器空,可以接收新数据。IBF信号由 选通信号激活,随CPU的读控制信号 的撤消而失效。

340 单片机中扩展的I/O口采用与外部数据存储器相同的寻址方法,所有扩展的I/O口,以及通过扩展I/O口连接的外设都与外部RAM统一编址
可以使用下面的代码对中断允许触发器INTE置位(假设命令端口地址为0E003H)

341 ⑤PB端口设置为模式1输入时,分别占用PC0(INTR)、PC1(IBF)和PC2( )。
MOV DPTR,#0E003H ;指向8255命令端口 MOV A,# B;PC4置1,允许激活PA端口的INTR信号 ;写入PC端口操作字 MOV A,# B;PC2置1,允许激活PB端口的INTR信号 ⑤PB端口设置为模式1输入时,分别占用PC0(INTR)、PC1(IBF)和PC2( )。 ⑥PC端口剩余的PC7和PC6,可以编程为两位输入或者输出,也可以单独进行位操作。

342 PA端口模式1输出传送的逻辑结构如图所示。

343 功能说明: ① 是输出缓冲器满信号,由8255A输出,低有效,表示PA端口数据已经准备就绪,可供外设电路读取。 ② 是输入响应信号,来自外设电路,低有效,表示外设电路已经读取PA端口的数据。 信号由 信号激活。当 信号生效后, 信号返回高电平撤销。当CPU把数据写入PA端口后,随着写控制信号 的撤销, 信号再次自动激活。

344 ③INTR是中断请求信号,输出到主机,表示PA端口已经空闲,要求CPU再次写入数据。INTR信号也可以作为查询信号使用。
④INTR信号能否激活,受8255A内部的中断允许触发器INTE的控制。但是,改用PC6来控制是否激活INTR信号。

345 中断允许触发器INTE的置位控制代码如下(假设命令端口地址为0E003H):
MOV DPTR,#0E003H ;指向8255命令端口  MOV A,# B;PC6置1,允许激活PA端口的INTR信号  MOVX @DPTR,A ;写入PC端口操作字  MOV A,# B;PC2置1,允许激活PB端口的INTR信号 ;写入PC端口操作字。

346 ⑤PB端口设置为模式1输出时,分别占用PC0(INTR)、PC1( )和PC2( )。
⑥PC端口剩余的PC5和PC4,可以编程为两位输入或者输出,也可以单独进行位操作。

347 (3)传送模式2 只有PA端口可以编程设置为模式2传送。这是采用中断或者查询控制的分时输入和输出的双向传送方式。模式2的逻辑结构如图所示。

348 3、单片机与8255A的接口设计 可以使用8255A进行并行I/O口的扩展。 8255A和单片机连接时,可以为外设提供三个8位的I/O端口:A口、B口和C口,三个端口的功能完全由编程来决定。

349 8255A与STC15F2K60S2单片机的接口电路如图8-56所示。

350 8255A的命令口地址为7FF3H,PA口地址为7FF0H,PB口地址为7FF1H,PC口地址为7FF2H。

351 4、8255A并行接口的编程操作 8255A并行接口的编程操作分为: 写入8255A命令字,用于设置8255A电路的工作模式与传送方向。
写入PC端口操作字,用于设置PC端口的位输入或输出状态。

352 8255A接口电路编程操作示例代码如下: MOV DPTR,#7FF3H ;指向8255命令端口
   MOV A,#80H ;命令字:PA、PB和PC端口直接输出 ;写入命令    MOV DPTR,#7FF0H ;指向PA端口 ;数据写入PA端口    MOV DPTR,#7FF3H ;指向8255命令端口    MOV A,#9H ;PC端口操作字 ;PC4输出高电平

353 二、74HC595接口及其应用 74HC595是为Motorola的SPI总线开发的一 款串行-并行转换芯片。 由于74HC595的输入输出电平兼容TTL、 NMOS和CMOS电平,且具有较强的输出负载能 力,因此被广泛地运用于MCU(微控制器)和 MPU(微处理器)的I/O口扩展。

354 74HC595在5V供电的时候能够达到30MHz的时钟速度,每个并行输出端口均能承受20mA的灌电流和拉电流。这个特点保证了不用增加额外的扩流电路即可轻松的驱动LED。
它的输入端允许500nS的上升(下降)时间,对严重畸形的时钟脉冲仍能检测。 这样就可以容纳较大的传输线对地电容,使系统的抗干扰能力增强。

355 74HC595管脚功能描述如下: QA~QH:锁存器输出,三态 GND:电源地 QH’:串行输出,用于级联。无三态输出功能。

356 /SCLR:低电平有效,当此管脚上出现低电平时,将复位内部的移位寄存器(清0),但不影响8位锁存器的值。通常可接Vcc。
SCK:上升沿时,将数据寄存器的数据移位。QA→QB→QC→... →QH;下降沿移位寄存器数据不变。(脉冲宽度:5V时,大于几十纳秒即可。)

357 RCK:锁存时钟输入,上升沿时,移位寄存器的数据进入数据存储寄存器,下降沿时存储寄存器数据不变,通常将RCK置为低电平。当移位结束后,在RCK端产生一个正脉冲(5V供电时,大于几十纳秒即可),更新输出数据。 /G:低电平有效,将锁存器的输出映射到输出并行口(QA-QH)上。当输入高电平时,高阻态,同时本芯片的串行输出无效。 SI:串行数据输入,数据从这个管脚移进内部的8位串行移位寄存器。 VCC:电源正,一般接5VDC。

358 74HC595真值表如表8-9所示。 表8-9 74HC595真值表 输入 输出管脚 SI SCK /SCLR RCK /G × H
QA-QH输出高阻态 L QA-QH输出有效值 移位寄存器清0 移位寄存器存储L 移位寄存器存储H 移位寄存器状态保持 输出存储器锁存移位寄存器中的状态值 输出存储器状态保持

359 74HC595与STC15F2K60S2单片机的接口电路如图所示。

360 应用演示程序: ;==================输出锁存器输出数据子程序 ================= SDATA_595 EQU P1.0 ;串行数据输入 SCLK_595 EQU P1.1 ;移位时钟脉冲 RCK_595 EQU P1.2 ;输出锁存器控制脉冲 ORG 0000H LJMP MAIN ORG 0030H MAIN: MOV SP,#60H MOV R0,#0FEH MAIN1: LCALL OUT_595 LCALL DELAY MOV A,R0 RL A MOV R0,A LJMP MAIN1

361 ;----------------- 输出锁存器输出数据子程序 -----------------
OUT_595:LCALL WR_595 CLR RCK_595 NOP SETB RCK_595 ;上升沿将数据送到输出锁存器 RET

362 ;----------------- 移位寄存器接收数据子程序 ------------------
WR_595: MOV R4,#08H MOV A,R0 WR_LOOP:RLC A MOV SDATA_595,C SETB SCLK_595 ;上升沿发生移位 NOP CLR SCLK_595 DJNZ R4,WR_LOOP RET

363 ;------------------------ 延时子程序---------------------
DELAY:MOV R5,#03H DEL0:MOV R6,#0FFH DEL1:MOV R7,#0FFH DJNZ R7,$ DJNZ R6,DEL1 DJNZ R5,DEL0 RET ;================================================= END

364 对应的C语言程序如下: /****** 74HC595 走马灯演示程序 ***********************/ #include “reg51.h” //51芯片管脚定义头文件 #include “intrins.h” //内部包含延时函数 _nop_() #define uchar unsigned char #define uint unsigned int uchar code DAT[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; sbit SDATA_595=P1^0; //串行数据输入 sbit SCLK_595 =P1^1; //移位时钟脉冲 sbit RCK_595 =P1^2; //输出锁存器控制脉冲 uchar bdata temp; sbit mybit=temp^7; /*********************延时子程序*********************/ void delay(int ms) { int k; while(ms--) for(k=0;k<250;k++) _nop_(); }

365 /***********将显示数据送入74HC595内部移位寄存器**********/
void WR_595(void) { uchar j; for(j=0;j<8;j++) temp=temp<<1; SDATA_595=mybit; SCLK_595=1; //上升沿发生移位 _nop_(); SCLK_595=0; }

366 /******将移位寄存器内的数据锁存到输出寄存器并显示******/
void OUT_595(void) { RCK_595=0; _nop_(); RCK_595=1; //上升沿将数据送到输出锁存器 }

367 /*******************主程序 ******************************/
void main(void) { SCLK_595=0; RCK_595=1; while(1) uchar i; for(i=0;i<8;i++) temp=DAT[i]; //取显示数据 WR_595(); OUT_595(); delay(100); }


Download ppt "第八章 数据通信 本章学习目标 了解通信的有关概念 掌握串行通信和并行通信的原理"

Similar presentations


Ads by Google