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