当前位置:文档之家› 单片机综合实验报告51电子时钟

单片机综合实验报告51电子时钟

一、实验内容:设计一个数字时钟,显示范围为00: 00: 00~23: 59: 59。

通过5个开关进行控制,其中开关K1用于切换时间设置(调节时钟)和时钟运行(正常运行)状态;开关 K2用于切换修改时、分、秒数值;开关K3用于使相应数值加1调节;开关K4用于减1调节;开关K5用于设定闹钟,闹钟同样可以设 定初值,并且设定好后到时间通过蜂鸣器发声作为闹铃。

选做增加项目:还可增加秒表功能(精确到0.01s )或年月日设定功能。

二、实验电路及功能说明按键键名 功能说明 K1切换键进入设定状态K2校时依次进入闹钟功能是否启用,闹钟时 ,分秒,年,月,日及时间时,分,秒的设置,直到退出 设置状态K3加1键调整是否起用闹钟和调节闹钟时 ,分,秒,年,月,日,时间的时,分,秒的数字三、实验程序流程图:1602显示器电路(不需接线)闹钟複攧时钟擾换单片机最小采绕电子音响电路四、实验结果分析定时程序设计:单片机的定时功能也是通过计数器的计数来实现的,此时的计数脉冲来自单片机的内部,即每个 机器周期产生一个计数脉冲,也就是每经过 1个机器周期的时间,计数器加1。

如果MCS-51采用的12MHz 晶体,则计数频率为 1MHz ,即每过1us 的时间计数器加1。

这样可以根据计数值计算出定时时 间,也可以根据定时时间的要求计算出计数器的初值。

MCS-51单片机的定时器/计数器具有4种工作方式,其控制字均在相应的特殊功能寄存器中,通过对特殊功能寄存器的编程,可以方便的选择定时器 计数器两种工作模式和 4 种工作方式。

定时器/计数器工作在方式 0时,为13位的计数器,由TLX (X=O 、1)的低5位和THX 的高8位所 构成。

TLX 低 5 位溢出则向 THX 进位, THX 计数溢出则置位 TCON 中的溢出标志位TFX.是--- ►调用校时子程序是调用定时子程序 -■是■调用复位子程序 L■初始化显示当定时器/计数器工作于方式1,为16 位的计数器。

本设计师单片机多功能定时器,所以MCS-51 内部的定时器/计数器被选定为定时器工作模式,计数输入信号是内部时钟脉冲,每个机器周期产生一个脉冲使计数器增1。

实时时钟实现的基本方法:这次设计通过对单片机的学习、应用,以AT89S51 芯片为核心,辅以必要的电路,设计了一个简易的电子时钟,它主要通过51 单片机综合仿真实验仪实现,通过1602 能够准确显示时间,调整时间,它的计时周期为24小时,从而到达学习、设计、开发软、硬件的能力。

主要实现功能为显示时间,时间校准调时(采用手动按键调时),闹铃功能(设置定时时间,到点后闹铃发出响声)。

通过键盘可以进行校时、定时。

闹铃功能使用I/O 口定时翻转电平驱动的无源蜂鸣器。

本文主要介绍了工作原理及调试实现。

四个按键K1、K2、K3、K4、一个蜂鸣器。

1602 显示时钟、跑表。

时钟的最小计时单位是秒,但使用定时器的方式1,最大的定时时间也只能达到131ms。

我们可把定时器的定时时间定为50ms。

这样,计数溢出20次即可得到时钟的最小计时单位:秒。

而计数20次可以用软件实现。

秒计时是采用中断方式进行溢出次数的累积,计满20次,即得到秒计时。

从秒到分,从分到时是通过软件累加并进行比较的方法来实现的。

要求每满 1 秒,则“秒”单元中的内容加 1 ;“秒”单元满60,则“分”单元中的内容加 1 ;“分”单元满60,则“时”单元中的内容加1;“时”单元满24,则将时、分、秒的内容全部清零。

实时时钟程序设计步骤:先对系统进行初始化,如:LCD1602 初始化, DS1302 初始化等,然后才能进入主显示模块, 即可在LCD1602 上看到相应的信息。

对于LCD1602 的初始化,主要是对开启显示屏,清屏,设置显示初始行等操作。

DS1302 的初始化主要是先开启写功能,然后写入一个初始值。

本系统采用的是LCD1602 液晶显示器,由于其是本身带有驱动模块的液晶屏,所以对于LCD1602 操作程序可分为开显示、设置显示初始行、写数据和清屏等部分。

LCD1602 的写命令程序和写数据程序分别以子程序的形式写在程序里,以便主程序中的调用。

( 1 )选择工作方式,计算初值;(2)采用中断方式进行溢出次数累计;(3)计时是通过累加和数值比较实现的;(4)时钟显示缓冲区:时钟时间在方位数码管上进行显示,为此在内部RAM 中要设置显示缓冲区,共 6 个地址单元。

显示缓冲区从左到右依次存放时、分、秒数值;(5)主程序:主要进行定时器/计数器的初始化编程,然后反复调用显示子程序的方法等待中断的到来;(6)中断服务程序:进行计时操作;(7)加 1 子程序:用于完成对时、分、秒的加操作,中断服务程序在秒、分、时加 1 时共有三种条调用加 1 子程序,包括三项内容:合字、加 1 并进行十进制调整、分字。

程序说明:按K1 按键进入设定状态按K2,依次进入闹钟功能是否启用,闹钟时,分秒,年,月,日及时间时,分,秒的设置,直到退出设置状态按K3,调整是否起用闹钟和调节闹钟时,分秒,年月,日,时间的时,分,秒的数字LCD 第二排中间显示小喇叭,表示启用闹钟功能,无则禁止闹钟功能(可在调整状态进行设置)正常状态,LCD 上排最前面显示自定义字符,LCD 下排最前面闪动"_"设置状态,LCD 上排最前面显示"P",下排最前面在设置闹钟时间时显示"alarm_",其它状态显示"time"年代变化2000--2099, 星期自动转换程序中有自定义字符写入在整个系统中,在单片机的30H 、31H 和32H 中存储当前时间的小时、分钟和秒。

由于要用数码管显示当前的时间,必须用到分字和合字,因此在33H 、34H、35H、36H、37H 和38H 中存储当前时间的时十位、时个位、分十位、分个位、秒十位和秒个位,方便显示。

本设计有由四个轻触按键组成的小键盘,这些按键可以任意改变当前的状态。

按功能移位键一次,表示当前要校对小时的十位;按第二次,表示当前校对的是小时的个位;按第三次,则表示校对的是分钟的十位;第四次,表示的校对的是分钟的个位。

按下数字“ +” 键和数字“ -”键可在当前校对的数字上相应加上 1 或者减去1。

本设计采用查表方式,在程序里预先存储两个表格,即日常作息时间表和考试时间表,可以通过手动按键来选择所要执行的时间表。

并且用红、绿发光二极管来区别当前所执行的时间表。

系统开机后,按功能移位键就可以调整当前的时间,整个系统操作简单,功能明确。

显示数据时,先把要显示的数据送到数据缓冲区SBUF 中,再从SBUF 中显示。

串行口缓冲寄存器SBUF 器是可直接寻址的专用寄存器。

在物理上,它对应着两个寄存器,一个发送寄存器,一个接收寄存器。

CPU 写SBUF ,就是修改发送寄存器;读SBUF ,就是读接收寄存器。

接收器是双缓冲的,以避免在接收下一帧数据之前,CPU 未能及时响应接收器的中断,没有把上一帧数据读走,而产生两帧数据重叠的问题。

对于发送器,为了保持最大的传输速率,一般不需要双缓冲,因为发送时CPU 是主动的,不会产生写重叠的问题。

五、心得体会在享受我们成果之时,懂得的重要性与高难度性,所以为期一周的单片机课程设计没有浪费,我们从中学到了很多知识.,也让我们对单片机有了更深一步的了解.虽然最后结果是出来了,可这与老师的精心指导是分不开的。

通过对这程序的制作,是我对单片机的基本知识的使用更加熟练,同时也增加了我对单片机的一些认识,在作业完成过程中通过和同学的交流,也增加了合作的技巧。

通过查阅资料也学到了一些课本上没有的东西,拓宽了自己的知识面,增加了学好单片机的信心。

这次实训虽然其中会有些错误和失败,但总的来说是受益匪浅,在运用中发现问题,解决问题,就是最大的收获。

专心做自己的事,是一种乐趣;互相交流,是大家一起进步的必要过程;上网查阅资料,是获得所需信息的有效途径。

我想,这些练习和经验都将是我以后最宝贵的财富!附录:实验主程序及注释#include <reg51.h>#include <intrins.h> unsigned char codedis_week[]={"SUN,MON,TUE,WED,THU,FRI,SAT"}Junsigned char codepara_month[13]={0,0,3,3,6,1,4,6,2,5,0,3,5};// 星期月参变数unsigned char data dis_buf1[16];//lcd 上排显示缓冲区unsigned char data dis_buf2[16];//lcd 下排显示缓冲区unsigned char data year,month,date,week;// 年、月、日、星期unsigned char data armhour,armmin,armsec;// 闹钟时、分、秒unsigned char data hour,min,sec,sec100; // 时、分、秒、百分之一秒void pro_timedate(); // 时间日期处理程序void pro_display(); // 显示处理程序void pro_key(); // 按键处理程序void time_alarm(); // 定时报警功能( 闹钟)unsigned char scan_key(); // 按键扫描程序unsigned char week_proc(); // 星期自动计算与显示函数bit leap_year(); // 判断是否为闰年void lcd_sef_chr(); //LCD 自定义字符程序void update_disbuf(unsigned char t1,unsigned char t2[],unsigned char dis_h,unsigned charunsigned char data flag,vkey,skey;// 设置状dis_m,unsigned char dis_s);态计数标志、按键先前值、按键当前值bit alarm; // 标识是否启用闹钟,1-- 启用,0-- 缓冲区函数关闭sbit rs = P2A0; //LCD 数据/命令选择端(H/L) // 延时程序sbit rw = P2A1; //LCD 读/ 写void delay(unsigned char ms)选择端(H/L) { while(ms--)sbit ep = P2A2; //LCD 使能{ unsigned char i;控制for(i = 0; i< 250;i++)sbit PRE = P3A3; // 调整键{(AN3) _nop_();sbit SET = P3A4; // 调整键一条_nop_() 指令为一个机器周期(AN4) _nop_();sbit SPK = P3A6; _nop_();void delayms(unsigned char ms); // 延时程序_nop_();bit lcd_busy(); // 测试LCD }忙碌状态程序}void lcd_wcmd(char cmd); // 写入指令}到LCD程序void lcd_wdat(char dat); // 写入数据到LCD程序//测试LCD忙碌状态void lcd_pos(char pos); //LCD 数据bit lcd_busy() // 更新显示// 执行void lcd_init(); //LCD 初始bit result; 指针位置程序{rw = 1;ep = 1;_n op_();_n op_();_n op_();_n op_();result =(bit)(PO&0x80); //LCD 的D0--D7 中,D7=1为忙碌,D7=0为空闲ep = 0;return result;}//写入指令到LCDvoid lcd_wcmd(char cmd){while(lcd_busy()); // 当lcd_busy 为 1 时,再次检测LCD忙碌状态,lcd-busy 为0时,开始写指令rs = 0;rw = 0;ep = 0;_n op_();_n op_();P0 = cmd;_n op_();_n op_();_n op_();_n op_();ep = 1;_n op_();_n op_();_n op_();_n op_();ep = 0;}//写入数据到LCDvoid lcd_wdat(char dat){while(lcd_busy()); // 当lcd_busy 为 1 时,再次检测LCD忙碌状态,lcd-busy 为0时,开始写数据rs = 1;rw = 0;ep = 0;P0 = dat;_n op_();_n op_();_n op_();_n op_();ep = 1;_n op_();_n op_();_n op_();_n op_();ep = 0;}//LCD数据指针位置程序void lcd_pos(char pos){lcd_wcmd(pos|0x80); // 数据指针=80+地址码(00H~27H,40H~67H)}//设定二个自定义字符,(注意:LCD1602中自定义字符的地址为0x00--0x07,即可定义8个字符)//这里我们设定把一个自定义字符放在0x00位置(000),另一个放在0x01位子(001)void lcd_sef_chr(){ //第一个自定义字符lcd_wcmd(0x40); 〃"01 000 000" 第1行地址(D7D6为地址设定命令形式D5D4D3为字符存放位置(0--7) ,D2D1DC为字符行地址(0--7))lcd_wdat(0x1f); //"XXX 11111" 第1行数据(D7D6D5为XXX表示为任意数(一般用000),D4D3D2D1D为字符行数据(1-点亮,0-熄灭)lcd_wcmd(0x41); 〃"01 000 001" 第2行地址lcd_wdat(0x11); //"XXX 10001" 第2行数据lcd_wcmd(0x42); //"01 000 010" 第3行地址Icd_wdat(0x15); //"XXX 10101" 第3行数据lcd_wcmd(0x43); //"01 000 011" 第4行地址lcd_wdat(0x11); //"XXX 10001" 第4行数据lcd_wcmd(0x44); //"01 000 100" 第5行地址lcd_wdat(0x1f); //"XXX 11111" 第5行数据数据lcd_wcmd(0x45); //"01 000 101" 第6行地址lcd_wdat(0x0a); //"XXX 01010" 第6行数据}lcd_wcmd(0x46); //"01 000 110" 第7行地址//LCD 初始化设定lcd_wdat(0x1f); //"XXX 11111" 第7行void lcd_init()数据{lcd_wcmd(0x47); //"01 000 111" 第8行lcd_wcmd(0x38); // 设置LCD为16X2显地址示,5X7点阵,八位数据借口lcd_wdat(0x00); //"XXX 00000" 第8行delay(1);数据lcd_wcmd(0x0c); //LCD 开显示及光标// 第二个自定义字符设置(光标不闪烁,不显示"-")lcd_wcmd(0x48); //"01 001 000" 第1行delay(1);地址lcd_wcmd(0x06); //LCD 显示光标移动lcd_wdat(0x01); //"XXX 00001" 第1行设置(光标地址指针加1,整屏显示不移动)数据delay(1);lcd_wcmd(0x49); //"01 001 001" 第2行lcd_wcmd(0x01); // 清除LCD 的显示内地址容lcd_wdat(0x1b); //"XXX 11011" 第2行delay(1);数据}lcd_wcmd(0x4a); //"01 001 010" 第3行地址// 闰年的计算lcd_wdat(0x1d); //"XXX 11101" 第3行bit leap_year()数据{bit leap;lcd_wcmd(0x4b); //"01 001 011" 第4行地址if((year%4==0&&year%100!=0)||year%400= lcd_wdat(0x19); //"XXX 11001" 第4行=0)// 闰年的条件数据leap=1;lcd_wcmd(0x4c); //"01 001 100" 第5行else地址leap=0;lcd_wdat(0x1d); //"XXX 11101" 第5行return leap;数据}lcd_wcmd(0x4d); //"01 001 101" 第6行地址// 星期的自动运算和处理unsigned char week_proc()lcd_wdat(0x1b); //"XXX 11011" 第6行数据{ unsigned char num_leap;lcd_wcmd(0x4e); //"01 001 110" 第7行unsigned char c;地址num_leap=year/4-year/100+year/400;// 自lcd_wdat(0x01); //"XXX 00001" 第7行00 年起到year 所经历的闰年数数据if( leap_year()&& month<=2 ) // 既lcd_wcmd(0x4f); //"01 001 111" 第8行是闰年且是 1 月和 2 月地址c=5;lcd_wdat(0x00); //"XXX 00000" 第8行elsec=6; dis_buf2[14]=dis_s/10+48;week=(year+para_month[month]+date+num_ dis_buf2[15]=dis_s%10+48;leap+c)%7;// 计算对应的星期return week; }}// 时间和日期处理程序// 更新显示缓冲区void pro_timedate()void update_disbuf(unsigned char t1,unsigned {char t2[],unsigned char dis_h,unsigned char sec++;dis_m,unsigned char dis_s) if(sec > 59){ dis_buf1[0]=t1; // {sec = 0;dis_buf1[1]=0x20; // 空格min++;dis_buf1[2]=50; //'2' if(min>59)dis_buf1[3]=48; //'0' {min=0;dis_buf1[4]=year/10+48; hour++;dis_buf1[5]=year%10+48; if(hour>23)dis_buf1[6]=0x2d; {hour=0;dis_buf1[7]=month/10+48; date++;dis_buf1[8]=month%10+48; ifdis_buf1[9]=0x2d; //'-' (month==1||month==3||month==5||month==7||mdis_buf1[10]=date/10+48; onth==8||month==10||month==12)dis_buf1[11]=date%10+48; if (date>31) dis_buf1[12]=0x20; {date=1;month++;} // 大月dis_buf1[13]=dis_week[4*week]; 31天dis_buf1[14]=dis_week[4*week+1]; ifdis_buf1[15]=dis_week[4*week+2]; (month==4||month==6||month==9||month==11)dis_buf2[0]=t2[0]; if (date>30) dis_buf2[1]=t2[1]; {date=1;month++;} // 小月dis_buf2[2]=t2[2]; 30 天dis_buf2[3]=t2[3]; if (month==2)dis_buf2[4]=t2[4]; {if( leap_year())dis_buf2[5]=t2[5]; // 闰年的条件dis_buf2[6]=t2[6]; // 空格{if (date>29) if (alarm) {date=1;month++;}} // 闰年 2 月为29 dis_buf2[7]=0x01; //alarm=1 ,天显示闹钟启用标致(第二个自定义字符)elseelse {if (date>28) dis_buf2[7]=0x20; //alarm=0 ,{date=1;month++;}} // 平年 2 月为28 不显示闹钟启用标致天dis_buf2[8]=dis_h/10+48; }dis_buf2[9]=dis_h%10+48; if (month>12) dis_buf2[10]=0x3a; //':' {month=1;year++;}dis_buf2[11]=dis_m/10+48; if (year>99) year=0;dis_buf2[12]=dis_m%10+48; }dis_buf2[13]=0x3a; }}week_proc();if (sec==armsec && min==armmin &&hour==armhour){if (alarm)TR1=1; // 闹钟启用时,报警时间到, 启动Timer1}}// 显示处理程序void pro_display(){ unsigned char i;lcd_pos(0x00);for (i=0;i<=15;i++){lcd_wdat(dis_buf1[i]);}lcd_pos(0x40);for (i=0;i<=15;i++){lcd_wdat(dis_buf2[i]);}}//Timer0 中断处理程序, 秒的产生void timer0() interrupt 1{TH0=0xD8;TL0=0xF0;sec100++;if(sec100 >= 100) //1 秒时间(100*10ms=1000ms=1s){sec100 = 0;pro_timedate();// 调用时间和日期处理程序}if (sec&0x01)//"__run__" 闪一秒,停一秒update_disbuf(0x00,"",hour,min,sec); //0x00 表示显示00 位置的自定义字符elseupdate_disbuf(0x00,"__run__",hour,min,sec)Jpro_display(); // 调用显示处理函数}// 按键扫描程序unsigned char scan_key(){skey=0x00;// 给变量vkey 置初值skey|=PRE;//读取PRE键的状态skey=skey<<1;//将PRE键的状态存于skey的B1位skey|=SET;//读取SET键的状态,并存于skey的B0 位return skey;II返回skey的键值(即PRE,SET的状态)}II 外部中断INT0 中断处理程序void int0() interrupt 0{TR0=0;II 禁止Timer0IE=0;II 禁止中断lcd_wcmd(0x0e);II 显示光标"_", 整个光标不闪烁alarm=1;update_disbuf(0x50,"alarm_",armhour,armmin,armsec); II 更新显示数据,0x50 表示要显示"P"pro_display();II 调用显示处理程序lcd_pos(0x47);II 使光标位于第一个调整项下flag=0;vkey=0x03; while(flagAOxOa) {skey =scan_key();II 扫描按键状态if (skeyWkey)// 若skey 与vkey 相同,跳出循环, 相异执行循环体{ delay(10);// 去按键抖动skey = scan_key();// 转回扫描按键状态if (skey A vkey)// 若skey 与vkey 相同,跳出循环, 相异执行循环体{ vkey=skey;// 将skey 的值付给vkey if (skey==0x01)//PRE 键按下{ flag++; // 调整标志位加 1光标置月调整位置case 6: lcd_pos(0x0b);break; // 光标置日调整位置case 7: lcd_pos(0x49);break; // 光标置时调整位置case 8: lcd_pos(0x4c);break; // 光标置分调整位置case 9: lcd_pos(0x4f);break; // 光标置秒调整位置switch (flag) // 将光标置于相应调整位置{case 1: lcd_pos(0x49);break; // 光标置小时报警设置位置case 2: lcd_pos(0x4c);break; // 光标置分钟报警设置位置case 3: lcd_pos(0x4f);break; // 光标置秒时报警设置位置case 4: update_disbuf(0x50,"time_",hour,min,sec);pro_display();lcd_pos(0x05);break; // 光标置年调整位置case 5: lcd_pos(0x08);break; //default:break;}}if (skey==0x02) //SET 键按下{ pro_key();// 转设置按键处理程序}}}}lcd_wcmd(0x0c);//设置LCD开显示及光标不闪烁,不显示II IIlcd_wcmd(0x01);// 清除LCD的显示内容IE=0x8f;//CPU 开中断,INT0,INT1,开中断TR0=1;//Timer0 启动}// 主程序,初始化及初值设定void main(){lcd_init(); // lcd_pos(0x47);break;初始化LCD // 光标回到原调lcd_sef_chr(); // 整位置写入自定义字符号case 1:armhour++;hour=0;min=0;sec=0; // if (armhour>23) armhour=0;开机时的时, 分, 秒显示armhour=0;armmin=0;armsec=0; // update_disbuf(0x50,"alarm_",armhour,ar开机时的时, 分, 秒报警初值mmin,armsec); // 更新显示数据year= 5; month=1;date=1; // pro_display();开机时的年, 月,日, 星期显示// 调用显示处理week_proc(); lcd_pos(0x49);break;alarm=1; // // 光标回到原调初始开机,启用闹钟整位置IE = 0x8f; case 2:armmin++;//CPU 开中断,INT0,INT1,Timer0,Timer1 开if (armmin>59) armmin=0;中断IP = 0x04; // update_disbuf(0x50,"alarm_",armhour,ar设置INT0 为中断最高优先级mmin,armsec);IT0=0;IT1=0; //片丄pro_display();外部INT0,INT1 设置为电平触发方式(注意,触lcd_pos(0x4c);break;发不要选边沿方式,易误动) case 3:armsec++;TMOD = 0x11; if (armsec>59) armsec=0;//Timer0,Timer1 工作于模式1, 16 位定时方式update_disbuf(0x50,"alarm_",armhour,ar TH0 = 0xdc;TL0 = 0x00; mmin,armsec);//Timer0 置10ms 定时初值pro_display();TH1 = 0xff;TL1 = 0x00; lcd_pos(0x4f);break;//Timer1 置初值TR0 = 1; case 4:year++;//Timer0 启动if (year> 99) year= 0;TR1 = 0; week_proc();while(1); // 星期自动运算}update_disbuf(0x50,"time_",hour,min,sec);// 设置按键处理程序pro_display();void pro_key() lcd_pos(0x05);break;{case 5:month++;switch (flag) if (month>12) month=1;{week_proc();case 0:alarm=!alarm; // // 星期自动运算启用或关闭闹钟(alarm=1: 启用,alarm=0: 关闭)update_disbuf(0x50,"time_",hour,min,sec);update_disbuf(0x50,"alarm_",armhour,ar pro_display();mmin,armsec); // 更新显示数据lcd_pos(0x08);break;pro_display(); case 6:date++;// 调用显示处理if(month==1||month==3||month==5||month==7||month==8||month==10||month==12)if (date>31) date=1;// 大月31 天if(month==4||month==6||month==9||month==11)if (date>30) date=1;// 小月30 天if (month==2){if(leap_year())// 闰年的条件{if (date>29) date=1;} // 闰年 2 月为29 天else{if (date>28)date=1;}} // 平年 2 月为28 天week_proc();// 星期自动运算update_disbuf(0x50,"time_ ",hour,min,sec);pro_display();lcd_pos(0x0b);break;case 7:hour++;if (hour>23) hour=0;update_disbuf(0x50,"time_",hour,min,sec);pro_display();lcd_pos(0x49);break;case 8:min++;if (min>59) min=0;update_disbuf(0x50,"time_",hour,min,sec);pro_display();lcd_pos(0x4c);break;case 9:sec++;if (sec>59) sec=0;update_disbuf(0x50,"time_",hour,min,sec);pro_display();lcd_pos(0x4f);break;default: break ;//Timer1 中断处理程序, 产生报警的声音void timer1() interrupt 3{TH1=0x80;TL1=0x00;SPK=~SPK; t++;}// 外部中断INT1 中断处理程序, 停止报警声音void int1() interrupt 2{if(TR1) TR1=0;}。

相关主题