找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2374|回复: 1
收起左侧

基于STC89C52RC单片机LCD12864和DS1302的多汇编文件俄罗斯方块+时间显示

[复制链接]
ID:829402 发表于 2021-2-18 18:00 | 显示全部楼层 |阅读模式
本帖最后由 liuyken 于 2021-3-10 17:54 编辑

本人非计算机科班出身,学习单片机是出于个人兴趣爱好。为了更好地理解单片机的工作原理,最近学了51单片机汇编语言,学习过程中为了练手,将就手中的一块开发板写了这个俄罗斯方块小游戏,芯片是STC89C52RC,显示屏是LCD12864(驱动芯片UC1701X,不带字库),时钟芯片是DS1302,游戏过程可以暂停/继续,可以存档/读取存档(使用芯片自带的eeprom),时间日期可调。游戏过程中碰撞检测采用位运算,即将图块与背景墙按位与,结果不为0则表示有碰撞。
代码由9个asm文件组成
LCD12864和DS1302的连线请见代码内的定义
4x4矩阵键盘的说明请见下图

矩阵键盘.jpg

贴上几个代码运行的画面:

1.jpg 2.jpg 3.jpg 4.jpg 5.jpg

部分代码如下:

EXTRN BIT (key_pressed_flag,key_renewed_flag,confirm_option,menu_option,is_record_5,is_record_6,If_bottom,auto_down_flag)
EXTRN BIT (if_blink,is_pause,is_escape,Game_over_flag,is_record_1,is_record_2,is_record_3)
EXTRN BIT (is_set_time)

EXTRN DATA (Menu_options,Location_Y,Location_X,Current_block_no,Next_block_no,Current_shape)
EXTRN DATA (msn,auto_down_count,auto_down_count_2,auto_down_speed,Blink_count)

EXTRN IDATA (STACK)

EXTRN CODE (Init_LCD,Clean_screen,Draw_frame,Init_game,Clean_game_area,Load_enter_game_menu,Change_enter_menu_option)
EXTRN CODE (Move_menu_option_by_key,Display_records_menu,BCD_preload_scores,Display_preload_scores)
EXTRN CODE (Load_record,BCD_scores,Display_scores,Set_speed,Display_the_speed,Load_dropping_block)
EXTRN CODE (Create_shape_no,Display_the_next_block,Set_boundary,Copy_background,Cover_background,Display_by_bit)
EXTRN CODE (Recover_background,move_by_key,Judge_and_move_down,Stick_to_background,Judge_and_remove_full_lines,Judge_if_game_over)
EXTRN CODE (Move_down_remained_lines,Count_scores,Display_pause,resume_by_key,Load_exit_game_menu,Change_exit_menu_option)
EXTRN CODE (Display_game_over,Change_record_option,Escape_by_key,Save_record,Scan_keys)
EXTRN CODE (Get_time_from_DS1302,Init_DS1302,Display_time,Display_the_ok_button)
EXTRN CODE (Change_time_option_by_key,Change_time_by_key,Set_time_by_option,Set_time_keys)
EXTRN CODE (Enable_write_to_DS1302,Disable_write_to_DS1302,Write_confirmed_data_to_DS1302,Clr_record_flags)

PUBLIC Delay_msn

;====================================================================================================================================
CODE_SEG   SEGMENT   CODE
                RSEG  CODE_SEG

;====================================================================================================================================
;+++++++++++++++++++++
;主程序
                org 0000H
                ajmp START
                org 000BH
                ajmp Timer_0


                org 0030H
START:
                mov SP,#(STACK-1)

                mov TMOD,#01H                                          ;定时器0工作在模式1
                mov TH0,#0DBH                                          ;预装载值56319,时长约10ms
                mov TL0,#0FFH


                setb EA
                setb ET0
                setb TR0

                Lcall Init_LCD
                Lcall Init_DS1302
;进入游戏菜单界面
Enter_start_game_menu:
                mov Menu_options,#1
                mov Blink_count,#2
                Lcall Clean_screen
                Lcall Draw_frame
                Lcall Init_game
Loop_start_game_menu:
                Lcall Clr_record_flags
                Lcall Get_time_from_DS1302
                Lcall Display_time
                Lcall Load_enter_game_menu
                jb key_pressed_flag,to_execute_enter_menu_key_motion
                ajmp Loop_start_game_menu
to_execute_enter_menu_key_motion:
                Lcall Move_menu_option_by_key
                jnb is_set_time,no_set_time
                clr is_set_time
                Ljmp to_set_time
no_set_time:
                Lcall Change_enter_menu_option
                jnb confirm_option,Loop_start_game_menu
                clr confirm_option
                jnb menu_option,Start_new_game
Load_read_records_menu:
                Lcall Clean_game_area
                mov Menu_options,#1
Loop_read_records_menu:
                Lcall Display_records_menu
                Lcall BCD_preload_scores
                Lcall Display_preload_scores
Loop_read_record_key:
                jb key_pressed_flag,to_execute_read_key
                ajmp Loop_read_record_key
to_execute_read_key:
                Lcall Move_menu_option_by_key
                Lcall Change_record_option
                jnb confirm_option,Loop_read_records_menu
                jnb is_record_5,to_load_data_and_start
                clr is_record_5
                ajmp Enter_start_game_menu
to_load_data_and_start:
                Lcall Load_record
                ajmp Loop_game
Start_new_game:
                Lcall Init_game
;游戏过程
Loop_game:
                Lcall BCD_scores
                Lcall Display_scores
                clr If_bottom                                                                  ;重置标志
                Lcall Set_speed
                Lcall Display_the_speed                                                  ;输入参数Auto_down_speed(该参数值由定时中断服务程序Auo_move_down产生和修改)
                Lcall Load_dropping_block                                          ;输入参数Current_block_no
                Lcall Create_shape_no                                                  ;输出参数Next_block_no
                Lcall Display_the_next_block                                  ;输入参数Next_block_no
                Lcall Set_boundary
Loop_dropping_block:
                Lcall Copy_background
                Lcall Cover_background
                Lcall Display_by_bit
                Lcall Recover_background
Loop_by_keys:
                jb If_bottom,jump_out_loop_keys
                jb auto_down_flag,to_auto_move_down
                jb key_pressed_flag,to_execute_key_motion
                ajmp Loop_by_keys
to_execute_key_motion:
                Lcall move_by_key
                jb is_pause,to_pause_the_game
                jb is_escape,Enter_exit_game_menu
                ajmp Loop_dropping_block
to_auto_move_down:
                Lcall Judge_and_move_down
                clr auto_down_flag
                ajmp Loop_dropping_block
jump_out_loop_keys:
                Lcall Stick_to_background
                Lcall Judge_and_remove_full_lines
                Lcall Judge_if_game_over
                jb Game_over_flag,Is_game_over
                Lcall Move_down_remained_lines
                Lcall Display_by_bit
                Lcall Count_scores
                mov Location_Y,#0
                mov Location_X,#7
                mov Current_block_no,Next_block_no
                mov Current_shape,#0
                setb key_renewed_flag
                ajmp Loop_game
to_pause_the_game:
                Lcall Display_pause
to_loop_pause:
                jb key_pressed_flag,to_execute_pause_key
                ajmp to_loop_pause
to_execute_pause_key:
                Lcall resume_by_key
                jnb is_pause,to_quit_pause
                ajmp to_loop_pause
to_quit_pause:
                ajmp Loop_dropping_block
;退出游戏界面
Enter_exit_game_menu:
                clr is_escape
                mov Menu_options,#1
                Lcall Clean_game_area
Loop_exit_game_menu:
                Lcall Load_exit_game_menu
Loop_exit_game_key:
                jb key_pressed_flag,to_execute_exit_game_key
                ajmp Loop_exit_game_key
to_execute_exit_game_key:
                Lcall Move_menu_option_by_key
                Lcall Change_exit_menu_option
                jnb confirm_option,Loop_exit_game_menu
                jb is_record_1,to_execute_exit_option_1
                jb is_record_2,to_execute_exit_option_2
                jb is_record_3,to_execute_exit_option_3
to_execute_exit_option_1:
                clr is_record_1
                ajmp Enter_save_records_menu
to_execute_exit_option_2:
                clr is_record_2
                ajmp Enter_start_game_menu
to_execute_exit_option_3:
                clr is_record_3
                ajmp Loop_dropping_block
;Game Over画面
Is_game_over:
                Lcall Display_game_over
Loop_game_over:
                jb key_pressed_flag,to_execute_escape_key_motion
                ajmp Loop_game_over
to_execute_escape_key_motion:
                Lcall Escape_by_key
                jnb is_escape, Loop_game_over
                clr is_escape
                ajmp Enter_start_game_menu
;进入保存记录界面
Enter_save_records_menu:
                clr is_escape
                mov Menu_options,#1
                Lcall Clean_game_area
Loop_save_records_menu:
                Lcall Display_records_menu
                Lcall BCD_preload_scores
                Lcall Display_preload_scores
Loop_save_record_key:
                jb key_pressed_flag,to_execute_save_key
                ajmp Loop_save_record_key
to_execute_save_key:
                Lcall Move_menu_option_by_key
                Lcall Change_record_option
                jnb confirm_option,Loop_save_records_menu
                jnb is_record_5,to_save_data_and_restart
                clr is_record_5
                ajmp Enter_exit_game_menu
to_save_data_and_restart:
                Lcall Save_record
                ajmp Enter_start_game_menu
to_set_time:
                mov Menu_options,#1
                Lcall Clean_game_area
                Lcall Get_time_from_DS1302
Loop_set_time_key:
                Lcall Display_time
                Lcall Display_the_ok_button
                jb key_pressed_flag,to_execute_time_key
                ajmp Loop_set_time_key
to_execute_time_key:
                jnb confirm_option,to_execute_set_time
                jnb is_record_6,to_execute_set_time
                Lcall Enable_write_to_DS1302
                Lcall Write_confirmed_data_to_DS1302
                Lcall Disable_write_to_DS1302
                clr confirm_option
                Ljmp Enter_start_game_menu
to_execute_set_time:
                Lcall Set_time_keys
                Lcall Change_time_option_by_key
                Lcall Change_time_by_key
                Lcall Set_time_by_option
                Ljmp Loop_set_time_key
;====================================================================================================================================






;+++++++++++++++++++++
;延时毫秒,毫秒数由msn设定
;11.0592M晶振
Delay_msn:       
                push ACC
                push PSW
                push 05H
                push 06H
;---------------------
D1:
                mov R5,#4
D2:
                mov        R6,#113
D3:
                djnz R6, D3
                djnz R5,D2
                djnz msn,D1
;---------------------
                pop 06H
                pop 05H
                pop PSW
                pop ACC
                ret
;+++++++++++++++++++++


;====================================================================================================================================
;+++++++++++++++++++++
;定时器0,周期检测按键
Timer_0:
                push ACC
                push PSW
;---------------------
                Lcall Scan_keys
                inc auto_down_count
Loop_for_adjust_time:
                mov A,#10
                clr C
                cjne A,auto_down_count,quit_timer_0
                clr C
                mov auto_down_count,#0
                djnz auto_down_count_2,to_blink_count
                setb auto_down_flag
                mov A,#10
                subb A,auto_down_speed
                mov auto_down_count_2,A
to_blink_count:
                djnz Blink_count,quit_timer_0
                cpl if_blink
                mov Blink_count,#6
quit_timer_0:
                clr C
                mov TH0,#0DBH
                mov TL0,#0FFH
;---------------------
                pop PSW
                pop ACC
                reti
;+++++++++++++++++++++





;====================================================================================================================================
END

51hei.png
全部程序51hei下载地址:
asm文件.rar (24.84 KB, 下载次数: 14)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:944211 发表于 2021-6-24 19:47 | 显示全部楼层
这个看着不错,还是可以运用于硬件也就是开发板上的
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表