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

8088单板机监控程序解读(四)

分析监控程序的按键扫描代码

8088kit用户手册资源-CSDN下载

监控程序的按键扫描代码位于SCAN1函数(源码第 1107-1180 行),采用动态扫描方式同时驱动 6 位数码管显示和检测 32 个按键。

硬件基础

根据手册和原理图(第 34 页),按键和数码管的硬件连接:

端口地址功能
PORT10001H数码管位选(选择哪一位点亮),同时用于键盘列扫描输出
PORT20002H数码管段选(显示什么字符),输出到 7 段数码管
PORT00100H键盘行输入(读取哪一行按键被按下),bit7 也用于 UART RXD

键盘矩阵:4 列 × 8 行 = 32 个按键(但实际只用了部分,对应 KEYTAB 表)

SCAN1 函数完整源码分析

1107 C616 B300 MOV BL,0 ; BL = 列计数器(0-3) 1108 C618 B701 MOV BH,1 ; BH = 列扫描掩码,初始 0000 0001B 1109 C61A B4FF MOV AH,-1 ; AH = 返回值,-1 表示无按键 1110 C61C B108 MOV CL,8 ; CL = 总列数(4列)×2?实际是 8 次循环?

外层循环:扫描 4 列

1113 C61E KCOL: 1114 C61E 8AC7 MOV AL,BH ; 取当前列掩码 1115 C620 F6D0 NOT AL ; 取反(因为列选可能是低电平有效) 1116 C622 E601 OUT PORT1,AL ; 输出到位选端口,选中当前列

关键:这里复用了数码管的位选信号作为键盘的列扫描输出。当某一位为低电平时,该列被选中,按键的行线可以读出。

显示当前列的数码管内容

1120 C624 8A04 MOV AL,[SI] ; 从显示缓冲区读取该位的段码 1121 C626 E602 OUT PORT2,AL ; 输出到段选端口,显示字符 1123 C628 247F AND AL,7FH ; 屏蔽小数点位(位7) 1124 C62A 3C06 CMP AL,6 ; 检查是否是 '-' 符号(段码 06H) 1125 C62C 7504 JNZ SKIP10 1126 C62E B503 MOV CH,3 ; 如果是 '-',短延时 3 1127 C630 EB02 JMP DELAY1 1128 C632 B50A SKIP10: MOV CH,10 ; 否则延时 10 1129 C634 FECD DELAY1: DEC CH 1130 C636 75FC JNZ DELAY1

这段是显示延时,让数码管点亮一段时间,保证亮度。不同字符延时不同(-符号笔画少,亮度高,所以延时短)。

关闭显示(消隐)

1137 C638 B000 MOV AL,0 ; 熄灭所有段 1138 C63A E602 OUT PORT2,AL

关闭显示是为了避免在按键扫描时产生鬼影。

等待显示稳定

1141 C63C B51E MOV CH,30 ; 延时 30 1142 C63E FECD DELAY3: DEC CH 1143 C640 75FC JNZ DELAY3

内层循环:扫描当前列的 8 行

1148 C642 B506 MOV CH,6 ; 扫描 6 行(实际只用了 6 行?) 1149 C644 BA0001 MOV DX,PORT0 ; 读行输入端口 1150 C647 EC IN AL,DX 1151 C648 DD08 KROW: RCR AL,1 ; 循环右移一位,检查最低位 1152 C64A 7202 JC NOKEY ; 如果该位为 1(无按键),跳转 1153 C64C 8AE3 MOV AH,BL ; 有按键!保存当前列号到 AH 1154 C64E FEC3 NOKEY: INC BL ; BL++(行号递增) 1155 C650 FECD DEC CH ; 行计数器减 1 1156 C652 75F4 JNZ KROW ; 继续扫描下一行

按键编码:最终AH= 列号(0-3)×8 + 行号(0-7),范围 0-31。

切换到下一列

1162 C654 DD07 ROL BH,1 ; 列掩码左移,切换到下一列(0001→0010→0100→1000) 1163 C656 46 INC SI ; 显示缓冲区指针后移,指向下一位 1164 C657 FEC9 DEC CL ; 列计数器减 1 1165 C659 75C3 JNZ KCOL ; 4 列未扫完,继续

检查串口数据

1170 C65B BA0001 MOV DX,PORT0 1171 C65E EC IN AL,DX 1172 C65F A880 TEST AL,80H ; 测试 RXD 位(bit7) 1173 C661 7502 JNZ no_serial ; 为高(空闲),无串口数据 1174 C663 B424 MOV AH,36 ; 有串口数据,返回特殊扫描码 36 1175 C665 90 no_serial: NOP 1176 C666 C3 RET

返回

  • AH = 0-35:有按键,返回按键扫描码

  • AH = 36:有串口数据

  • AH = 255 (FFH):无按键

扫描时序图

循环 4 次(每列一次): ┌─────────────────────────────────────────────────────────┐ │ 选中列 N(输出到 PORT1) │ │ 显示该列对应位的数码管(输出段码到 PORT2) │ │ 延时(保持显示) │ │ 关闭显示(PORT2=0) │ │ 延时(消隐) │ │ 循环 6-8 次(每行一次): │ │ 读取 PORT0 │ │ 测试该行是否有按键按下 │ └─────────────────────────────────────────────────────────┘ 切换到下一列,SI++(显示缓冲区指针后移)

按键扫描码到内部码的转换

扫描得到AH(0-35)后,主程序通过查表KEYTAB转换为内部功能码:

243 COD4 BE69CA MOV SI,KEYTAB ; KEYTAB 表地址 244 COD7 8AC4 MOV AL,AH ; 扫描码 245 COD9 B400 MOV AH,0 246 COD8 03F0 ADD SI,AX ; SI = KEYTAB + 扫描码 247 CODD 2E SEG CS 248 CODE 8A04 MOV AL,[SI] ; 读取内部码

KEYTAB 表(源码第 1985-2022 行)定义了每个按键对应的功能码,例如:

  • 扫描码 0 →10H(IP 键)

  • 扫描码 1 →11H(REG 键)

  • 扫描码 2 →12H(DATA 键)

  • 扫描码 3 →13H(ADDR 键)

  • ...

设计特点总结

特点说明
时分复用数码管显示和键盘扫描共用同一套硬件,通过时间片分离
动态扫描6 位数码管轮流点亮,利用视觉暂留效果
矩阵扫描4 列 × 8 行矩阵键盘,节省 I/O 引脚
消隐处理切换列时先关闭显示,避免鬼影
串口检测键盘扫描同时也检测 UART 数据,实现“伪中断”式串口接收
返回值设计AH=255 无按键,AH=0-35 有按键,AH=36 有串口数据

这是一个非常经典的嵌入式系统键盘/显示扫描设计,充分利用了 8088 的 I/O 端口,硬件简洁但功能完整。

http://www.cnnetsun.cn/news/2819894.html

相关文章:

  • STM32CubeMX配置FreeRTOS信号量时,这3个坑我帮你踩过了(附避坑指南与调试技巧)
  • 女硬件工程师多吗?
  • Python 3.13 连续迭代,自由线程、JIT 编译器、子解释器三剑齐发
  • 避坑指南:ArcGIS里做IDW插值,你的搜索半径和幂值设置对了吗?
  • 第四周小学期
  • SpringAOP原理和代理模式详解
  • SpeakCoach
  • 实测揭秘:WPS双进程备份机制,内存占用真的高吗?手把手教你手动清理驻留进程
  • VMware网络感叹号?别急着重装!手把手教你修复VMnet1/VMnet8驱动代码31错误
  • 扫描阅卷机支持哪些格式的试卷?
  • 2、K8S网络概述
  • x64汇编案例5
  • SysConfig Device Support 笔记
  • VC6环境下内存直载DLL的完整可运行工程包(含源码、编译成品与测试模块)
  • ToxiTwitch:基于混合模型的Twitch实时聊天毒性检测
  • 新闻语义处理流水线:面向金融NLP的结构化解码与时序锚定
  • AI动态简报之商业洞察篇(2026.06.07)
  • 电机控制工程师必看:手把手教你配置TMS320F280049的SDFM模块进行电流采样
  • 【个人博客—山东大学项目实训——古诗词与文章智能创作助学平台(六)】
  • 生产级机器学习服务的三大支柱:可观测性、弹性和契约
  • AI实战第5篇:Python+DeepSeek智能简历优化器,HR看了直呼专业
  • 跨境支付业务流程
  • Sqribble文档自动化系统:模板驱动的结构化出版流水线
  • 别再只用System.out.printf了!Java格式化数字的三种姿势,从基础到实战一次讲透
  • ROS 2进阶:深入理解rosdep与package.xml的依赖关系,打造可复用的机器人软件包
  • Vue3 + Baidu Map API 实战:手把手教你实现一个带搜索和自定义弹窗的店铺地图
  • 多维聚合中的数据变形:从GROUP BY到高维视图的工程实践
  • 手机存储速度翻倍的秘密:一文看懂UFS 2.2里的M-PHY物理层(附避坑指南)
  • 告别黑盒:用dotPeek和Symbol Server在VS里一步步调试Newtonsoft.Json源码
  • AT24C02不止是存储:聊聊I2C总线上的设备地址与多机通信那点事