;8251串行通信 用8251 8253 clk0接1M
;宏定义必须放在end main 以外 必须放在程序开头 在end main后不行
;用equ定义8251 8253 地址
;操作 键盘键入要发送的键值 屏幕显示其值和接收回来加三后的值 判ESC退出
delay MACRO ;调用时直接用宏名 delay
LOCAL d0
MOV CX,0ffffh ;初值越大越好 0ffffh
d0: LOOP d0
ENDM
ioport EQU 0dc00h-280h
proc_53 EQU ioport+283h
pro0_53 EQU ioport+280h
proc_51 EQU ioport+2B9h
prod_51 EQU ioport+2B8h
data SEGMENT
mes DB 13,10,"Start Keyboard:",13,10,"$"
data ENDS
code SEGMENT
ASSUME CS:code
main: MOV DX,proc_53 ;283为8253控制口地址
MOV AL,00011111b ;通道0 方式3(方波)
OUT DX,AL
MOV DX,pro0_53 ;280为通道0口地址
MOV AL,52h ;波特率1200 异步*16
OUT DX,AL ;n=1M/1200*16=1M/19200=52 OUT0=1M/52=20kH
MOV DX,proc_51 ;2b9为8251控制口地址
MOV AL,00h
OUT DX,AL ;输出第一个0
delay
OUT DX,AL ;输出第二个0
delay
OUT DX,AL ;输出第三个0
delay
MOV AL,40h ;命令字 IR=1 内部复位
OUT DX,AL
delay
MOV AL,01111010b ;方式字 一个停止符 偶校验 7位字符
OUT DX,AL ;异步方式*16
delay
MOV AL,00010101b ;命令字 使错误标志复位 允许发送和接收
OUT DX,AL
MOV AX,data
MOV DS,AX
MOV DX,OFFSET mes
MOV AH,09h ;显示字符串
INT 21h
send: MOV DX,proc_51 ;控制口读入
IN AL,DX
TEST AL,01h ;发送是否准备好
JZ send ;未准备好 继续读
MOV AH,07h ;dos中断 键盘输入输出一个字符 输入后只存al 比较时不能用扫描码
INT 21h ;无回显
CMP AL,1bh ;或 27
JE exit
MOV AH,0eh ;BIOS中断 显示一个字符
INT 10h
ADD AL,3 ;加3后发送
MOV DX,prod_51 ;2b8为8251数据口地址
OUT DX,AL ;加3后从数据口发送
recv:MOV DX,proc_51 ;控制口读入
IN AL,DX
TEST AL,02h ;接收是否准备好
JZ recv ;未准备好 继续读
MOV DX,prod_51 ;从8251数据口读入加3后发送的数据
IN AL,DX
MOV AH,0eh ;BIOS中断 显示一个字符
INT 10h
JMP send
exit: MOV AH,4ch
INT 21h
code ENDS
END main