H_Prj06_02 8088单板机串口读取内存块
1.程序
通过查询方式检测串口接收字符'r',然后从内存地址0000:2000H开始发送512字节数据。程序使用18.432MHz时钟的16550 UART,波特率9600:
; 串口查询接收'r'后发送内存数据程序
; 硬件配置:
; PC16550 基地址: 100H
; 时钟频率: 18.432MHz
; 波特率: 9600 bps
; 数据源: 0000:2000H 开始的512字节内存ORG 100H
JMP START; 数据段
WAIT_MSG DB 'Waiting for "r"...', 0Dh, 0Ah, 0
SENDING_MSG DB 'Sending 512 bytes...', 0Dh, 0Ah, 0
DONE_MSG DB 'Transfer complete!', 0Dh, 0Ah, 0; 16550寄存器偏移地址
UART_BASE EQU 100H
RBR_THR EQU UART_BASE + 0 ; 接收/发送寄存器
LSR EQU UART_BASE + 5 ; 线路状态寄存器
LCR EQU UART_BASE + 3 ; 线路控制寄存器
DLL EQU UART_BASE + 0 ; 除数锁存低字节 (DLAB=1)
DLM EQU UART_BASE + 1 ; 除数锁存高字节 (DLAB=1); 初始化UART (波特率9600, 18.432MHz时钟)
INIT_UART:; 设置波特率除数(9600 @ 18.432MHz)MOV DX, LCRMOV AL, 80H ; 设置DLAB=1OUT DX, ALMOV DX, DLL ; 除数锁存低字节MOV AL, 78H ; 120 = 78HOUT DX, ALMOV DX, DLM ; 除数锁存高字节MOV AL, 00H ; 高位为0OUT DX, AL; 设置线路参数: 8位数据, 1停止位, 无校验MOV DX, LCRMOV AL, 03H ; 8N1, DLAB=0OUT DX, AL; 禁用中断MOV DX, UART_BASE + 1 ; IERMOV AL, 00HOUT DX, ALRET; 发送单个字符
; 输入: AL = 要发送的字符
SEND_CHAR:PUSH DXPUSH AX; 保存字符MOV AH, ALSEND_WAIT:; 检查发送保持寄存器是否为空MOV DX, LSRIN AL, DXTEST AL, 20H ; 检查THRE位(bit5)JZ SEND_WAIT ; 不为空则等待; 发送字符MOV DX, RBR_THRMOV AL, AHOUT DX, ALPOP AXPOP DXRET; 接收单个字符
; 输出: AL = 接收到的字符
RECV_CHAR:PUSH DXRECV_WAIT:; 检查接收数据就绪MOV DX, LSRIN AL, DXTEST AL, 01H ; 检查DR位(bit0)JZ RECV_WAIT ; 无数据则等待; 读取字符MOV DX, RBR_THRIN AL, DXPOP DXRET; 发送字符串
; 输入: DS:SI = 字符串地址(以0结尾)
SEND_STRING:PUSH SIPUSH AXSEND_STR_LOOP:LODSB ; 从[DS:SI]加载字符到AL, SI++OR AL, AL ; 检查是否结束(AL=0)JZ SEND_STR_DONE ; 是则结束CALL SEND_CHAR ; 发送当前字符JMP SEND_STR_LOOP ; 继续发送SEND_STR_DONE:POP AXPOP SIRET; 发送内存块
; 输入: ES:BX = 数据起始地址
; CX = 数据长度(字节数)
SEND_MEMORY:PUSH AXPUSH BXPUSH CXPUSH DX; 发送状态消息MOV SI, OFFSET SENDING_MSGCALL SEND_STRING; 设置计数器MOV CX, 512SEND_MEM_LOOP:; 读取内存字节MOV AL, ES:[BX]; 发送字节CALL SEND_CHAR; 更新指针和计数器INC BXLOOP SEND_MEM_LOOP; 发送完成消息MOV SI, OFFSET DONE_MSGCALL SEND_STRINGPOP DXPOP CXPOP BXPOP AXRET; 主程序
START:; 初始化UARTCALL INIT_UARTAGAIN: ; 显示等待消息MOV SI, OFFSET WAIT_MSGCALL SEND_STRING; 等待接收字符'r'
WAIT_FOR_R:CALL RECV_CHARCMP AL, 'r' ; 检查是否收到'r'JNE WAIT_FOR_R ; 不是则继续等待; 收到'r'后发送内存数据MOV AX, 0000H ; 设置段地址0000HMOV ES, AXMOV BX, 2000H ; 设置偏移地址2000HCALL SEND_MEMORY ; 发送512字节数据 JMP AGAIN; 程序结束MOV AH, 4CHINT 21H DB 55H,55H,55H,55H,55HEND START
2.验证