用汇编语言编写一段程序,单片机89S51串行口按工作方式3进行穿行数据通信时,假定波特率为1200b/s,第9位数据位作奇偶校验位,以中断方式传送数据。
时间: 2024-02-17 20:01:19 浏览: 87
好的,下面是汇编语言的程序,可以实现你的需求:
```
ORG 0000H ; 程序从地址0000H开始
MOV PCON, #80H ; 关闭SMOD位,波特率加倍功能不启用
MOV TMOD, #20H ; 将T1设置为方式2
MOV TH1, #-3 ; 设置T1的计数初值,计数到0时产生中断
MOV SCON, #50H ; 将串行口设置为方式3,启用接收中断和帧错误中断
MOV IE, #90H ; 开启总中断和串行口中断
LOOP: ; 主循环开始
SJMP LOOP ; 一直循环
ORG 0023H ; 定义中断向量表,串行口中断向量为0023H
PUSH ACC ; 保存ACC寄存器
PUSH PSW ; 保存PSW寄存器
JB RI, RECEIVE ; 判断是否接收到数据,如果是,跳转到RECEIVE处理
JB FE, FRAME_ERROR ; 判断是否发生帧错误,如果是,跳转到FRAME_ERROR处理
POP PSW ; 恢复PSW寄存器
POP ACC ; 恢复ACC寄存器
RET ; 中断结束,返回
RECEIVE: ; 处理接收到的数据
CLR RI ; 清除接收中断标志位
MOV A, SBUF ; 读取接收到的数据
MOV R0, #0 ; 初始化校验位为0
MOV R1, #1 ; 初始化计数器为1
CHECK_PARITY: ; 校验奇偶位
RL A ; 将数据左移一位
JNC SKIP_XOR ; 如果左移后最高位为0,跳过异或运算
XRL A, R0 ; 否则,将校验位与数据异或
SKIP_XOR: ; 跳过异或运算
DJNZ R1, CHECK_PARITY ; 继续校验下一位
JNB P, PARITY_ERROR ; 判断校验位是否正确,如果不正确,跳转到PARITY_ERROR处理
MOV P1, A ; 将接收到的数据存入P1口输出
SJMP END_INTERRUPT ; 结束中断处理
PARITY_ERROR: ; 处理校验错误
SETB P1.0 ; 将P1.0置为1,表示校验错误
SJMP END_INTERRUPT ; 结束中断处理
FRAME_ERROR: ; 处理帧错误
SETB P1.1 ; 将P1.1置为1,表示帧错误
SJMP END_INTERRUPT ; 结束中断处理
END_INTERRUPT: ; 结束中断处理
POP PSW ; 恢复PSW寄存器
POP ACC ; 恢复ACC寄存器
RET ; 中断结束,返回
END ; 程序结束
```
解释一下上面的代码:
1. 首先关闭SMOD位,波特率加倍功能不启用;将T1设置为方式2,即16位自动重装载模式;将T1的计数初值设置为-3,计数到0时产生中断;将串行口设置为方式3,启用接收中断和帧错误中断;开启总中断和串行口中断。
2. 进入主循环,一直循环等待中断。
3. 当串行口中断发生时,首先保存ACC寄存器和PSW寄存器。
4. 判断是否接收到数据,如果是,跳转到RECEIVE处理;判断是否发生帧错误,如果是,跳转到FRAME_ERROR处理。
5. RECEIVE处理中,先清除接收中断标志位,然后读取接收到的数据,并进行奇偶校验,校验错误则跳转到PARITY_ERROR处理,否则将接收到的数据存入P1口输出,结束中断处理。
6. PARITY_ERROR和FRAME_ERROR处理中,将P1.0或P1.1置为1,表示校验错误或帧错误,然后结束中断处理。
7. END_INTERRUPT中,恢复ACC寄存器和PSW寄存器,结束中断处理。
希望这个程序能够满足你的需求!
阅读全文