资源描述
目录
1设计任务和内容 1
1.1设计任务 1
1.2 功能要求说明 1
1.3 设计课题总体方案介绍及工作原理说明 2
1.3.1 工作原理 2
1.3.2 总体方案介绍 2
2硬件设计 4
2.1 设计课题硬件系统各模块功能简要介绍 4
2.1.1晶振电路 4
2.1.2 显示及显示驱动电路 4
2.1.3 键盘控制电路 5
2.1.4 复位电路 5
2.1.5 指示灯控制电路 6
2.2 电路原理图 7
2.3 电路PCB图 7
2.4 元器件布局图 7
2.5 元器件清单图 7
3、设计课题软件系统的设计 8
3.1 单片机资源的使用情况 8
3.2 软件系统各模块功能简要介绍 8
3.3 软件系统程序流程框图 8
3.4 程序清单 11
4 设计总结 13
4.1 使用说明 13
4.2 仿真结果 13
4.3 误差分析 15
4.4 设计体会 15
4.5 教学建议 16
参考文献 17
附 录 18
附录一 电路原理图 18
附录二 PCB图 19
附录三 元器件布局图 20
附录四 元器件清单 21
附录五 程序清单 22
1设计任务和内容
1.1设计任务
设计一个具有特定功能的十字路口交通灯。该交通灯上电或按键复位后能自动显示系统提示符“P.”, 进入准备工作状态。按开始键则开始工作,按结束键则返回“P.”状态。要求甲车道和乙车道两条交叉道路上的车辆交替运行,甲车道为主车道,每次通车时间为60秒,乙车道为次车道,每次通车时间为30秒,要求黄灯亮3秒,并且1秒闪烁一次。有应急车辆出现时,红灯全亮,应急车辆通车时间10秒,同时禁止其他车辆通过。
1.2 功能要求说明
利用单片机完成交通信号灯控制器的设计,该交通信号灯控制器由一条主干道和一条支干道汇合成十字路口,在每个入口处设置红、绿、黄三色信号灯,红灯亮禁止通行,绿灯亮允许通行,黄灯亮则给行驶中的车辆有时间停在禁行线外。用红、绿、黄发光二极管作信号灯。如图下图所示。设东西向为主干道,南北为支干道。
(1)当交通灯上电或按键复位后能自动显示系统提示符“P.”,进入准备工作状态。
(2)干道亮绿灯时,支干道亮红灯;支干道亮绿灯时,主干道亮红灯。
(3)灯亮到红灯亮的转换过程中,要亮3秒黄灯作为过渡。黄灯亮时,原红灯按1Hz的频率闪烁。
(4)应急车辆出现时,红灯全亮,应急车辆通车时间10秒,同时禁止其他车辆通过。
北
东
南
西
图1.1 交通灯示意图
1.3 设计课题总体方案介绍及工作原理说明
1.3.1 工作原理
甲、乙两干道交于一个十字路口,各干道有一组红、黄、绿三色的指示灯。红灯亮禁止通行,绿灯亮允许通行。黄灯闪亮提示人们注意绿、红灯的状态即将切换。指示灯燃亮的方案如表1。
表 1 交通灯状态转换图
计时
60s
3s
30s
3s
支道
红灯亮
红灯亮
绿灯亮
黄灯闪
亮
…..
主道
绿灯亮
黄灯闪
亮
红灯亮
红灯亮
…..
(1) 电源提供方面
采用独立的稳压电源,此方案的优点是稳定可靠,且有各种成熟电路可供使用。
(2) 显示方面
完全采用数码管显示,用来显示有限符号和数码字符。
(3)键盘输入方面
直接在I/O口线上接按键开关,因为设计时精简和优化了电路,所以剩余的口资源还比较多。我们共用到了4个按键,分别为:K1、K2、K3、K4。
1.3.2 总体方案介绍
该交通灯电路由单片机AT89S52、键盘接口电路、显示接口电路、发光二极管控制电路、时钟电路和复位电路构成,原理框图如图1.2所示。
图1.2 系统总体框图
单片机可选用AT89S52,它与8051系列单片机全兼容,但其内部带有4KB的FLASH ROM,设计时无需外接程序存储器,为设计和调试带来极大的方便。南北向和东西向各采用2个数码管计时,同时需要对该方向的指示灯的点亮时间进行倒计时。键盘系统可以根据系统的需要设置不同的键的个数,可以选择线式
键盘。
2硬件设计
2.1 设计课题硬件系统各模块功能简要介绍
2.1.1晶振电路
时钟电路用来产生单片机工作所需要的时钟信号,单片机本身就是一个复杂的同步时序电路,为了保证同步工作方式的实现,电路应在唯一的时钟信号控制下严格地按时序进行工作。通过在芯片的外部XTAL1和XTAL2两个引脚跨接晶体振荡器和微调电容,形成反馈电路,就构成了一个稳定的自激振荡电路。时钟电路为单片机产生时钟脉冲序列,本设计中采用的晶振频率为12MHz,电容为33pF。
图2.1.单片机系统的复位电路
2.1.2 显示及显示驱动电路
在本次课程设计中,为了使硬件电路更简单化,为了节省口线,我们采用的是八位一体共阳数码管,显示原理跟单个LED的显示原理完全相同, 由于七段数码显示器在显示字形代码时需要有足够的功率,所以需在显示器上加显示驱动,本设计的显示驱动是采用NPN三极管作为驱动,并且,无论是位控线上还是段控线上都串接一个电阻,以提高其输出功率,在这里采用470欧母电阻。显示及驱动电路图如图2.2。
图2.2.单片机系统的复位电路
2.1.3 键盘控制电路
键盘是最常用的输入设备,是实现人机对话的纽带。按其结构形式可分为非编码键盘和编码键盘。
编码键盘采用硬件方法产生键码。每按下一个键,键盘能自动生成键盘代码,键数较多,且具有去抖动功能。这种键盘使用方便,但硬件较复杂。非编码键盘仅提供按键开关工作状态,其键码由软件确定,这种键盘键数较少,硬件简单,广泛应用于各种单片机应用系统,在单片机控制电路中,可把单片机使用的键盘分为独立式和矩阵式两种。独立式实际上就是一组独立的按键,这些按键可直接与单片机的I/O口连接,即每个按键独占一条口线,这种接法简单。矩阵式键盘也称行列式键盘,因为键的数目较多,所以键按行列组成矩阵。本设计中键盘数目较少,且为安装方便,因此在本设计中采用独立式接法。如图2.3所示。
图2.3独立式按键
2.1.4复位电路
复位电路用于产生复位信号,通过RST引脚送入单片机,复位是单片机的初始操作,其主要功能是:为一些专用寄存器设置初始状态、程序状态字PSW清0、程序计数器PC被赋值为0000H等,除了进入系统的正常初始化之外,当由于程序运行出错或操作错误使系统处于死锁状态时,为摆脱困境,也需安装复位键以重新启动。RST引脚是复位信号的输入端,复位信号是高电平有效,完成复位操作共需要24个状态周期,复位结束后,单片机从地址0000H单元开始执行程序,SP为07H,其它寄存器大多数被置为00H,本设计使用频率为12MHz的晶振,所以复位信号持续时间应超过2μs才能完成复位操作。复位电路分为上电复位、按键复位、按键脉冲复位三种,本次课程设计采用的是按键复位,接线图如图2.4。
图2.4.单片机系统的复位电路
2.1.5 指示灯控制电路
本次课程设计采用P1口控制二极管的发光情况,口线送低电平有效,具体设计如下:P1.2控制东西方向的绿灯,P1.3口控制东西方向的黄灯,P1.4控制东西方向的红灯,P1.5控制南北方向的红灯,P1.6控制南北方向的黄灯,P1.7控制南北方向的绿灯。如图2.5所示。
图2.5指示灯控制电路
2.2 电路原理图
电路原理图见附录一所示。
2.3 电路PCB图
PCB图见附录二所示。
2.4 元器件布局图
元器件布局图见附录三所示。
2.5 元器件清单图
元器件清单见附录四所示。
3、设计课题软件系统的设计
3.1 单片机资源的使用情况
l P3口为二极管的控制端
l P0口用作地址/数据总线
l P2口用作数据总线
l P1.0、P1.1、P1.2、P1.3口线作为键盘输入端
l 采用了INTO外部中断
既在AT89S52的P0口用来接八个发光二极管的阳极,控制其亮与灭,P0口和P2口外接由8个LED数码管(LED1、LED0)构成的显示器,用P2口作LED的段码输出口(P2.0~P2.7对应于LED的a~dp),P0口作LED的位控输出线(P0.1、P0.0分别对应于LED1、LED0),其中在P1的串行口外接2个三极管作为显示驱动,显示为2个数码管(LED0~LED1)进行动态显示。P1口外接三个个按键K1、K2、K3、K4(分别对应于P1.0、P1.1、P1.2、P1.3口)用于调整显示接口电路。
3.2 软件系统各模块功能简要介绍
主程序模块的主要任务是程序的初始化显示“P.”,当没任何键按下时,显示模块将一直不变,交通灯全部是熄灭的,当K1键按下并松开后开始倒计时,
其中在时间显示的过程中判断是否有键按下,当再次按下K1时,显示将重新开始倒计时,如果是K3按下,将显示“P.”,并且发光二极管全部熄灭,如果是K2按下,数码管将开始十秒倒计时,并且东西南北全部亮起红灯。
显示模块包括送缓冲区模块,送显示等,通过这些模块完成了显示的功能,并能按照我们所熟悉的时钟时间进行显示。
3.3 软件系统程序流程框图
根据设计要求,程序框图如图1所示。由C语言完成。软件设计可以分为以下几个功能模块:
主程序:初始化及调用控制灯的显示程序,主程序的流程图如图3.1所示。
显示程序模块:完成交通灯的秒数显示,显示程序流程图如图3.2所示。
按键判断模块:完成按键判断并还回键值,按键判断程序流程图如图3.3所示。
定时器模块:完成交通灯秒数的的定时,定时器程序流程图如图3.4所示。
交通灯模块:完成交通灯的状态转换,交通灯程序流程图如图3.5所示
图3.1 主程序流程图
图3.2 显示程序流程图
图3.3 判断按键程序流程图
图3.4 定时器中断程序流程图
图3.5 交通灯状态转换流程图
3.4 程序清单
程序清单详见附录五
4 设计总结
4.1 使用说明
本实验主要是利用单片机AT89S52、数码管和发光二极管组成,整个电路结构比较简单,它能实现以下几个功能:
l 时间的显示。
l 红黄绿灯的发光与熄灭。
具体操作说明如下: 当交通灯上电或按键复位后能自动显示系统提示符“P.”,进入准备工作状态。当按下启动按钮K1并释放后,数码管显示将会从“60始倒计时,每隔一秒减1,此时南北方向开始一直亮绿灯,东西方向一直亮红灯,直到显示为“00”时,数码管将会从“03开始倒计时,每隔一秒减1,此时南北方向没隔一秒黄灯就闪烁一次,东西方向亮一直红灯,直到显示为“00”时,数码管将会从“30始倒计时,此时南北方向一直亮红灯,东西方向一直亮绿灯,直到显示为“00”时,数码管又将从“03开始倒计时,此时南北方向一直亮红灯,东西方向每隔一秒黄灯就闪烁一次;当没有其他键按下时,交通灯将这样一直循环下去。当按下结束键K3并释放后,数码管将显示“P.”,东西南北方向无灯亮,当有其它键按下时,就退出,去执行该键的键功能。当按下紧急键K2并释放后,数码管将显示“10”,并且每隔一秒就减1,东西南北方向全部红灯亮,当没亮到显示“00”就有其它键按下时,就退出,执行该键的键功能,当显示到“00”时,就会自动退出中断继续完成主程序。
4.2 仿真结果
当交通灯上电复位后,数码管显示“P.”,仿真结果如图4.1所示;当按下开始键K1后,南北方向就开始亮绿灯,东西方向开始亮红灯,显示器并开始从60s倒计时,仿真结果如图4.2所示;当按下紧急键K3后,南北方向和东西方向均亮红灯,显示器并开始从10s倒计时,其仿真结果如图4.3所示;
图4.1 上电显示
图4.2 按下开始键后的显示(上)
图4.2 按下开始键后的显示(下)
图4.3 按下紧急键后的显示
4.3 误差分析
本次课程设计的误差就在于显示时间,我采用的是调用延时程序来让显示器上数字共显示一秒钟,而循环一次的时间并不仅仅只是2次调用延时程序的时间,其间CPU还执行其它指令,例如说将缓存区的内容送给累加器A、查表指令、将段控码送给P2口等等,因为它们都是微秒级的,而延时程序是毫秒级的,因此在计算的过程中就可以省略了,每次循环除两次调用延时程序外,所用时间为15微秒,一秒钟共循环了60次,此在显示器上只需要显示1秒数字,事实上多显示了900微秒,误差率=0.9%
4.4 设计体会
经过一个多星期的时间,终于完成了这次的课程设计,在这期间,我觉得这次课程设计的难点就在函数的调用以及在函数调用中跳出。程序编了很多遍,最后还是没有成功,最后勉强成功,但还有一点小问题。我觉得这次课程设计中的第二个难点就是:显示程序。送的数到显示器,然后调用延时程序(用的是1ms的延时),因为数的显示要用人感觉到需要几百毫秒这,而我用得延时程序只有1ms,所以我用了一个循环显示程序,让它循环显示80次即可,不能用在较正式的场合。
关于PCB制作,我认真查阅资料,在上学期理论学习的基础上,经过几个星期的努力,又下了一次苦功夫,算是明白了制作一个系统的过程,也让我体会到要成功的设计出某个东西,光靠单一的知识是不够的,必须要系统的知识,对于这次的实物,我们采用的双面板制作,但是我是做了两次才成功的,第一次的问题主要是线设置的比较细,容易断掉,排列的比较紧,给人的感觉就是不美观,当我第二次再画PCB时,我就特意注意了这些细节,重新排了一下版,调整了元器件之间的距离,并加大了线的宽度,加大了焊孔的内外直径。但又出现了新的一些问题,线接错了,最后经过一天的修改终于弄好了
总结这次实习,在理论课上的学到的知识在这一周充分的和实践结合了起来,发现了学习中遗漏的知识点,对于已经有所了解的知识有了更进一步认识。
4.5教学建议
对于这学期的单片机教学,我个人认为总体上教的比较成功的。老师上课讲得比较好。也比较负责。如果要说改进的话,我觉的这本教材有一点薄,上面的程序不是很多,比如那上面没有独立式按键的讲解以及程序。那上面没有C的讲解,虽然又发了另一本书,但是比较厚,很难看,我觉的选一本既有汇编又有C的比较好。还有一点我觉的书上还有一章没有讲(不过在这读书基本上没有那个老师把书讲完的)要是能讲完就好了。
参考文献
[1] 李广弟,朱月秀.单片机基础[M].北京:北京航空航天大学出版社,
2007.
[2] 李光飞.单片机课程设计实例指导[M].北京:北京航空航天大学出版社,2004.
[3] 李东生,张勇,许四毛.protel99s电路设计与应用[M].北京:电子工业出版社,2004.
[4] 张红润,马平安,张亚凡.单片机原理及应用[M].北京:科学出版社,2002.
附 录
附录一 电路原理图
附录二 PCB顶层图
PCB底层图
附录三 元器件布局图
附录四 元器件清单图
元器件及材料名称
规格
数目
备注
AT89S52加底座
40P
1
四位一体共阳数码管加底座
40P
2
晶振
12MHz
1
发光二极管
9
单排插
40脚
1
三极管
9012
9
蜂鸣器
1
小按键
9
下载口座子
十芯
1
六脚按键开关
1
Usb电源线加接口
1
电阻
200
1
电阻
1K
3
电阻
470
24
电解电容
22uf
1
瓷片电容
33pf
2
排阻
10k
2
短路冒
2
杜邦线8P
1
PCB板子
1
元器件及材料清单
附录五
程序清单
本程序的相关设定:
显示器的设定:P1.0—P1.1制显示器的个位和十位的位选码P0.0——P0.7控制显示器的段选码
按键的设定: P1.0——P1. 4控制交通灯的开启准备,返回准备,紧急事件状态
/**************************************************************** *
*第一个状态:主干道、支干道均亮红灯10S *
*第二个状态:主干道亮绿灯60S、支干道亮红灯 *
*第三个状态:主干道绿灯闪3次转亮黄灯、支干道亮红灯3S *
*第四个状态:主干道亮红灯、支干道亮绿灯30S *
*第五个状态:主干道亮红灯、支干道绿灯闪3次转亮黄灯3S *
*返回到第二个状态 *
* *
***************************************************************/
#include<reg51.h>//头文件
#include<intrins.h>//头文件
#define uchar unsigned char//宏定义
#define uint unsigned int//宏定义
sbit RED_ZHU = P3^0;
sbit YELLOW_ZHU = P3^1;
sbit GREEN_ZHU = P3^2;
sbit RED_ZHI = P3^3;
sbit YELLOW_ZHI = P3^4;
sbit GREEN_ZHI = P3^5;
sbit p3_0=P3^0;
sbit p3_1=P3^1;
sbit p3_7=P3^7;
uint aa, bai,shi,ge,bb; //定义变量
/*数码管显示0-9*/
uint code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x0C,0xbf};
//电子0903——13显示
uint data table1[]={0,0,9,0,3,11,1,3};
/*子函数声明*/
void delay(uint z);
void delay0(uint z);
//void init(uint a);
void display(uint shi,uint ge);
void disp();
void xtimer0();
void init1();
void init2();
void init3();
void init4();
void init5();
uchar keychuli();
uchar key();
/*********************************************************
主函数
*********************************************************/
void main()
{ uchar m,n;
uchar k,b;
P0=0XFF;
P1=0xFF;
P2=0xFF;
EA=1;//打开外部中断
while(1)
{ k=key();
switch(k)
{ case 0x00:
while(1)
{
display(10,10);
b=P1;
if(b!=0xff)
break;
case 0x01: while(1)
{ if(P1!=0xff)
{ break;
}
Loop: init2();//第2个状态
init3(); //第3个状态
init4(); //第4个状态
init5();//第5个状态
} break;
case 0x02:
init1();
goto Loop;
break;
while(1)
{
display(10,10);
b=P1;
if(b!=0xff)
break;
}
break;
case 0x04:
while(1)
{ uchar i=80;
b=P1;
if(b!=0xff)
break;
do{disp();}while(i--) ;
m=table1[0];
for(n=0;n<7;n++)
{table1[n]=table1[n+1];
}
table1[7]=m;
} break;
case 0x08: while(1)
{ uchar i=80;
b=P1;
if(b!=0xff)
break;
do{disp();}while(i--) ;
m=table1[0];
for(n=0;n<7;n++)
{table1[n]=table1[n+1];
}
table1[7]=m;
} break;
}
}
}
void init1()//第一个状态:主干道、支干道均亮红灯10S
{
uint temp;
temp=11;//变量赋初值
TMOD=0x01;//定时器0工作于方式1
TH0=0x4c;
TL0=0x00;//定时器赋初值
EA=1;//开外部中断
ET0=1;//开定时中断
TR0=1;//开定时器0
while(1)
{
RED_ZHU=0; //第一个状态主干道、支干道均亮红灯10S
RED_ZHI=0;
GREEN_ZHU=1;
GREEN_ZHI=1;
YELLOW_ZHU=1;
YELLOW_ZHI=1;
if(aa==10)//定时20*50MS=1S
{
aa=0;//定时完成一次后清0
temp--;//变量自增
//delay(10);
if(temp==1)//定时100S
{
temp=11;//变量清0
break;
}
shi=temp/10;//显示十位
ge=temp%10;//显示个位
}
display(shi,ge);
if(P1!=0xff)
{ break;
}
}
}
void init2()//第二个状态:主干道亮绿灯60S、支干道亮红灯
{
uint temp;
temp=61;//变量赋初值
TMOD=0x01;//定时器0工作于方式1
TH0=0x4c;
TL0=0x00;//定时器赋初值
EA=1;//开外部中断
ET0=1;//开定时中断
TR0=1;//开定时器0
while(1)
{
RED_ZHU=1;
RED_ZHI=0;
GREEN_ZHU=0;
GREEN_ZHI=1;
YELLOW_ZHU=1;//第二个状态:主干道亮绿灯60S、支干道亮红灯
YELLOW_ZHI=1;
if(aa==20)//定时20*50MS=1S
{
aa=0;//定时完成一次后清0
temp--;//变量自增
if(temp==1)//定时100S
{
temp=61;//变量清0
break;
}
shi=temp/10;//显示十位
ge=temp%10;//显示个位
}
display(shi,ge);
if(P1!=0xff)
{ break;
}
}
}
void init3() //第三个状态:主干道绿灯闪3次转亮黄灯、支干道亮红灯3S
{
uint temp;
temp=7;//变量赋初值
TMOD=0x01;//定时器0工作于方式1
TH0=0x4c;
TL0=0x00;//定时器赋初值
EA=1;//开外部中断
ET0=1;//开定时中断
TR0=1;//开定时器0
while(1)
{
RED_ZHI=0;
GREEN_ZHU=1;
YELLOW_ZHU=0;
//YELLOW_ZHU=~YELLOW_ZHU;
if(aa==10)//定时20*50MS=1S
{
aa=0;//定时完成一次后清0
temp--;//变量自增
YELLOW_ZHU=~YELLOW_ZHU;
//delay(1);
if(temp==1)//定时100S
{
temp=4;//变量清0
break;
}
shi=temp/10/2;//显示十位
ge=temp%10/2;//显示个位
}
display(shi,ge);
if(P1!=0xff)
{ break;
}
}
}
void init4()//第四个状态:主干道亮红灯、支干道亮绿灯30S
{
uint temp;
temp=31;//变量赋初值
TMOD=0x01;//定时器0工作于方式1
TH0=0x4c;
TL0=0x00;//定时器赋初值
EA=1;//开外部中断
ET0=1;//开定时中断
TR0=1;//开定时器0
while(1)
{
RED_ZHU=0;
RED_ZHI=1;
YELLOW_ZHU=1;//第一个状态主干道、支干道均亮红灯5S
GREEN_ZHI=0;
if(aa==20)//定时20*50MS=1S
{
aa=0;//定时完成一次后清0
temp--;//变量自增
if(temp==1)//定时100S
{
temp=31;//变量清0
break;
}
shi=temp/10;//显示十位
ge=temp%10;//显示个位
}
display(shi,ge);
if(P1!=0xff)
{ break;
}
}
}
void init5()//第五个状态:主干道亮红灯、支干道绿灯闪3次转亮黄灯3S
{
uint temp;
temp=7;//变量赋初值
TMOD=0x01;//定时器0工作于方式1
TH0=0x4c;
TL0=0x00;//定时器赋初值
EA=1;//开外部中断
ET0=1;//开定时中断
TR0=1;//开定时器0
while(1)
{
RED_ZHI=1;
RED_ZHU=0;
GREEN_ZHU=1;
GREEN_ZHI=1;
YELLOW_ZHI=0;
//YELLOW_ZHI=~YELLOW_ZHI;
if(aa==10)//定时20*50MS=1S
{
aa=0;//定时完成一次后清0
temp--;//变量自增
YELLOW_ZHI=~YELLOW_ZHI;
if(temp==1)//定时100S
{
temp=4;//变量清0
break;
}
shi=temp/10/2;//显示十位
ge=temp%10/2;//显示个位
}
display(shi,ge);
if(P1!=0xff)
{ break;
}
}
}
/*显示子函数*/
void display(uint shi,uint ge)
{
P2=0x01;
P0=table[shi];//显示十位
delay0(5);
P2=0x02;
P0=table[ge];//显示个位
delay0(5);
}
void disp()
{
P2=0x01;
P0=table[table1[0]];delay0(1);
P2=0x02;
P0=table[table1[1]];delay0(1);
P2=0x04;
P0=table[table1[2]];delay0(1);
P2=0x08;
P0=table[table1[3]];delay0(1);
P2=0x10;
P0=table[table1[4]];delay0(1);
P2=0x20;
P0=table[table1[5]];delay0(1);
P2=0x40;
P0=table[table1[6]];delay0(1);
P2=0x80;
P0=table[table1[7]];delay0(1);
}
/*定时中断子函数*/
void xtimer0() interrupt 1
{
TH0=0x4c;
TL0=0x00;
aa++;
}
/*延时子函数*/
void delay0(uint z)
{
uint i,j;
for(i=0;i<z;i++)
for(j=0;j<110;j++);
}
/*********************************************************
500ms延时函数
*********************************************************/
void delay(unsigned char j)
{
uchar k;
uint i;
for(;j>0;j--)
{
for(i=1250;i>0;i--)
{
for(k=180;k>0;k--);
}
}
}
uchar keychuli()
{
uchar k;
k=P1;
k=~k;
return(k);
}
uchar key()
{
uchar keyzhi,keyzhii;
keyzhi=keychuli();
if(keyzhi!=0)
{
delay0(5);
keyzhi=keychuli();
if(keyzhi!=0)
{
keyzhii=keyzhi;
while(keyzhi!=0)
{
delay0(5);
keyzhi=keychuli();
}
keyzhi=keyzhii;
}
}
return(keyzhi);
}
展开阅读全文