1、 接口技术课程设计报告 篮球赛计时记分牌 学院(系): 专业年级: 学生姓名: 学 号: 指导教师: 完成日期: 2013年7月05日 I 设计思路与方案 目录 1 设计目的与要求 - 1 - 1.1 设计目的 - 1 - 1.2 设计要求 - 1 - 2 系统硬件设计 - 1 - 2.1 总体设计方案 - 1 - 2.2 芯片选型与电路设计 - 2
2、 - 2.2.1 单片机的选型 - 2 - 2.2.2 74HC573介绍 - 2 - 2.3 各模块电路设计 - 5 - 2.3.1 复位和振荡电路的设计 - 5 - 2.3.2 键盘输入模块的设计 - 6 - 2.3.3 信息提示模块的设计 - 6 - 2.3 系统总体电路 - 6 - 3 软件系统设计 - 7 - 3.1 软件系统总体设计方案 - 7 - 3.2 系统各模块程序设计 - 8 - 3.2.1 主程序设计 - 8 - 3.2.2 按键检测子程序设计 - 9 - 3.2.3 数码管显示子程序设计 - 10 - 4 系统调试
3、 - 11 - 4.1 Proteus仿真 - 11 - 4.2 实物调试 - 12 - 5 总结 - 13 - 5.1本系统存在的问题及经验总结 - 13 - 5.2心得体会 - 14 - 参考文献 - 14 - 附录I 源程序清单 - 15 - - 31 - 设计目的与要求 1 设计目的与要求 1.1 设计目的 目前球场计时记分牌在传统操作模式下,采用记分员手动翻动记分牌记分,采用秒表手动计时,工作方式单一,且记分翻牌麻烦,计时不准确。由于这些弊端,电子计时记分板逐渐兴起,近年大量应用于各种体育项目。 电子计时记分板根据篮球比赛的具体规则,
4、采用小型单片机为核心控制LED数码管对比赛比分以及计时进行显示,具有亮度高、可视性好、功耗小、使用寿命长等优点。 1.2 设计要求 设计题目:篮球赛电子计时记分牌 设计要求: (1)分别设计篮球比赛用的计时牌和记分牌; (2)上下半场各20分钟,要求能随时暂停,启动后继续计时,一场比赛结束后可清零重新开始比赛; (3)能按照篮球计分规则计分并显示。 (新增内容:①加上了减分按键,若存在按错键记录了错误比分,或由于误判比分无效等情况,可以通过减分按键将错误分数进行更正;②增加加时赛环节) 2 系统硬件设计 2.1 总体设计方案 篮球记分器的硬件电路分成核心处理模块
5、输入模块、信息提示、显示模块三部分构成,核心处理模块以AT89C52为核心,对输入模块信号进行分析处理,设置时钟中断,数据分析及发出显示、提示模块所需控制信号;键盘输入模块由3X4矩阵键盘构成,为用户提供交互,完成比赛的开始、暂停、记分、分数调整、置数计时等功能,为单片机处理提供数据基础;提示、显示模块由8个独立数码管、10个LED显示灯及一个蜂鸣器组成,完成对比赛分数的即时显示、比赛进度的提示及时间提示,为记分员提供下一步操作的参考。 系统整体结构如图1所示。 图1 系统整体结构图 2.2 芯片选型与电路设计 2.2.1 单片机的选型 主控模块以AT89C52单片机作为微控
6、制器。AT89C52单片机是一种低电压,高性能CMOS 8位单片机,片内含8k bytes的可反复擦写的Flash只读程序存储器和256 bytes的随机存取数据存储器(RAM),器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,片内置通用8位中央处理器和Flash存储单元,有3级程序存储器加密锁定,2~3个16位定时器/计数器,6~8级中断。由于它的这些优良特性,AT89C52单片机在电子行业中有着广泛的应用。采用AT89C52作为微控制器,可以很好地满足篮球记分器的系统要求。 图2 AT89C52 芯片 2.2.2 74HC573介绍 74H
7、C573包含八进制3态非反转透明锁存器,是一种高性能硅门CMOS器件, 各模块电路设计 输入是和标准 CMOS 输出兼容的;加上拉电阻,他们能和 LS/ALSTTL 输出兼容。当锁存使能端LE为高电平输入时,这些器件的锁存对于数据输出同步。当锁存使能变低时,符合建立时间和保持时间的数据会被锁存。74HC573在本系统中用于锁存由单片机P0数据复用口输出的位选及段选信号,对篮球时间、分数进行显示。其引脚图及功能图如图3所示。 图 3 74HC573引脚图及功能图 2.3 各模块电路设计 2.3.1 复位和振荡电路的设计 图4 AT89C52单片机最小系
8、统原理图 复位电路可以实现上电复位和按键复位两种复位方式:上电复位电路由电容串联电阻构成,由图并结合“电容电压不能突变”的性质,可以知道,当系统一上电,RST脚将会出现高电平,并且这个高电平持续的时间由电路的RC值来决定。典型的51单片机当RST脚的高电平持续两个机器周期以上就将复位,所以适当组合RC的取值就可以保证可靠的复位。按键复位电路则是通过按下RESET按键拉高RST引脚电平来实现的。 晶体振荡电路由一个12MHZ石英晶振和两个30pF的电容组成,用于产生稳定的时钟脉冲信号供单片机工作。 2.3.2 键盘输入模块的设计 用户通过键盘输入模块对系统进行控制。键盘采用3*4矩
9、阵式按键,其中按键“开始/暂停”控制计时计分的开始与暂停,按键“交换比分”用于在半场结束后交换双方记分牌上的分数,按键 “清除结果”用于在比赛结束后清除比分,其余的按键“+1分”、“+2分”、“+3分”、“-1分”用于给参加比赛的A、B两队加上相应的分数,或在错误记分后对比分进行调整。3*4矩阵按键的7条引线分别接至AT89C52的I/O口P3_0~P3_6(实际电路中接入4*4键盘,使用其三行四列作为本系统输入模块),在单片机内部采用行列扫描法检测到按键按下,从而执行相应的任务。 矩阵键盘的连接方式如图5所示。 图5 矩阵键盘的连接方式 2.3.3 信息提示模块的设计 信息提
10、示模块包含4个2位8段共阴极数码管(图6 仿真中、实际电路采用8个独立数码管)、8个LED指示灯(图7 实物包含2个记分牌中间间隔灯)和一个蜂鸣器(图8)。8个数码管分别用两位数字显示比赛分钟、秒钟和赛场上两个篮板的分数。由于单片机I/O口资源有限,为了不占用太多的接口,在此使用P0口向数码管同时送出数据(段选信号)和地址(位选信号),使用两个74HC573锁存器来分离数据和地址,而P2_0和P2_1口分别用于使能段选锁存器和位选锁存器。由于P0口的电流 信息显示模块设计 驱动能力有限,所以外接了排阻RP1,从而增强了对数码管的驱动能力。 图 6 数码管连接图 LED1、LED2
11、LED3分别指示比赛状态“开始”、“暂停”和“结束”;LED4用于“进球”指示,在比赛进行时按下任何一个加分按键,“进球”指示灯会闪一下;在上半场比赛结束后按下“EXCHANGE”键,“交换场地”指示灯LED5会亮,同时两个篮板的比分互换。“ERROR!”指示灯LED6用于指示用户的操作出错。6个LED采用共阳极连接方式,其阴极分别接单片机P1_0~P1_5口,当单片机某口输出低电平时,对应的LED亮。 图 7 LED仿真连接图 蜂鸣器接通过一个8550三级管对P1_6口输入信号放大后,接在三极管的集电极上。蜂鸣器主要用于提示比赛阶段,在半场结束或比赛结束后会发出提示音。具体连接如
12、图8所示。 图8 蜂鸣器连接图 2.3 系统总体电路 系统电路主要由一片AT89C52、两片74HC573、数码管、按键及LED显示灯构成。单片机通过烧入的执行文件,通过执行,从P0口输出LED显示的位选及段选信号,为节省I/O口资源、P0口输出信号输出给两片74HC573(锁存器),通过不同时刻选通两片锁存器,为数码管输出段选和位选信号。图中排阻用于增加驱动能力,使数码管显示更清晰;按键采用点3*4矩阵按键作为输入;外部时钟电路为单片机提供固定的时钟,使计时准确;复位电路用于单片机的复位,以及显示的复位;蜂鸣器通过三极管放大电路增加驱动能力,为比赛阶段进行提示;LED显示灯用
13、于提示比赛状态及阶段。总体电路图如图9所示。 图9 系统硬件总体原理图 软件系统设计 3 软件系统设计 3.1 软件系统总体设计方案 软件分为主程序和自定义的头文件构成,其中头文件包含按键扫描程key_scan()、按键响应函数key_respond()、数码管显示驱动函数display()、延时函数void delay_ ms(unsigned int xms)、初始化函数init()和蜂鸣器发声函数sounder()。软件开机复位初始化,只有当按下“开始”键,开始计时记分,整个过程分为上半场、下半场、加时赛三个阶段。比赛过程中,可以通过加分按键进行记分,为纠正错误记分,
14、可以通过“—1分”对分数进行调整;当上半场结束,单片机调用蜂鸣器提示程序进行提示,并使LED灯按规律显示;下半场开始时,比分交换,时间重置与上半场一样;下半场结束可对比分清零或进入加时赛。软件总流程图如图10所示。 图10 软件总流程图 3.2 系统各模块程序设计 3.2.1 主程序设计 在主程序文件main.c中包含两部分内容,分别是主函数和中断服务函数。 首先是主函数void main(),这是整个程序执行的入口,在这个函数里,首先调用init()进行单片机的初始化,然后进入大循环,反复调用key_respond()和display()两个函数不断扫描按键输入并输出显示数据
15、在中断服务函数void Timer() interrupt 1里,设置定时器T0以工作方式1计时,计时时长为50ms,计时器每溢出一次,变量intr_num自增一次,直至intr_num等于20,于是计时时长达到1s。在中断服务程序里,计时每达到1s,篮球计时牌上的秒钟数就自减1;秒钟减到0后,分钟自减1,然后秒钟从59开始继续自减。 主程序和中断服务程序流程如图11(a)、11(b)所示。 图11(a) 主程序流程图 图11(b) 中断服务程序流程图 按键检测子程序设计 3.2.2 按键检测子程序设计 按键检测子程序包括key_scan()和key_respond()
16、两个函数。在key_scan()中采用逐行扫描法判断是哪个键被按下,返回相应的键码,如果没有按键按下,则返回0。在key_respond()中调用key_scan()中的函数,根据得到的不同键码来执行不同操作,如果键码为0,则不执行任何操作。程序实现如下: uchar key = key_scan(); //获取键码 if (key!=0) //有键按下 { if (LED_run==ON) //游戏进行中 { if(key == 11) game_pause(); //游戏暂停 else if (key == 21)
17、 { time_grade_increase(_GRADE_A,1); //A队加1分 LED_SHOOT(); //LED闪烁 game_pause(); //游戏暂停 } ··· ··· 对矩阵键盘的检测,有两种常用方法:行扫描法和线反转法。在此采用行扫描法,其识别按键的过程介绍如下。 ① 判断键盘中有无键按下:将全部行线置低电平,然后检测列线的状态。只要有一列的电平为低,则表示键盘中有键被按下,而且闭合的键位于低电平线与4根行线相交叉的4个按键之中。若所有列线均为高电平,则键盘中无键按下。 ② 判断闭合键所在的位置:在确认有键按
18、下后,即可进入确定具体闭合键的过程。其方法是:依次将行线置为低电平,即在置某根行线为低电平时,其它线为高电平。在确定某根行线位置为低电平后,再逐行检测各列线的电平状态。若某列为低,则该列线与置为低电平的行线交叉处的按键就是闭合的按键。 按键检测程序流程图如图12所示。 图12 按键检测子程序流程图 3.2.3 数码管显示子程序设计 动态显示的特点是将所有位数码管的段选线并联在一起,由位选线控制是哪一位数码管有效,从而大大地简化了硬件电路。选亮数码管采用动态扫描显示。所谓动态扫描显示即轮流向各位数码管送出字形码和相应的位选,利用发光管的余辉和人眼视觉暂留作用,使人的感觉好像各位数码
19、管同时都在显示。 数码管动态显示的正确操作顺序为: (1)段选赋值 (2)位选赋值 (3)位选左移 (4)延时 (5)消影 以8只数码管同时显示数字“0”~“7”为例来说明: unsigned char code num_table[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07, 0x7F,0x6F}; //共阴极数码管字型码0~9 void delay_ms(unsigned int xms) { unsigned int i,j; for (i=xms;i>0;i--) for (j=110;j>0;
20、j--); } /*-------------------数码管显示------------------------*/ void display(void) 系统调试 { unsigned char i; while(1) { P2=0x7f; //P2=0111,1111 for (i=0;i<8;i++) { P0=num_table[i]; //线选信号 P2=P2<<1|P2>>7; //位选信号(先循环左移再赋给P2) delay_ms(5); P0=0x00; //先延时后消影! } }//
21、while 4 系统调试 4.1 Proteus仿真 系统仿真通过Proteus软件搭建电路原理图;通过Keil uVsion 4对系统软件进行编程调试,并进行修改优化,编译解决程序中错误及警告后,生成 .hex 文件。通过点击单片机烧入执行文件,对软件及整个系统进行仿真,检验电路原理是否正确。仿真效果图如图13所示。 图13 软件仿真效果图 4.2 实物调试 通过理论分析及Proteus电路仿真,对电路进行了论证,采用单片机开发板作为信号的输出控制,焊接了一个8位显示的数码管显示模块用于显示,其余如3*4按键部分采用开发板的4*4矩阵键盘;LED显示模块采用开发板上跑
22、马灯中6个;蜂鸣器使用开发板自带蜂鸣器。实物图如图14所示。 图14 实物图 将连线连好后,通过数据线及STC-ISP软件将生成的.hex文件烧入单片机,连接电源进行了实物仿真,通过按键,实现了篮球赛的时间显示、加分、分数调整、显示、蜂鸣器提示等功能。具体实物调试结果如图15所示。 实物调试、总结 图15 实物演示图 5 总结 5.1本系统存在的问题及经验总结 本系统设计由实际出发,根据篮球赛具体规则进行设计,实现了篮球赛基本的要求,但在实践中遇到了一些问题:1)软件编写过程中,当要引用别人功能代码时,需看清其代码编写的思想,明确其代码具体用途,在本次实验中,采用共
23、阴极数码管显示,由于未注意,导致有段时间仿真总是乱码。2)软件编写头文件两种方法总结:一是将自己写的功能函数全部写成子函数放在 .H 头文件中,在主程序中只需#include该 .H 文件即可;二是将功能函数全部写成单独的 .C文件,在.H文件中将所有函数进行声明,主程序只需在开头写上#include "···.h"即可。编写头文件可以省去重复写定义和声明的麻烦。3)在实物搭建过程中,要注意芯片引脚分布,不能根据仿真图中芯片引脚排列进行接线。4)本次设计未加入篮球赛中24秒,在设计后期想加入24秒,但单片机I/O有限,实验室又缺少2位的8端数码管,故放弃了该功能。 5.2心得体会 通过本次
24、单片机课程设计,对大二大三所学的知识进了温习和巩固,并将书本中理论运用到实际的电路中,同时也在其中学会了得到一个课题该按什么步骤去实现它,也学会和锻炼了在实践过程中如何去发现问题,解决问题的技巧和能力。在实际操作过程中,我们必须本着严谨的态度操作,因为接线不能马虎,接错一根就会失败而且很难发现,尤其是在接一些芯片引脚时,一旦错了要么花很多时间查找问题,要么重新连线。在本次实习中,通过多次失败,磨砺了我严谨的态度,让我懂得了耐心和细心在实际生活中的重要性。 本次实习,遇到了很多问题,发现自身存在在知识方面的欠缺和不足,意识到在今后学习中要时刻温习和学习知识,扩展知识面。通过此次课程设计,我学会
25、了发现问题解决问题的能力,同时也提高了我的实际动手能力,在老师的悉心教导和指导下,我最终基本完成了此次设计,在此谢谢老师。 参考文献 [1] 郭文川主编. 单片机原理与接口技术. 北京:中国农业出版社,2007. [2] 郭天祥.51单片机C语言教程.北京: 电子工业出版社,2009.1 [3] 童诗白.华成英.数字电子技术基础[M].北京:高等教育出版社,2005年第4版 [4] 郑学坚,周斌.微型计算机原理及应用[M].北京:清华大学出版社1995年第2版 [5] 阎石.数字电路技术基础.高等教育出版社,2002.:364-400 [6]徐惠民.单片微型计算机原理接口与应
26、用.北京:北京邮电大学出版社,1996.:26-39
[7]陈大钦主编.模拟电子技术基础.北京:高等教育出版社 ,2000:74-96
附录I 源程序清单
附录I 源程序清单
主程序:
/*======================================*/
//文件名:main.c
#include
27、e (1) { key_respond(); display(); } } /*------------计时器T0溢出中断服务程序------------*/ void Timer() interrupt 1 //T0中断 { TIMER_LOAD(); //T0装初值 intr_num++; if (intr_num == 20) { intr_num = 0; time_grade_increase(_SECOND,-1); } } /*-------------------------------------------
28、/
/*头文件======================================*/
//文件名:My_func.h
#ifndef MY_FUNC_H //防止重复定义
#define MY_FUNC_H
/*---------------头文件-----------------*/
#include
29、e _MINUTE 1 #define _SECOND 2 #define _GRADE_A 3 #define _GRADE_B 4 /*----------------位定义----------------*/ sbit LED_run= P1^0; sbit LED_pause= P1^1; sbit LED_end= P1^2; sbit LED_shoot= P1^3; sbit LED_exchg= P1^4; sbit LED_error= P1^5; sbit SOUNDER= P1^6; sbit LE_duan= P2^1; sbit LE_wei
30、 = P2^2; /*------------数据类型定义--------------*/ typedef unsigned char uchar; typedef unsigned int uint; /*----------------函数声明--------------*/ extern void init (void); extern void delay_ms(unsigned int xms); extern void sounder(void); extern uchar key_scan(void); extern void key_respond(v
31、oid); extern void game_start(void); extern void game_pause(void); extern void game_clear(void); extern void display(void); extern uchar time_grade_increase(uchar item,char inc_num); extern void time_grade_set(uchar item,uchar num); void LED_INIT() { LED_run=1; LED_pause=1; LED
32、end=0; LED_shoot=1; LED_exchg=1; LED_error=1; } void LED_RUN() { LED_run=0; LED_pause=1; LED_end=1; } void LED_PAUSE() { LED_run=1; LED_pause=0; LED_end=1; } void LED_END() { LED_run=1; LED_pause=1; LED_end=0; } void LED_EXCHG() { LED_exchg=!LE
33、D_exchg; } void LED_SHOOT() { LED_shoot=0; delay_ms(500); LED_shoot=1; } void LED_ERROR() {LED_error=0; delay_ms(500); LED_error=1; } void TIMER_START() { TR0=1; } //启动T0 void TIMER_PAUSE() { TR0=0; } //暂停T0 void TIMER_LOAD() { TH0=(65536-50000)/25
34、6; TL0=(65536-50000)%256; } void TIMER_INIT() { TMOD=0x01; TH0=(65536-50000)/256; TL0=(65536-50000)%256; EA=1; ET0=1; } char minute,second,grade_A,grade_B; uchar code num_table[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//共阴极数码管显示0~9的字型码 /*---------------
35、8只数码管显示数字---------------------*/ void display() { uchar display_table[8] = {0}; //display_table[8]存放8只数码管将要显示的字型码 uchar i,display_3_num,display_4_num,temp_wei; if (second<0) { second = 59; minute--; } //秒进位到分钟 if (minute==-1) //半场结束 { TIMER_PAUSE(); //暂停计时 if (
36、LED_exchg == OFF) //如果是上半场 { LED_PAUSE(); sounder(); //蜂鸣器提示 while (key_scan()!=12) { LED_EXCHG(); //灯闪烁 delay_ms(500); } //响应EXCHANGE键 LED_exchg = ON; time_grade_set(_MINUTE,20); //计时置数 time_grade_set(_SECOND,0); } else if (LED_exchg ==
37、ON) //如果是下半场 { time_grade_set(_MINUTE,0); //计时清零 time_grade_set(_SECOND,0); LED_END(); sounder(); //蜂鸣器提示 } } if (grade_A>99) { grade_A = 99; LED_ERROR(); } //比分超出显示范围 if (grade_B>99) { grade_B = 99; LED_ERROR(); } if (LED_exchg==ON)
38、{ display_3_num = grade_B; display_4_num = grade_A; } //下半场,比分交换 else if (LED_exchg==OFF) { display_3_num = grade_A; display_4_num = grade_B; } //上半场,比分不交换 display_table[0] = num_table[(uchar)(minute/10)]; //第1只数码管 display_table[1] = num_table[(uchar)(minute%10)]; /
39、/第2只数码管 display_table[2] = num_table[(uchar)(second/10)]; display_table[3] = num_table[(uchar)(second%10)]; display_table[4] = num_table[(uchar)(display_3_num/10)]; display_table[5] = num_table[(uchar)(display_3_num%10)]; display_table[6] = num_table[(uchar)(display_4_num/10)]; display
40、table[7] = num_table[(uchar)(display_4_num%10)];//第8只数码管 temp_wei=0xfe; //位选初值1111,1110 for (i=0;i<8;i++) { P0 = 0x00; //消影! LE_duan = 1; //打开段选锁存端 _nop_(); P0 = display_table[i]; //段选信号 _nop_(); LE_duan = 0; //关闭段选锁存端 P0 = 0xFF; //消影! LE_wei = 1; //打开
41、位选锁存端 P0 = temp_wei; //位选信号 LE_wei = 0; //关闭位选锁存端 temp_wei = temp_wei<<1|temp_wei>>7; //位选信号循环左移 delay_ms(1); } LE_wei = 1; P0 = 0xFF; LE_wei = 0; } /*-----------------增大指定显示项的数字-----------------*/ //显示项可以是_MINUTE、_SECOND、_GRADE_A、_GRADE_B。 uchar time_grade_increas
42、e(uchar item,char inc_num) { uchar temp; switch (item) { case _MINUTE: minute += inc_num; temp = minute; break; case _SECOND: second += inc_num; temp = second; break; case _GRADE_A: grade_A += inc_num; temp = grade_A; break; case _GRADE_B:
43、 grade_B += inc_num; temp = grade_B; break; default: break; } return temp; } /*-----------------给指定的显示项置数--------------------*/ //显示项可以是_MINUTE、_SECOND、_GRADE_A、_GRADE_B。 void time_grade_set(uchar item,uchar num) { switch (item) { case _MINUTE: minute = nu
44、m; break; case _SECOND: second = num; break; case _GRADE_A: grade_A = num; break; case _GRADE_B: grade_B = num; break; default: break; } } void key_respond() { uchar key = key_scan(); //获取键码 if (key!=0) //有键按下 { if (LED_run==ON)
45、//游戏进行中,响应除了EXCHANGE和CLEAR之外的按键 { if (key == 11) game_pause(); else if (key == 21) { time_grade_increase(_GRADE_A,1); LED_SHOOT(); game_pause(); } else if (key == 22) { time_grade_increase(_GRADE_A,2); LED_SHOOT(); game_paus
46、e(); } else if (key == 23) { time_grade_increase(_GRADE_A,3); LED_SHOOT(); game_pause(); } else if (key == 31) { time_grade_increase(_GRADE_B,1); LED_SHOOT(); game_pause(); } else if (key == 32) { time_grade_increase
47、GRADE_B,2); LED_SHOOT(); game_pause(); } else if (key == 33) { time_grade_increase(_GRADE_B,3); LED_SHOOT(); game_pause(); } else LED_ERROR(); } else if (LED_pause==ON) //游戏暂停,只响应START/PAUSE键(半场结束才响应EXCHANGE键) { if(key == 11)
48、 game_start(); else if (key == 21) { time_grade_increase(_GRADE_A,1); LED_SHOOT(); } else if (key == 24) { if(grade_A==0) { time_grade_increase(_GRADE_A,0); LED_ERROR(); } else { time_grade_increase(_GRADE_A,-1);
49、 LED_SHOOT(); game_pause(); } } else if (key == 31) { time_grade_increase(_GRADE_B,1); LED_SHOOT(); } else if (key == 34) { if(grade_B==0) { time_grade_increase(_GRADE_B,0); LED_ERROR(); } else {
50、 time_grade_increase(_GRADE_B,-1); LED_SHOOT(); game_pause(); } } else LED_ERROR(); } else if (LED_end==ON) //游戏结束,只响应START/PAUSE和CLEAR键 { if (key == 11) game_start(); else if (key == 13) game_clear(); else if (key==14)






