当前位置: 首页 > news >正文

H_Prj06 8088单板机的串口

1.串口控芯片PC16550

2.电平转换,使用CH340G  232转换成USB

3.验证程序

; 串口控制LED程序 (18.432MHz时钟)
; 硬件配置:
;   PC16550 基地址: 100H 
;   8259 PIC 端口: 400H(命令), 402H(数据)
;   LED端口: 800H (0xFF亮, 0x00灭)
;   16550中断引脚连接8259的IR1 (中断类型码21H)ORG 100H            ; COM文件起始地址
JMP INIT            ; 跳转到初始化程序; 数据段
RECV_BYTE DB 0      ; 接收数据字节
LED_STATE DB 00H   ; LED初始状态(全亮)
INTR_MASK DB 0ffh     ; 保存原始中断屏蔽字; 16550寄存器偏移地址
UART_BASE EQU 100H
RBR_THR EQU UART_BASE + 0  ; 接收/发送寄存器
IER     EQU UART_BASE + 1  ; 中断使能寄存器
IIR_FCR EQU UART_BASE + 2  ; 中断标识/FIFO控制
LCR     EQU UART_BASE + 3  ; 线路控制寄存器
MCR     EQU UART_BASE + 4  ; 调制解调器控制寄存器
LSR     EQU UART_BASE + 5  ; 线路状态寄存器
DLL     EQU UART_BASE + 0  ; 除数锁存低字节 (DLAB=1)
DLM     EQU UART_BASE + 1  ; 除数锁存高字节 (DLAB=1); 8259端口
PIC_CMD EQU 400H
PIC_DATA EQU 402H; 中断服务程序(IR1)
UART_ISR PROC FARPUSH AXPUSH DX; 检查中断源MOV DX, IIR_FCRIN AL, DXTEST AL, 1        ; 检查是否有待处理中断JNZ ISR_EXIT      ; 无中断则退出; 仅处理接收数据中断TEST AL, 4        ; 检查是否为接收中断JNZ ISR_EXIT      ; 不是则退出; 读取接收到的数据MOV DX, RBR_THRIN AL, DXMOV [RECV_BYTE], AL; 根据接收字符控制LEDCMP AL, '1'       ; 接收到'1'?JE TURN_ONCMP AL, '0'       ; 接收到'0'?JE TURN_OFFJMP UPDATE_LED    ; 其他字符不改变状态TURN_ON:MOV [LED_STATE], 055H ; 设置全亮JMP UPDATE_LEDTURN_OFF:MOV [LED_STATE], 00H  ; 设置全灭UPDATE_LED:; 更新LED状态MOV DX, 800HMOV AL, [LED_STATE]OUT DX, AL; 回显接收到的字符MOV DX, RBR_THRMOV AL, [RECV_BYTE]OUT DX, ALISR_EXIT:; 发送EOI到8259MOV AL, 20HMOV DX, PIC_CMDOUT DX, ALPOP DXPOP AXIRET
UART_ISR ENDP; 初始化UART (波特率9600, 18.432MHz时钟)
INIT_UART:; 设置波特率除数(9600 @ 18.432MHz); 除数 = 18.432MHz / (16 * 9600) = 120 (78H)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; 启用FIFOMOV DX, IIR_FCRMOV AL, 0C7H      ; 启用FIFO, 14字节触发点OUT DX, AL; 设置调制解调器控制MOV DX, MCRMOV AL, 0BH       ; 启用OUT2(中断使能), RTS和DTROUT DX, AL; 启用接收数据中断MOV DX, IERMOV AL, 01H       ; 仅启用接收数据中断OUT DX, ALRET; 初始化8259
INIT_PIC:; 保存原始中断屏蔽字MOV DX, PIC_DATAIN AL, DXMOV [INTR_MASK], AL; 初始化8259MOV DX, PIC_CMDMOV AL, 13H       ; ICW1: 边沿触发, 级联, 需要ICW4OUT DX, ALMOV DX, PIC_DATAMOV AL, 20H       ; ICW2: 中断向量基值20HOUT DX, ALMOV AL, 01H       ; ICW4: 8086模式, 非缓冲, 正常EOIOUT DX, AL; 启用IR1中断MOV AL, [INTR_MASK]AND AL, 0FDH      ; 清除IR1屏蔽位(11111101)OUT DX, ALRET; 初始化LED
INIT_LED:MOV DX, 800HMOV AL, [LED_STATE] ; 初始状态(全亮)OUT DX, ALRET; 精确1秒延时子程序
; 输入: 无
; 输出: 无
; 使用寄存器: CX, DX
DELAY_1S PROCPUSH CXPUSH DX; 使用EMU8086的精确延时方法MOV CX, 05H      ; 外层循环次数 (调整此值可改变总延时)
DELAY_OUTER:MOV DX, 4FFFH    ; 内层循环计数器; 精确计时循环 (约0.066秒)
DELAY_INNER:NOP              ; 1周期NOP              ; 1周期NOP              ; 1周期DEC DX           ; 1周期JNZ DELAY_INNER  ; 4周期(跳转)/3周期(不跳)LOOP DELAY_OUTER ; 17/5周期; 微调延时 (约0.01秒)MOV CX, 0FFH
MICRO_DELAY:NOPNOPLOOP MICRO_DELAYPOP DXPOP CXRET
DELAY_1S ENDP; 发送单个字符
; 输入: 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; 发送字符串
; 输入: DS:SI = 字符串地址(以0结尾)
SEND_STRING:PUSH SIPUSH AXSEND_LOOP:LODSB             ; 从[DS:SI]加载字符到AL, SI++OR AL, AL         ; 检查是否结束(AL=0)JZ SEND_DONE      ; 是则结束CALL SEND_CHAR    ; 发送当前字符JMP SEND_LOOP     ; 继续发送SEND_DONE:POP AXPOP SIRET   ; 主初始化程序
INIT:CLI               ; 关中断; 设置中断向量(21H号中断)XOR AX, AXMOV ES, AXMOV DI, 21H * 4    ; 中断向量表地址MOV AX, OFFSET UART_ISRCLDSTOSW             ; 设置偏移地址MOV AX, CSSTOSW             ; 设置段地址; 初始化UARTCALL INIT_UART; 初始化8259; CALL INIT_PIC; 初始化LEDCALL INIT_LEDSTI               ; 开中断; 主循环(等待中断)
MAIN_LOOP:;HLT               ; 等待中断; 点亮LEDMOV DX, 800HMOV AL, 0FFhOUT DX, AL; 发送字符串MOV SI, OFFSET MESSAGECALL SEND_STRINGCALL DELAY_1S     ; 延时1秒; 熄灭LEDMOV AL,00HOUT DX, ALCALL DELAY_1S     ; 延时1秒                                               JMP MAIN_LOOP                 MESSAGE DB 'Hello Worl!     ',13,10, 0  ; 要发送的字符串 (以0结尾)DB   55H,55H,55H,55H,55HEND INIT             ; 程序结束点

4.验证结果

 

http://www.lqws.cn/news/191593.html

相关文章:

  • Java下载文件(特殊字符编码处理)
  • 为什么说数列是特殊的函数
  • 2025主流智能体Agent终极指南:Manus、OpenManus、MetaGPT、AutoGPT与CrewAI深度横评
  • Day14
  • Java-IO流之压缩与解压缩流详解
  • 前端开发面试题总结-JavaScript篇(一)
  • SQLAlchemy 中的 func 函数使用指南
  • 手机号段数据库的作用
  • 传统的将自然语言转化为嵌入向量的核心机制是:,将离散的语言符号转化为连续的语义向量,其核心依赖“上下文决定语义”的假设和神经网络的特征提取能力。
  • SATA3.0接口PCB布局走线注意事项
  • 【各种主流消息队列(MQ)对比指南】
  • vue3:十五、管理员管理-页面搭建
  • CMake 为 Debug 版本的库或可执行文件添加 d 后缀
  • vue组件的data为什么是函数?
  • FPGA没有使用的IO悬空对漏电流有没有影响
  • 毫米波雷达基础理论(3D+4D)
  • 如何使用索引和条件批量更改Series数据
  • MajicTryOn(基于wanvideo的虚拟试穿项目)
  • C++.OpenGL (7/64)摄像机(Camera)
  • Dify工具插件开发和智能体开发全流程
  • GNSS终端授时方式-合集:PPS、B码、NTP、PTP、单站授时,共视授时
  • go语言学习 第7章:数组
  • springcloud SpringAmqp消息队列 简单使用
  • MCP协议三种传输机制全解析
  • 【51单片机】0. 基础软件安装
  • 动量及在机器人控制中的应用
  • 数据治理在制造业的实践案例
  • 【AI】智驾地图在不同自动驾驶等级中的作用演变
  • 在maven项目中 继续增加maven 项目
  • Power Query动态追加查询