【例7-3】设有两台单片机分别为8751-1和8751-2。8751-1的工作是检查接在P1口上的DIP SW开关,当检测到开关的状态有变化时,就将变化后的状态读入,通过串行口将这个开关状态传送给8751-2。当8751-2接收到这个字节后就将它输出到P1口上显示,并且也将它接收到的数据回传给8751-1以通知8751-1已经接收到数据。当8751-1接收到这个响应数据后与刚才传出去的数据比较,若不相同再发送一次,以确保将正确的数据传递给8751-2。
两个8751接口原理图如图7-12所示。
通信约定:双方都采用串行通信方式,波特率为9 600bps(晶振为11.059MHz),采用中断方式发送和接收数据。
图7-12 两台8751互传数据
程序如下。
(1)8751-1程序。
BUFFER EQU 30H ;发送数据缓冲区
ECHOFLAG BIT00H ;当发送与接收到的数据相同时此标志置0
ERRFLAG BIT 01H ;当发送与接收到的数据不同时此标志置1
ORG 0000H
SJMP START
ORG 0023H ;串行口中断输入口
SJMP UART1
ORG 0030H
START: MOV TMOD, #20H ;定时器1设置为方式2,作为波特率发生器
ANL PCON, #7FH
MOV TH1, #0FDH ;波特率为9600 bps
MOV TL1, #0FDH
SETB TR1
MOV SCON, #50H ;设置为串行方式1,允许接收
MOV IE,#90H ;允许串行口中断
MOV BUFFER,#00H ;缓冲区清零
WAIT: MOV A, P1
CJNE A,BUFFER,SWCH
SJMP WAIT
SWCH: MOV BUFFER,A
TRAGIN:MOV SBUF,A ;发送数据
CLR ECHOFLAG
CLR ERRFLAG
WAITEO:JB ERRFLAG,TRAGIN
JNB ECHOFLAG,WAITEO
SJMP WAIT
UART1: PUSH PSW
PUSH ACC
SETB RS0
CLR RS1
JBC RI,RCV1 ;判断是否为接收中断
CLR TI
SJMP RETURN
RCV1: MOV A, SBUF
CJNE A, BUFFER,DATAER
SETB ECHOFLAG
SJMP RETURN
DATAER:SETB ERRFLAG
RETURN:POP ACC
POP PSW
RETI
END
(2)8751-2程序。
ORG 0000H
SJMP START
ORG 0023H ;串行口中断输入口
SJMP UART1
ORG 0030H
START: MOV TMOD, #20H ;定时器l设置为方式2,作为波特率发生器
ANL PCON, #7FH
MOV TH1, #0FDH ;波特率为9600 bps
MOV TL1, #0FDH
SETB TR1
MOV SCON, #50H ;设置为串行方式1,允许接收
MOV IE, #90H ;允许串行口中断
LOOP: SJMP LOOP
UART1: PUSH PSW
PUSH ACC
SETB RSO
CLR RS1
JBC RI,RCV1 ;判断是否为接收中断
CLR TI
SJMP RETURN
RCV1: MOV A,SBUF
MOV P1, A
MOV SBUF, A
RETURN:POP ACC
POP PSW
RETI
END
以上是采用中断方式进行串行通信的例子。中断法效率较高,是在通信中经常用到的方法。如果使用查询法进行编程,则需对发送中断标志TI和接收中断标志RI进行查询,以判断一个字节数据是否发送完毕或是否已接收到一个字节的数据。下面给出使用查询法发送和接收一个字节的子程序。
发送一个字节:
BYTSND:MOV SBUF, A
SDWAIT:JNB TI, SDWAIT
CLR TI
RET
接收一个字节:
BYTRCV:JNB RI,BYTRCV
CLR RI
MOV A, SBUF
RET
在程序中,若要发送一个字节,可先将要发送的字节送入寄存器A,然后调用发送子程序,即ACALL BYTRCV,通过串行口接收到的字节也存放在寄存器A中。
【例7-4】假定甲、乙两个MCS-51单片机以方式1进行串行数据通信,其波特率为
1 200bps。甲机发送,发送数据在外部数据RAM中2000H~202FH单元。乙机接收,并把接收到的数据块首、末地址及数据依次存入外部数据RAM中3000H开始的区域中。甲、乙两机的连接如图7-13所示。
图7-13 甲、乙两机的连接示意图
设晶振频率为6 MHz,通信速率为1 200 bps特,SMOD=0,即波特率不倍增。
用以下公式计算定时器1的计数初值。
求得定时器1的初值为TH1=243=0F2H。
串行发送的内容包括数据块的首、末地址和数据两部分。数据块首、末地址以查询方式传送,而数据则以中断方式传送。因此在程序中要先禁止串行中断,后允许串行中断数据传送,这是在中断服务程序中完成的,数据为ASCII码形式,其最高位作奇偶校验位使用。MCS-51单片机的PSW中有奇偶校验位P,当累加器A中“l”的个数为奇数时,P=1。但如果直接把P的值送入ASCII码的最高位,变成了偶校验,与要求不符。为此应把P值取反后送入最高位才能满足奇偶校验的要求。
下面是发送和接收的参考程序。
甲机发送主程序如下:
ORG 0023H
LJMP SINT
ORG 0030H
MOV TMOD,#20H ;设置定时器l工作方式2
MOV TLI,#0F2H ;定时器1计数初值
MOV TLI,#0F2H ;计数重装值
SETB EA ;中断总允许
CLR ES ;禁止串行中断
MOV PCON,#00H ;SMOD清零,波特率不倍增
SETB TR1 ;启动定时器1
MOV SCON,#50H ;设置串行口方式1,REN=1
MOV SBUF,#40H ;发送数据区首地址高位
SOUTI: JNB TI,$ ;等待一帧发送完毕
CLR TI ;清发送中断标志
MOV SBUF,#00H ;发送数据区首地址低位
SOUT2: JNB TI,$ ;等待一帧发送完毕
CLR TI ;清发送中断标志
MOV SBUF,#20H ;发送数据区末地址低位
SOUT3: JNB TI,$ ;等待一帧发送完毕
CLR TI ;清发送中断标志
MOV SBUF,#2FH ;发送数据区末地址低位
SOUT4: JNB TI, $ ;等待一帧发送完毕
CLR TI ;清发送中断标志
MOV DPTR,#2000H ;数据区地址指针
MOV R7,#30H ;设置R7为数据个数计数器
SETB ES ;开放串行中断
AJMP $ ;等待中断
下面是甲机中断发送服务程序:
ORG 0100H
SINT: MOVX A,@DPRT ;读数据
CLR TI ;清发送中断
MOV C,P ;奇偶标志赋予C
CPL C ;C取反
MOV ACC.7,C ;送ASCII码最高位
MOV SBUF,A ;发送数据字符
CJNE R7, #00H, SEND ;发送完转SEND
INC DPTR ;调整数据指针
AJMP BACKA ;未送完返回主程序
SEND: CLR ES ;禁止串行中断
CLR TR1 ;定时器l停止计数
BACKA: ETI ;中断返回
乙机接收主程序如下:
ORG 0023H
LJMP BINT
ORG 0030H
MOV TMOD,#20H ;设置定时器l工作方式2
MOV TH1,#0F2H ;定时器1计数初值
MOV TH1,#0F2H ;计数重装值
SETB EA ;中断总允许
CLR ES ;禁止串行中断
MOV PCON,#00H ;SMOD清零,波特率不倍增
SETB TR1 ;启动定时器1
MOV SCON,#50H ;设置串行口方式1,REN=1
MOV DPTR,#3000H ;数据存放首地址
MOV R7,#34H ;接收数据个数,其中4个为首、末地址
SINI: JNB RI,$ ;等待接收
CLR RI ;清接收中断标志
MOV A,SBUF ;接收数据区首地址高位
MOVX @DPTR,A ;存首地址
INC DPTR ;调整地址指针
SIN2: JNB RI,$ ;等待接收
CLR RI ;清接收中断标志
MOV A,SBUF ;接收数据区首地址低位
MOVX @DPTR,A ;存首地址低位
INC DPTR ;调整地址指针
SIN3: JNB RI,$ ;等待接收
MOV A,SBUF ;接收数据区末地址高位
MOVX @DPTR,A ;存末地址高位
INC DPTR ;调整地址指针
SIN4: JNB RI,$ ;等待接收
CLR RI ;清接收中断标志
MOV A,SBUF ;接收数据区末地址低位
MOVX @DPTR,A ;存末地址低位
INC DPTR ;调整地址指针
SETB ES ;开放串行中断
AJMP $ ;等待中断
乙机中断接收服务程序如下:
ORG 0100H
BINT: MOV A,SBUF ;接收数据
MOV C,P ;奇偶标志送C
JNC ERROR ;C为0,则转接收出错处理程序
ANL A,#7FH ;删去最高位,即校验位
MOVX @DPTR,A ;存数据
CLR RI ;清接收中断标志
CJNE R7,#00H,BEND ;接收转BEND
INC DPTR ;调整地址指针
AJMP BACKB ;没收完,返回主程序
BEND: CLR ES ;接收完,则禁止串行中断
CLR TR1 ;定时器l停止计数
BACKB: ETI ;中断的返回
ERROR: …… ;接收出错处理程序(略)
(1)串行数据传送的主要优点和用途是什么?
(2)简述串行口接收和发送数据的过程。
(3)串行口有几种工作方式?有几种帧格式?各种工作方式的波特率如何确定?
(4)假定串行口串行发送的字符格式为1个起始位,8个数据位,1个奇校验位,1个停止位,请画出传送字符“A”的帧格式。
(5)判断下列说法是否正确。
串行口通信的第9数据位的功能可由用户定义。
发送数据的第9数据位的内容在SCON寄存器的TB8位预先准备好的。
串行通信发送时,指令把TB8位的状态送入发送SBUF。
串行通信接收到的第9位数据送SCON寄存器的RB8中保存。
串行口方式1的波特率是可变的,通过定时器/计数器T1的溢出设定。
(6)为什么定时器/计数器T1用作串行口波特率发生器时采用方式2?若已知时钟频率、通信波特率,如何计算其初值?
(7)若晶体振荡器为11.0592MHz,串行口工作于方式1,波特率为4 800bps,写出用T1作为波特率发生器的方式控制字和计数初值。
(8)简述利用串行口进行多机通信的原理。
(9)使用8031的串行口按工作方式1进行串行数据通信,假定波特率为2 400bps,以中断方式传送数据,请编写全双工通信程序。
(10)使用8031的串行口按工作方式3进行串行数据通信,假定波特率为1200bps,第9数据位作奇偶校验位,以中断方式传送数据,请编写通信程序。
(11)某8031串行口,传送数据的帧格式为1个起始位(0),7个数据位,1个偶校验位和1个停止位(1)。当该串行口每分钟传送1 800个字符时,试计算出波特率。
(12)为什么MCS-51串行口的方式0帧格式没有起始位(0)和停止位(1)?