📄 serialr.asm
字号:
;*------------------------------------------------------*/
;* SerialR.asm(查询方式半双工串行通信接口实验-接收端程序) */
;* 查询方式半双工串行通信接收程序 Source File */
;* Copyright (c) 2001 by HUST */
;* Modify Date 2005.4.10 */
;*------------------------------------------------------*/
stack1 segment para 'stack'
dw 200 dup(?)
stack1 ends
data51 equ 308h ;8251A数据口
ctr151 equ 309h ;8251A命令/状态口
ctr155 equ 303h ;8255命令口
timer2 equ 306h ;8253的2号计数器端口
timctl equ 307h ;8253命令口
clk00 equ 12h ;8251输入时钟频率(十六进制表示)这是多少?
clk01 equ 34deh
factor equ 16 ;波特率因子16
data segment para public 'data'
int0a_off dw(?)
int0a_seg dw(?)
bps00 dw (?)
receive db 100 dup(?) ;缓冲区
resize dw (?) ;缓冲区长度
data51 equ 308h ;8251A数据口
ctr151 equ 309h ;8251A命令/状态口
ctr155 equ 303h ;8255命令口
timer2 equ 306h ;8253的2号计数器端口
timctl equ 307h ;8253命令口
clk00 equ 12h ;8251输入时钟频率(十六进制表示)这是多少?
clk01 equ 34deh
factor equ 16 ;波特率因子16
mes1 db 'now enter the serial communication(receive)',0ah,0dh
db 'end with q/Q',0ah,0dh,'$'
input_message db '0:110 1:150 2:300 3:600'
db 0dh,0ah
db '4:1200 5:2400 6:4800 7:9600'
db 0dh,0ah
db 'please take a choice(0~7)of baud_rate:'
db 0dh,0ah,'$'
error_message db 'input error! try again'
db 0dh,0ah,'$'
data ends
code segment
assume cs:code, ds:data, ss:stack1
charout proc near ;送数子程
out dx,al
push cx
mov cx,100 ;延时
gg: loop gg
pop cx
ret
charout endp
int51 proc near ;8251A初始化子程
mov dx,ctr151 ;8251A命令口
xor ax,ax ;空操作
call charout ;送数子程
mov al,40h ;内部复位
call charout
mov al,4ah ;8251A方式命令
call charout
mov al,27h ;8251A工作命令
call charout
ret
int51 endp
set_bps proc near ;8253-5计数初值计算与装入子程
mov dx,clk00 ;取8253-5输入时钟频率clk作被除数
mov ax,clk01
mov bx,bps00 ;取所选波特率作第一个除数
div bx ;除法运算,商数送ax
mov dx,0 ;余数清零
mov bx,factor ;取波特率因子作第二个除数
div bx ;除法运算,得计数初值(商数)送ax
mov bx,ax ;保存计数初值至bx
mov dx,timctl ;8253-5命令口
mov al,0b6h ;8253-5初始化命令
out dx,al
mov dx,timer2 ;8253-5计数器2的端口
mov ax,bx ;取计数初值
out dx,al ;装计数初值低字节
mov al,ah ;装计数初值高字节
out dx,al
ret ;返回
set_bps endp
serv_int proc far ;中断服务程序
push bx
push ax
push dx
push di
push ds
mov ax,data ;载入数据段
mov ds,ax
cli
mov dx,data51 ;已准备好,即有数据传送过来,则接收1个字符
in al,dx
mov di,resize ;载入缓冲区指针
mov [di],al ;将数据放入缓冲区
inc di ;缓冲区指针加1
mov resize,di ;保存缓冲区指针
mov al,62h ;发中断结束命令(OCW2)
mov dx,0a0h
out dx,al ;向从片8259发EOI命令
mov al,20h
out 020h,al ;向主片8259发EOI命令
sti
pop ds
pop di
pop dx
pop ax
pop bx
iret
serv_int endp
main proc far ;通信(接收)主程序
mov ax,data
mov ds,ax
mov ah,9 ;提示选择波特率
mov dx,seg input_message
mov ds,dx
mov dx,offset input_message
int 21h
input:mov ah,8 ;输入波特率
int 21h
cmp al,'0' ;输入’0’,表示选择110baud
jne next1
mov bps00,110 ;存入bps00
jmp begin ;跳转开始begin处
next1:cmp al,'1'
jne next2
mov bps00,150 ;’1’表示150b/s
jmp begin
next2:cmp al,'2'
jne next3
mov bps00,300 ;’2’表示300b/s
jmp begin
next3:cmp al,'3'
jne next4
mov bps00,600 ;’3’表示600b/s
jmp begin
next4:cmp al,'4'
jne next5
mov bps00,1200 ;’4’表示1200b/s
jmp begin
next5:cmp al,'5'
jne next6
mov bps00,2400 ;’5’表示2400b/s
jmp begin
next6:cmp al,'6'
jne next7
mov bps00,4800 ;’6’表示150b/s
jmp begin
next7:cmp al,'7'
jne error ;若波特率选择有错,则重新输入
mov bps00,9600 ;’7’表示9600b/s
jmp begin
error:
mov ah,9 ;提示波特率选择出错,则重新输入
mov dx,seg error_message
mov ds,dx
mov dx,offset error_message
int 21h
jmp input
begin:call set_bps ;调用set_bps子程序,设置所选波特率的计算初初值
call int51 ;调用int51子程序,初始化8251A
mov ax,offset receive
mov resize,ax
lea dx,mes1
mov ah,09
int 21h
mov dx,303h ;初始化8255A
mov al,80h
out dx,al
mov al,0dh ;置PC6=1,打开8253-5的GATE2,开始输出方波
out dx,al
mov ax,3572h ;获取原中断向量
int 21h
mov int0a_off,bx ;保存原中断向量
mov bx,es
mov int0a_seg,bx
cli ;关中断
mov ax,2572h ;设置新中断向量
mov dx,seg serv_int
push ds
mov ds,dx
mov dx,offset serv_int
int 21h
pop ds
in al,0a1h ;打开IRQ10(OCW1)
and al,0fbh
out 0a1h,al
in al,21h ;打开IRQ2
and al,0fbh
out 21h,al
sti ;开中断
hlt ;等待中断
isq: mov ah,0bh ;是否有键按下
int 21h
inc al
jnz show
mov ah,08h ;是q/Q键就退出
int 21h
cmp al,071h
je over
cmp al,051h
je over
show: mov ax,offset receive ;获取缓冲区首位地址偏移量
mov di,ax
cmp di,resize ;比较,若相等,就循环等待;不相等,就显示接收的数据
je isq
snext:mov dl,[di]
mov ah,02h
int 21h
inc di
cmp di,resize
jne snext
mov ax,offset receive ;缓冲区指针复位为首地址偏移量,为下次接收准备好缓冲区
mov resize,ax
jmp isq
over: mov ax,2572h ;恢复原中断向量
mov dx,int0a_seg
push ds
mov ds,dx
mov dx,int0a_off
int 21h
pop ds
in al,0a1h ;屏蔽IRQ10(OCW1)
or al,04h
out 0a1h,al
in al,21h ;屏蔽IRQ2
or al,04h
out 21h,al
mov al,0ch ;置PC6=0,关闭8253-5的GATE2,停止输出方波
mov dx,303h
out dx,al
mov ax,4c00h ;程序退出
int 21h
main endp
code ends
end main
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -