You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于x86汇编通过串口传输16位数据的问题排查

问题分析与修复方案

你的核心问题在于依赖固定延迟同步收发字节,这完全不可靠——COM口通信时序由波特率决定,固定的loop延迟无法适配不同波特率或系统运行差异,极易导致接收端读取到错误字节(比如未等第二个字节传输完成就读取,或是读到下一次传输的数据)。此外,代码未检查COM口状态寄存器确认数据就绪,进一步放大了出错概率。

问题点拆解

  • 无状态校验:接收时直接执行in al, dx,未确认COM口数据寄存器就绪,可能读取无效数据
  • 固定延迟不可靠:cx=200的循环延迟在不同系统、波特率下时长不一致,无法保证字节传输同步
  • 字节序未明确:虽数据最大值为8(16位下高字节为0),但收发双方需严格遵循相同字节序(小端/大端)

修复后的代码

接收子程序(带硬件状态检查)

receive proc
    mov data_in, 0 ; 初始化接收变量
    mov dx, 03FDH  ; COM1线路状态寄存器地址
wait_first_byte:
    in al, dx
    test al, 01H   ; 检查DR位(数据就绪标志)
    jz wait_first_byte ; 未就绪则循环等待

    mov dx, 03F8H  ; COM1数据寄存器
    in al, dx
    mov byte ptr data_in, al ; 存储低字节

wait_second_byte:
    mov dx, 03FDH
    in al, dx
    test al, 01H
    jz wait_second_byte

    mov dx, 03F8H
    in al, dx
    mov byte ptr data_in + 1, al ; 存储高字节
    ret
receive endp

发送子程序(带发送完成校验)

transmit proc
    mov dx, 03FDH  ; 线路状态寄存器
wait_tx_empty_first:
    in al, dx
    test al, 20H   ; 检查THRE位(发送保持寄存器空标志)
    jz wait_tx_empty_first

    mov dx, 03F8H
    mov al, byte ptr data_out ; 发送低字节
    out dx, al

wait_tx_empty_second:
    mov dx, 03FDH
    in al, dx
    test al, 20H
    jz wait_tx_empty_second

    mov dx, 03F8H
    mov al, byte ptr data_out + 1 ; 发送高字节
    out dx, al
    ret
transmit endp

关键改进说明

  • 硬件状态同步:通过读取03FDH线路状态寄存器的对应标志位,确保数据就绪(接收)或发送寄存器空闲(发送),这是COM口通信的标准可靠做法,彻底替代不可靠的固定延迟
  • 明确字节顺序:代码采用先低字节、后高字节的小端模式收发,若你的数据存储为大端,只需调换两个字节的读写顺序即可
  • 适配性提升:完全基于硬件状态判断,可适配任意波特率和系统环境

另外,由于你的数据最大值为8(二进制00001000),16位数据的高字节始终为0,可优化收发逻辑:仅传输低字节,接收时直接将高字节置0,能减少一半通信时间,前提是双方提前约定该规则。

内容的提问来源于stack exchange,提问作者zizo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 04:06:08