在嵌入式系统的奇妙世界中,汇编语言与硬件的结合总是充满了无限可能。今天,我将带你走进一场充满乐趣的实验:如何用汇编语言在单片机上实现矩阵按键输入和数码管显示功能。这不仅是一次技术探索,更是一场点亮创意与灵感的奇幻之旅!
实验背景
矩阵按键是一种常见的输入设备,通过行列扫描的方式实现多个按键的功能。数码管则是用于显示数字的常用设备,通过段选和片选信号控制显示内容。在本次实验中,我选择了经典的AT89C51 单片机,利用矩阵键盘输入数字,并通过数码管显示输入的数字序列。
实验要求
- 利用单片机开发板的矩阵键盘实现个人学号后8位的输入和显示。
- 利用矩阵键盘 S1~S10输入数字 1~0
- 利用数码管 LED8~LED1从左到右显示8位学号
参考电路图

实验工具
Keil uVision4:用于编写汇编代码并验证是否成功
PZ-ISP普中自动下载软件:用于将汇编代码烧录至开发板上
AT89C51:一款经典的 8 位微控制器
实验设计
整体思路
要实现矩阵按键输入和数码管显示功能,我们需要让汇编语言与硬件伙伴紧密配合。具体来说:
- 创建一个数组用于存放要显示在数码管中的八位数字,并不断将数组值显示在数码管上。
- 处理矩阵按键,将每次输入的值更新在数组的第一位,并逆序更新数组。
- 使用显示程序充当防抖延时程序,并将显示程序加入到每一次按键的单个处理程序中,以避免在判断按键松开时出现黑屏的情况。
流程图

主要模块设计
(1)初始化模块
初始化模块负责配置单片机的 I/O 口、设置数码管显示数组的初始值等。
START:
ARRAY_START EQU 30H ; 创建显示值数组
ARRAY_END EQU 37H
MOV R0, #ARRAY_START ; R0 作为指向第一位元素的指针
MOV R2, #00H ; R2 作为第一位的位选码
MOV R3, #00H ; R3 用于存放每次矩阵按键输入值
MOV R7, #8 ; 循环次数
STORE_LOOP:
MOV @R0, #0 ; 初始化显示值数组为全 0
INC R0
DJNZ R7, STORE_LOOP
AJMP KEY
(2)主循环模块
主循环模块负责不断检测按键状态,并调用相应的处理程序。
KEY:
LCALL DEBOUNCE ; 显示
MOV P1, #0FH ; 初始化按键电平为 00001111
MOV A, P1
XRL A, #0FH ; 异或操作,所有位相同时为 0
JZ KEY ; 即没有被按下时重新检测
LCALL DEBOUNCE ; 防抖操作
MOV A, P1
XRL A, #0FH ; 再检测一次按键状态
JZ KEY
MOV A, P1 ; 存入按键电平,被按下的列电平被拉低
JNB ACC.3, PK1 ; 先检测哪一列按键被按下
JNB ACC.2, PK2
JNB ACC.1, PK3
JNB ACC.0, PK4_0
(3)按键处理模块
按键处理模块负责检测具体哪个按键被按下,并将对应的数字存储到数组中。
PK1:
MOV P1, #0F0H ; 此时将行电平置 1
JNB P1.7, PK1_NUM1
JNB P1.6, PK1_NUM2
JNB P1.5, PK1_NUM3
JNB P1.4, PK1_NUM4
PK1_NUM1:
LCALL DEBOUNCE ; 调用显示子程序,防止不松开按键时黑屏
JNB P1.7, PK1_NUM1 ; 按键未松开时不进行下一步
MOV R3, #1
LJMP KEY1
(4)数码管显示模块
数码管显示模块负责将数组中的数字显示在数码管上。
DISPLAY:
MOV R0, #ARRAY_START ; 初始化指针为数组首地址
MOV R7, #8 ; 初始化显示位数
MOV R2, #00H ; 第一位的位选码
DISPLAY_LOOP:
MOV A, R2 ; 初始化位选码
MOV P2, A ; 传入位选码
MOV A, @R0 ; 传入指针
MOV DPTR, #TABLE
MOVC A, @A+DPTR ; 从 TABLE 中查找对应的段码
MOV P0, A ; 输出到数码管
ACALL DELAY
MOV A, R2 ; 更新位选码
ADD A, #04H
MOV R2, A
MOV A, R0 ; 更新指针
ADD A, #1
MOV R0, A
DJNZ R7, DISPLAY_LOOP
RET
(5)延时模块
延时模块用于实现按键去抖和显示延时。
DELAY:
MOV R4, #1
DEL0:
MOV R5, #10
DEL1:
MOV R6, #20
DEL2:
DJNZ R6, DEL2
DJNZ R5, DEL1
DJNZ R4, DEL0
RET
(6)按键防抖模块
按键防抖模块通过多次显示程序充当防抖延时程序,确保按键状态的稳定性。
DEBOUNCE:
MOV R3, #7
DEB0:
DJNZ R3, DEB1
RET
DEB1:
ACALL DISPLAY
AJMP DEB0
(7)显示值更新模块
显示值更新模块负责将新输入的数字更新到数组中,并逆序更新数组。
UPDATE:
MOV R0, #ARRAY_END
MOV A, R0
DEC A
MOV R1, A ; 设置 R1 尾地址前一位
MOV R0, #ARRAY_END ; 设置 R0 为尾地址
MOV R7, #7 ; 设置循环次数
ACALL UPDATE_LOOP ; 先把前七位更新,随后把最新输入一位放入最低位
MOV R0, #ARRAY_START ; 回到首地址
MOV A, R3 ; 最新输入
MOV @R0, A
RET
UPDATE_LOOP:
MOV A, @R1
MOV @R0, A
DEC R0
DEC R1
DJNZ R7, UPDATE_LOOP
RET
(8)数码管查找表模块
数码管查找表模块用于将数字转换为数码管的段选信号。
TABLE: DB 03FH,06H,05BH,04FH,66H,06DH,07DH,07H,07FH,06FH,00H
实现效果
通过调试和验证,矩阵按键输入和数码管显示功能成功实现!按下矩阵键盘上的不同按键,数码管能够清晰地显示对应的数字序列。整个设备运行流畅,按键响应灵敏,显示效果稳定。

总结与思考
1. 深入理解硬件接口:通过编写汇编代码,可以更深入地理解单片机的硬件接口和工作原理。
2. 底层操作的重要性:学习汇编语言有助于理解计算机的底层操作,为更高级的编程语言打下基础。
3. 代码结构的组织:学会了如何组织代码结构,实现复杂的功能,如防抖、按键处理和显示更新。
4. 调试与错误解决:在编写和调试过程中,学会了如何识别和解决汇编语言中的错误。
5. 耐心与细致:汇编语言编程需要高度的注意力和耐心,因为错误可能非常细微且难以发现。
结语
通过这次实验,我不仅在技术上有了新的突破,更对嵌入式系统开发充满了兴趣。汇编语言虽然古老,但它依然有着强大的生命力,能够帮助我们实现各种奇妙的功能。如果你对汇编语言或嵌入式开发感兴趣,欢迎一起交流探讨!让我们在技术的道路上共同进步,继续探索更多神奇的魔法!✨

360

被折叠的 条评论
为什么被折叠?



