这是一个非常有趣的汇编程序,看起来像是一个运行在 8051 单片机上的**“内存踩踩乐”**小游戏或演示程序。
程序的逻辑是:从地址 00h 开始累加,当数值达到 24h (36) 时触发红色特效,达到 48h (72) 时触发蓝色特效和打印“8”的动画,最后还有 LED 闪烁和显示“猪”字的彩蛋。
1. 整理后的代码(格式化版)
我已经帮你修正了代码中的一些语法错误(如 LJMP 25h 改为 LJMP AUTO_INCREMENT ),并进行了缩进和注释排版,使其更易读。
assembly
; ============================================================
; 程序名称: 内存踩踩乐 (Memory Step Game)
; 运行环境: 8051 单片机
; 程序说明: 从00h出发,累加触发各种特效
; ============================================================
ORG 00h ; 程序起始地址
; ============================================================
; 【主程序入口】
; ============================================================
START:
MOV A, #00h ; 初始化累加器A为0
MOV R0, #00h ; R0存储当前地址/数值
MOV R1, #01h ; R1存储累加步长
; ============================================================
; 【主循环】累加并检查关键点
; ============================================================
MAIN_LOOP:
ADD A, R1 ; A = A + R1 (数值累加)
MOV R0, A ; 更新当前地址/数值
CALL PLAY_CLICK_SOUND ; 播放点击音效
; 检查是否达到 24h (36)
CJNE A, #24h, CHECK_48H
LJMP TRIGGER_24H ; 跳转到24h处理逻辑
CHECK_48H:
; 检查是否达到 48h (72)
CJNE A, #48h, MAIN_LOOP
LJMP TRIGGER_48H ; 跳转到48h处理逻辑
; ============================================================
; 【事件 1】数值达到 24h (36)
; 效果: 屏幕变红 + 成功提示 + 延时
; ============================================================
TRIGGER_24H:
MOV P1, #0F0h ; 屏幕变红色 (假设P1口控制LED或LCD背光)
CALL DISPLAY_SUCCESS_TEXT
CALL PLAY_SUCCESS_SOUND
; 延时5秒 (250 * 20ms = 5000ms)
MOV R2, #250
DELAY_5S:
CALL DELAY_20MS
DJNZ R2, DELAY_5S
MOV P1, #00h ; 恢复屏幕
LJMP AUTO_INCREMENT ; 跳转到自动累加模式
; ============================================================
; 【自动累加模式】从25h开始自动递增
; ============================================================
AUTO_INCREMENT:
MOV A, #25h ; 从25h开始
AUTO_INC_LOOP:
INC A ; 自动加1
CALL PLAY_CLICK_SOUND
CALL DISPLAY_ADDR ; 显示当前地址/数值
CALL DELAY_1S ; 延时1秒
; 检查是否达到 48h (72),未达到则继续
CJNE A, #48h, AUTO_INC_LOOP
LJMP TRIGGER_48H ; 达到48h,触发下一阶段
; ============================================================
; 【事件 2】数值达到 48h (72)
; 效果: 屏幕变蓝 + 漂浮文字 + 打印满屏"8"
; ============================================================
TRIGGER_48H:
MOV P1, #0Fh ; 屏幕变蓝色
CALL DISPLAY_FLOATING_TEXT
CALL PLAY_SUCCESS_SOUND
CALL DELAY_2S
CALL PRINT_EIGHTS ; 打印满屏的"8"
LJMP 00h ; 重置程序
; ============================================================
; 【子程序】打印满屏的"8"
; ============================================================
PRINT_EIGHTS:
MOV R3, #00h ; 总打印计数
MOV R4, #00h ; 行号
MOV R5, #00h ; 列号
PRINT_LOOP:
MOV A, R5
CJNE A, #20h, CONTINUE_PRINT ; 假设每行20个字符
INC R4 ; 换行
MOV R5, #00h ; 重置列号
CONTINUE_PRINT:
CALL PRINT_CHAR_8 ; 打印字符 '8'
CALL PRINT_SPACE ; 打印空格
INC R3
INC R5
CALL PLAY_CLICK_SOUND
CALL DELAY_500MS ; 控制打印速度
MOV A, R4
CJNE A, #14h, PRINT_LOOP ; 假设打印14行
RET
; ============================================================
; 【后续流程】统计信息与彩蛋 (原代码中未被主逻辑直接调用,可作为扩展)
; ============================================================
SHOW_STATS:
MOV R6, #00h ; 8的数量
MOV R7, #00h ; 空格数量
CALL COUNT_SCREEN_CHARS
CALL DISPLAY_STATS
MOV P2, #01h ; 点亮IO1 LED
CALL START_LED_BLINK
RET
START_LED_BLINK:
MOV R8, #00h ; 闪烁计数
LED_BLINK_LOOP:
MOV A, R8
CJNE A, #64h, CONTINUE_BLINK ; 闪烁100次
LJMP DATA_PACKING
CONTINUE_BLINK:
MOV A, P2
XRL A, #02h ; IO2引脚翻转
MOV P2, A
CALL DELAY_500MS
INC R8
LJMP LED_BLINK_LOOP
DATA_PACKING:
LJMP 00h ; 跳回开始 (原代码此处逻辑未完成)
; ... (省略未完成的打包逻辑)
SHOW_PIG:
CALL CLEAR_SCREEN
MOV P1, #0A0h ; 紫色背景
CALL DISPLAY_PIG_CHAR
CALL DELAY_3S
LJMP LOOP_FLOATING_TEXT
LOOP_FLOATING_TEXT:
MOV R10, #0B4h ; 180秒
LOOP_TEXT:
MOV A, R10
JZ EXIT_PROGRAM
CALL PLAY_PIG_MUSIC
CALL DISPLAY_FLOATING_TEXT
CALL DELAY_1S
DEC R10
LJMP LOOP_TEXT
EXIT_PROGRAM:
CALL STOP_MUSIC
CALL CLEAR_SCREEN
CALL DISPLAY_EXIT_MESSAGE
SJMP $ ; 程序原地踏步结束
; ============================================================
; 【延时子程序库】
; ============================================================
DELAY_20MS:
MOV R6, #200
DELAY_20MS_LOOP:
MOV R7, #100
DELAY_20MS_INNER:
DJNZ R7, DELAY_20MS_INNER
DJNZ R6, DELAY_20MS_LOOP
RET
DELAY_500MS:
MOV R6, #25
DELAY_500MS_LOOP:
CALL DELAY_20MS
DJNZ R6, DELAY_500MS_LOOP
RET
DELAY_1S:
MOV R6, #50
DELAY_1S_LOOP:
CALL DELAY_20MS
DJNZ R6, DELAY_1S_LOOP
RET
DELAY_2S:
MOV R6, #100
DELAY_2S_LOOP:
CALL DELAY_20MS
DJNZ R6, DELAY_2S_LOOP
RET
DELAY_3S:
MOV R6, #150
DELAY_3S_LOOP:
CALL DELAY_20MS
DJNZ R6, DELAY_3S_LOOP
RET
; ============================================================
; 【占位符子程序】
; 这些函数需要根据具体硬件(LCD/蜂鸣器)编写具体代码
; ============================================================
PLAY_CLICK_SOUND: RET
PLAY_SUCCESS_SOUND: RET
PLAY_PIG_MUSIC: RET
STOP_MUSIC: RET
DISPLAY_SUCCESS_TEXT: RET
DISPLAY_FLOATING_TEXT: RET
DISPLAY_ADDR: RET
PRINT_CHAR_8: RET
PRINT_SPACE: RET
COUNT_SCREEN_CHARS: RET
DISPLAY_STATS: RET
CLEAR_SCREEN: RET
DISPLAY_PIG_CHAR: RET
DISPLAY_EXIT_MESSAGE: RET
END ; 程序结束
2. 如何运行这段程序
由于这是汇编代码,你需要一个8051 单片机开发环境来编译和运行。以下是具体步骤:
方法 A:使用 Keil C51(最专业,适合硬件开发)
1. 安装 Keil uVision:下载并安装 Keil C51 软件。
2. 新建项目:
- 打开 Keil,点击 Project -> New μVision Project 。
- 选择一个保存位置,输入项目名(如 MemoryGame )。
- 在 Select Device for Target 窗口中,选择一个 8051 兼容芯片(例如 Atmel -> AT89C51 或 NXP -> P89C51RD2 )。
- 提示是否复制启动代码时,选择 否 (因为我们写的是完整汇编,不需要默认启动代码)。
3. 添加汇编文件:
- 点击 File -> New ,新建一个文本文件。
- 将上面整理后的代码复制粘贴进去。
- 点击 Save ,保存为 main.asm (注意后缀是 .asm )。
- 在左侧 Project 窗口中,右键 Source Group 1 -> Add Existing Files to Group 'Source Group 1' ,选中 main.asm 添加进去。
4. 编译:
- 点击工具栏上的 Build 或 Rebuild 按钮(类似锤子图标)。
- 如果没有语法错误,底部 Build Output 窗口会显示 0 Error(s), 0 Warning(s) 。
5. 下载/仿真:
- 仿真:点击 Debug -> Start/Stop Debug Session (放大镜图标),可以单步执行(F11)看代码运行流程。
- 下载:连接你的 8051 开发板(如 STC89C52),使用对应的下载软件(如 STC-ISP),选择生成的 .hex 文件下载到芯片中。
方法 B:使用在线仿真器(最简单,无需安装软件)
如果你只是想看看程序逻辑是否能跑通,可以使用在线 8051 模拟器:
1. 搜索 "8051 Simulator Online" 或 "Online 8051 Assembler"。
2. 找到一个支持直接输入代码并运行的网站(例如 https://www.tutorialspoint.com/compile_8051_online.php 或类似站点)。
3. 将代码粘贴进去,点击 Assemble (汇编)和 Run (运行)。
3. 程序运行效果预测
1. 启动:程序从 00h 开始,A 寄存器开始累加。
2. 阶段一 (00h -> 24h):
- 每累加一次,播放一次“点击声”。
- 当 A 变成 24h 时,P1 口输出 0F0h (假设低四位接红灯),红灯亮,播放成功音效,延时 5 秒。
3. 阶段二 (25h -> 48h):
- 进入自动加速模式,每秒自动加 1,并显示当前数值。
4. 阶段三 (48h):
- P1 口输出 0Fh (假设高四位接蓝灯),蓝灯亮。
- 开始在屏幕上打印满屏的字符 8 ,每个字符打印间隔 0.5 秒,伴有点击声。
5. 结束:打印完成后,程序跳回 00h 重新开始。
注意:代码中 PLAY_CLICK_SOUND 、 DISPLAY_ADDR 等具体的硬件控制函数目前是 RET (空操作)。如果你在真实硬件上运行,需要根据你的 LCD1602/12864 和蜂鸣器电路,补全这些子程序的具体代码才能看到画面和听到声音。 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?注册
×
|