14、以89C51串行口按工作方式3进行串行数据通信。假定波特率为1200b/s,第9数据位作奇偶校验位,以中断方式传送数据。请编写通信程序。
解:
ORG0000H
AJMPMAIN;上电,转向主程序
ORG0023H;串行口的中断入口地址
AJMPSTOP;转向中断服务程序
ORG0040H;主程序
MAIN:MOVSP,#60H;设置堆栈首地址
MOVTMOD,#20H;T1定时/计数器工作在方式方式2,为定时器工作方式
MOVTH1,#0E8H;T1高8位设置初值,十进制是“248”
MOVTL1,#0E8H;T1低八位设置初值,十进制是“248”
SETBTR1;启动定时器T1
MOVSCON ,#0D0H;设置串行口工作在方式3,且REN=1,允许接收
MOVPCON ,#00H;SMOD=0,波特率不加倍
MOVR0 ,#20H;置发送数据区首地址
MOVR1 ,#40H;置接收数据区首地址
SETBES;允许串行口中断
SETBEA;CPU允许中断
MOVA ,@R0
MOVC, PSW.0;P→C
CPLC;本题采用奇校验,对C取反
MOVTB8 ,C;将数据传到奇偶校验位
MOVSBUF ,A;发送第一个数据
SJMP$;等待中断($指当前地址,指令意思是在当前地址循环,原地踏步。) STOP: JNBRI SOUT;TI=1,为发送中断
CLRRI
MOVA ,SBUF;读出接收缓冲区内容
MOVC ,PSW.0;P→C
CPLC;形成奇校验
JCLOOP1;判断接收端的奇偶值,C=1转LOOP1
JNBRB8 ,LOOP2;C=0,RB8=0,转LOOP2
SJMPERROR;C=0,RB8=1,转出错处理
LOOP1: JBRB8 ,LOOP2;C=1,RB8=1,转LOOP2
SJMPERROR;C=0,RB8=1,转出错处理
LOOP2:MOV@R1 ,A;将接收数据送入接收数据区
INCR1;修改数据区指针
RETI
SOUT: CLRTI;是发送中断,清除发送中断标志
INCR0;修改数据区指针
MOVA ,@R0
MOVPSW.0, C;P→C
CPLCMOVTB8 ,CMOVSBUF ,A;发送第一个数据
RETIEND(这条题的答案已经是包括发送和接收的程序的了,按顺序看也不难。不过和课本的立体不同的就是它发完一次都会等待中断“SJMP$”。)