8250 自发自收实验
实验内容:
用 8250 实现串行口异步通信,自发自收,波特率1200bps。采用查询方式发送,采用中断方式接收。发送程序连续将符号 '*' 从串口 COM1
发送出去,COM1
接收到的字符显示在屏幕上,当线路出错时屏幕输出 '#'。
(本程序还不完善!)
[org 0x7c00]
start:
cli
mov bx,0x30 ; INT 0CH,中断向量表的偏移量 0x30
mov word [cs:bx],int_recv ; 自定义的中断处理程序的偏移地址
mov [cs:bx+2],cs ; 段地址
; 开放 COM1 的中断请求
in al,0x21 ; 读 8259 主片 OCW1
and al,0xef ; COM1 对应 IRQ4
out 0x21,al
; 设置波特率 9600 b/s
mov al,0x80 ; 设 DLAB 为 1,访问除数锁存器
mov dx,0x03fb ; COM1 线路控制寄存器(LCR)
out dx,al
mov al,0x0c
mov dx,0x03f8 ; COM1 的除数锁存器低字节(DLL)
out dx,al
mov al,0x00
mov dx,0x03f9 ; COM1 的除数锁存器低字节(DLH)
out dx,al
mov al,0b_00_001_0_11 ; 设 DLAB 为 0,为正常模式;8 位数据位,1 位停止位,1 位奇校验位
mov dx,0x03fb ; COM1 线路控制寄存器(LCR)
out dx,al
mov al,0b_000_0_1011 ; 令 DTR、RTS 和 OUT2 有效
mov dx,0x03fc ; COM1 Modem 控制器(MCR)
out dx,al
mov al,0x01 ; 只允许接收数据中断
mov dx,0x03f9 ; COM1 中断允许寄存器(IER)
out dx,al
sti
infi:
mov dx,0x03fd ; COM1 线路状态寄存器(LSR)
in al,dx
test al,0x20 ; 测试发送保持寄存器是否为空
jz infi ; THR 不空则等待
mov al,'X' ; 发送字符 'X'
mov dx,0x03f8 ; COM1 的寄存器地址
out dx,al
jmp infi
int_recv:
pusha
call beep
.int_recv.try:
mov dx,0x03fd ; COM1 线路状态寄存器(LSR)
in al,dx ; 取 COM1 线路状态
test al,0x1e
jnz .int_recv.err
mov dx,0x03f8 ; COM1 的寄存器地址
in al,dx
call printc
.int_recv.fin:
; EOI
mov al,0x20 ; 8259 OCW2,一般 EOI
out 0x20,al
popa
iret
.int_recv.err:
mov dx,0x03f8 ; 清除读接收缓冲寄存器(RBR),以免溢出错
in al,dx
mov al,'#'
call printc
jmp .int_recv.fin
; Print a character
; al character
printc:
push ax
mov ah,0x0e
int 0x10
pop ax
ret
; Make a beep sound
beep:
pusha
mov al,0xb6
out 0x43,al ; 8254 CNT2
mov ax,0x0533 ; Sound frequency 896 Hz
out 0x42,al
mov al,ah
out 0x42,al
in al,0x61 ; 8255 PB
mov ah,al
or al,0x03 ; Enable 8254 CNT2
out 0x61,al
mov cx,0x0055 ; Last for some time
loop2:
push cx
mov cx,0xffff
loop1:
nop
loop loop1
pop cx
loop loop2
mov al,ah
out 0x61,al ; Restore 8255 PB
popa
ret
signature:
%if $-$$>510
%fatal "stage1 code exceed 512 bytes."
%endif
times 510-($-$$) \
db 0
db 0x55,0xaa
参考资料:
教材 P192 表 4.10
Last updated