资源描述
课程设计单片机系统课程设计成绩评定表设计课题基于89C51的数字音乐盒设计设计学院名称: 电气工程学院专业班级:学生姓名:学号:指导教师:设计地点 :设计时间 :指导教师意见:成绩: 签名: 年 月 日33单片机系统课程设计课程设计名称:基于89C51的数字音乐盒设计 专业班级:学生姓名:学号:指导教师:课程设计地点:课程设计时间: 单片机系统 课程设计任务书学生姓名专业班级学号题目课题性质工程设计课题来源自拟指导教师主要内容(参数)利用89C52设计数字音乐盒的控制系统,实现以下功能:1按下开始键或停止键后能够自动播放或停止音乐;2按下选择键可以切换曲目;3LCD显示当前播放的曲目标号和播放时间;4蜂鸣器发出某个音调,与之相对应的LED亮起;任务要求(进度)第1-2天:熟悉课程设计任务及要求,查阅技术资料,确定设计方案。第3-4天:按照确定的方案设计单元电路。要求画出单元电路图,元件及元件参数选择要有依据,各单元电路的设计要有详细论述。第5-6天:软件设计,编写程序。第7-8天:实验室调试。第9-10天:撰写课程设计报告。要求内容完整、图表清晰、文理流畅、格式规范、方案合理、设计正确。主要参考资料1 张迎新单片微型计算机原理、应用及接口技术(第2版)M北京:国防工业出版社,20042 谭浩强。C语言程序设计(第二版),北京:清华大学出版社,1991.3中国电子网http:/www.21IC.com4 康华光,模拟电子技术基础(第四版)武汉:华中理工大学出版社,1999.审查意见系(教研室)主任签字: 年月日目录引言51 概述52 系统总体方案设计52.1硬件组成52.2.方案论证。62.3音乐盒的功能图用框图表示73硬件电路设计73.1单片机电路73.2 晶振电路83.3复位电路83.4键盘83.5蜂鸣器电路93.6 LCD液晶电路93.7电源电路104 软件设计104.1 音调、节拍、及编码的设置104.1.1音调104.1.2节拍的确定124.2144.3播放音乐子程序流程图(包含了键盘扫描)154.4定时器0中断服务子程序框图:155,调试165.1 检查硬件连接165.2 检查软件系统165.2.1165.2.2165.3测试结果175.3.1整体运行图175.3.2LED灯运行图186 总结187参考文献18附录A19附录B20引言在电子信息技术飞速发展的今天,现代电子产品几乎渗透了社会的各个领域,它不仅推动了社会的进步,而且为我们的生活带来了诸多的便利。由于人们生活质量的提高,人们对视觉、听觉方面的享受提出了越来越高的要求。小小的音乐盒可以给人们带来美好的回忆,提高人们的精神文化享受。传统音乐盒多是机械型的,体积笨重,发音单调,可以选择的曲目较为单一。本文设计的音乐盒是以单片机为核心元件的电子式音乐盒,它体积小,重量轻,可以随心添加自己喜欢的音乐,外观效果多彩,使用方便,并且具有一定的商业价值。1概述本音乐盒的设计是以AT89C52芯片的电路为基础,外部以蜂鸣器作为发音器件,共同组成了音乐演奏控制器的硬件电路,通过软件程序来控制单片机内部的定时器使单片机I/O口发出相应频率的脉冲来驱动蜂鸣器发出某个音调,与之相对应的LED亮起,从而演奏出优美动听的音乐。利用按键切换演奏出不同的乐曲,并可以在LCD上显示当前曲目序号和时间。用户可以按照自己的喜好选择音乐并将其转化成机器码存入单片机的存储器中。对于不同型号的单片机只需要相应的改变一下地址和I/O管脚即可。该软、硬件系统具有很好的通用性,很高的实际使用价值,为单片机DIY制作者和音乐爱好者具有一定的借鉴作用。2 系统总体方案设计2.1硬件组成按照数字是音乐盒对控制系统的技术要求,控制系统的硬件应包括以下几部分:(1)控制器。作为控制系统的核心,可以采用主流的51单片机,MSP430,或处理性能更为优越的ARM来合理控制各个器件有条不紊的运行。(2)乐曲选择器。可以采用按键或者触摸屏来切换相应的曲目。(3)音频输出器件。做为音乐盒的发声设备,可以用蜂鸣器通过它可以将音乐代码转变为音频信号发出来。(4)人机交互界面。可以运用LED或LCD在歌曲播放过程中用来对歌曲信息进行监控显示,反馈给使用者相应的信息。硬件方框图图2-1-12.2.方案论证。本次设计以低成本,灵活方便为原则,所以控制器选用主流的51系列单片机,考虑到51内部储存空间的限制,故选用容量为51两倍的AT89C52单片机作为总控制器,共有以下两套方案可供选择:方案一:以AT89C52单片机作为总控制器,以机械键盘作为乐曲选择器,以蜂鸣器作为音频输出设备,以LCD1602液晶作为人机交互界面。 方案二:以AT89C52单片机作为总控制器,以机械键盘作为乐曲选择器,以蜂鸣器作为音频输出设备,以LED数码管作为人机交互界面。由于数码管显示内容的单一,操作较为繁琐且难以满足大众对主流时尚的需要,所以选用较为流行的显示效果良好的1620液晶作为人机交互界面,最终确定方案一作为制作方案。总体方案图:图2-2-12.3音乐盒的功能图用框图表示音乐盒的功能结构如图2.2所示。Start_pause键负责开始播放和暂停歌曲,播放歌曲共3首,分别是和两只老虎和铃儿响叮当。Up键负责切换上一首曲目,down键用来切换下一首曲目。图2-3-13硬件电路设计3.1单片机电路微控制器采用AT89C52。AT89C52是美国ATMEL公司生产的与MCS-51系列单片机完全兼容的高性能CMOS 8位单片机,MCS-51系列单片机以其推出时间早、配套资源丰富、开发手段完善、性价比高等特点而得到了广泛的应用,是单片机的主流品种。AT89C52的内部资源主要包括:与MCS-51 系列完全兼容的高性能8位CPU;8K字节可重复编程的Flash存储器;256字节的SRAM;4个8位的并行口,共32条I/O口线;3个16位的定时器/计数器;6个中断源,2个中断优先级的中断系统;一个全双工的串行口;内部振荡器。3.2 晶振电路单片机的正常工作是在时钟的作用下完成的,晶振选用11.0592M的。图3-2-13.3复位电路复位电路是为了在某些情况下需要单片机恢复到初始运行条件下而设计的,只要给RESET端大约10US的高电平,单片机就可以有效复位。图3-3-13.4键盘该键盘电路是为了能够更好地对音乐盒进行控制,选择和切换曲目,开始和终止曲目,10K的上拉电阻保证键在没按下时,I/O口输出为高电平,键按下时防止按键杯烧坏。图3-4-13.5蜂鸣器电路蜂鸣器作为音乐盒的发声设备,当I/O口数出一个低电平时,蜂鸣器能够发声,PNP三极管用来放大输出电流,从而来驱动蜂鸣器。图3-5-13.6 LCD液晶电路LCD液晶显示电路用来进行人机交互,对1602的操作通过P0口发送数据来实现。图3-6-1图3-6-23.7电源电路通过变压器将220V交流变为6V,再通过整流,滤波,稳压电路实现单片机可以使用的电源,其中LM7805使稳压电源。图3-7-14 软件设计4.1 音调、节拍、及编码的设置4.1.1音调音调的确定不同音高的乐音是用C、D、E、F、G、A、B来表示,这7个字母就是音乐的音名,它们一般依次唱成DO、RE、MI、FA、SO、LA、SI,即唱成简谱的1、2、3、4、5、6、7,相当于汉字“多来米发梭拉西”的读音,这是唱曲时乐音的发音,所以叫“音调”。每个音调都有它固有的频率。如高音DO的频率(1046Hz)刚好是中音DO的频率(523Hz)的一倍,中音DO的频率(523Hz)刚好是低音DO频率(266 Hz)的一倍;同样的,高音RE的频率(1175Hz)刚好是中音RE的频率(587Hz)的一倍,中音RE的频率(587Hz)刚好是低音RE频率(294 Hz)的一倍。1)要产生音频脉冲,只要算出某一音频的周期(1/频率),然后将此周期除以2,即为半周期的时间。利用定时器计时这半个周期时间,每当计时到后就将输出脉冲的I/O反相,然后重复计时此半周期时间再对I/O反相,就可在I/O脚上得到此频率的脉冲。2)利用AT89C52的内部定时器使其工作在计数器模式MODE1下,改变计数值TH0及TL0以产生不同频率的方法。此外结束符和休止符可以分别用代码00H和FFH来表示,若查表结果为00H,则表示曲子终了;若查表结果为FFH,则产生相应的停顿效果。3)例如频率为523Hz,其周期T=1/523=1912us,因此只要令计数器计时956us/1us=956,在每次计数956次时将I/O反相,就可得到中音DO(523Hz)。计数脉冲值与频率的关系公式如下:N=Fi2FrN:计算值;Fi:内部计时一次为1us,故其频率为1MHz;其计数值的求法如下:T=65536-N=65536-Fi2Fr例如:设K=65536,F=1000000=Fi=1MHz,求低音DO(261Hz)。中音DO(523Hz)。高音的DO(1046Hz)的计算值T=65536-N=65536-Fi2Fr=65536-10000002Fr=65536-500000/Fr低音DO的T=65536-500000/262=63627中音DO的T=65536-500000/523=64580高音DO的T=65536-500000/1047=650594) C调各音符频率与计数值T的对照表如表4.1所示。表4.1 C调各音符频率与计数值T的对照表低音频率T参数中音频率T参数高音频率T参数Do2621908229Do523956115Do10465757Do2771805217Do554903108Do11095454Re2941701204Re587852102Re11755151Re3111608193Re62280497Re12454848Mi3301515182Mi65975991Mi13184545Fa3491433172Fa69871686Fa13974343Fa3701351162Fa74067681Fa14804141So3921276153So78463877So15683838So4151205145So83160272So16613636La4401136136La88056868La17603434La4641078129La93253664La18653232Si4941012121Si98850661Si197630304.1.2节拍的确定若要构成音乐,光有音调是不够的,还需要节拍,让音乐具有旋律(固定的律动),而且可以调节各个音的快慢度。音持续时间的长短即时值,一般用拍数表示。休止符表示暂停发音,一排的时间并不确定,一般是400500MS,本次设计选择一拍的时间是500MS。一首音乐是由许多不同的音符组成的,而每个音符对应着不同频率,这样就可以利用不同的频率的组合,加以与拍数对应的延时,构成音乐。对于单片机来说,产生不同频率的脉冲是非常方便的,利用单片机的定时/计数器来产生这样的方波频率信号。因此,需要弄清楚音乐中的音符和对应的频率,以及单片机定时计数的关系。表4.2节拍与节拍码对照节拍码节拍数节拍码节拍数11/4拍11/8拍22/4拍21/4拍33/4拍33/8拍41拍42/1拍51又1/4拍55/8拍61又1/2拍63/4拍82拍81拍A2又1/2拍A1又1/4拍C3拍C1又1/2拍F3又3/4拍每个音符使用1个字节,字节的高4位代表音符的高低,低4位代表音符的节拍,图4.2为节拍码的对照。如果1拍为0.4秒,1/4拍实0.1秒,只要设定延迟时间就可求得节拍的时间。假设1/4拍为1DELAY,则1拍应为4DELAY,以此类推。所以只要求得1/4拍的DELAY时间,其余的节拍就是它的倍数,如图5.3为1/4和1/8节拍的时间设定。表4.3 1/4和1/8节拍的时间设定曲调值DELAY曲调值DELAY调4/4125毫秒调4/462毫秒调3/4187毫秒调3/494毫秒调2/4250毫秒调2/4125毫秒编码do re mi fa so la si分别编码为17,重音do编为8,重音re编为9,停顿编为0。播放长度以十六分音符为单位(在本程序中为125ms),一拍即四分音符等于4个十六分音符,编为4,其它的播放时间以此类推。音调作为编码的高4位,而播放时间作为低4位,如此音调和节拍就构成了一个编码。以0 xff作为曲谱的结束标志。举例1:音调do,发音长度为两拍,即二分音符,将其编码为0 x18。举例2:音调re,发音长度为半拍,即八分音符,将其编码为0 x22歌曲播放的设计。先将歌曲的简谱进行编码,储存在一个数据类型为unsignedchar 的数组中。程序从数组中取出一个数,然后分离出高4位得到音调,接着找出相应的值赋给定时器0,使之定时操作蜂鸣器,得出相应的音调;接着分离出该数的低4位,得到延时时间,接着调用软件延时。表4.4 简谱对应的简谱码、T值、节拍数表4.4简谱发音简谱码T值节拍码节拍数5低音SO16426011/4拍6低音LA26440022/4拍7低音TI36452433/4拍1中音DO46458041拍2中音RE56468451又1/43中音MI66477761又1/24中音FA76482082拍5中音SO864898A2又1/26中音LA964968C3拍7中音TIA65030F3又3/41高音DOB650582高音REC651103高音MID651574高音FAE651785高音SOF652174.2本设计主程序较为简单,流程图如下:图4-2-14.3播放音乐子程序流程图(包含了键盘扫描)图4-3-14.4定时器0中断服务子程序框图: 图4-4-15调试5.1 检查硬件连接在PROTUES检查各硬件管脚是否连接正确,线路逻辑是否正确,例如:晶振电路的连接,复位电路是否设计正确.5.2 检查软件系统5.2.1根据系统的原理结构检查各流程图是否正确,再根据流程图来检查程序是否也正确。5.2.2将所有程序组织起来,在软件环境下运行,检查程序是否正确。通过对硬件和软件系统的认真检查,反复测试,如果没有出现问题即可把源程序编译成HEX文件装载到单片机中,对硬件进行仿真。5.3测试结果由于开发板上1602液晶遮挡住了LED灯,所以附上两张图5.3.1整体运行图图5-3-15.3.2LED灯运行图图5-3-26 总结经过几天的紧张工作,终于把本次设计完成了,总体下来,其中有苦有乐。比较喜欢电子制作的我,在这次设计当中让我学到了很多。在大二寒假期间自学了一点单片机编程,我想对本次的设计也带来了一定的帮助。刚拿到题目,我很高兴,因为我一直都想做一个属于我自己的制作,由于学习较为繁忙就迟迟没有亲自动起手来,正好借着这次机会,让我对自己的动手能力和自己所学有了一个很好地锻炼和检测的机会。由于音乐知识较为薄弱,所以在起初又感觉无从下手,在上网查找了与音乐相关的信息之后,我突然有了一点思路,就开始了我自己的制作之路。刚开始一切都很顺利,就在编写按键控制1602液晶切换曲目、暂停和开始音乐的时候耽误了好久。刚开始是按键总是没有反应,1602无法显示按键的切换,经过一番查找终于找到了原因,原来在给1602写数据显示的时候字符的编码地址出现了错误。之后当按下暂停键之后液晶上没有及时,但是歌曲去一直在唱,刚开始找不到原因,就一直检查按键的扫描程序,但始终没有结果,最后,当我把键盘的扫描程序放到歌曲的循环子程序当中后,突然能够正常运行了,我感到很开心,再经过一系列的检测与调试,最后终于能够演奏我自己写进去的音乐了,一个属于我的设计就完成了。通过本次设计使我的动手能力有了一定的提高,更锻炼了我的编程能力,分析问题和解决问题的能力,真的给了我很大的帮助,可以说是,本次设计收货良多。 7参考文献1)谭浩强。C语言程序设计(第二版),北京:清华大学出版社,1991.2)张维新。单片微型计算机原理应用及接口技术(第二版),北京,国防工业出版社,2009.3)单片机播放音乐原理,百度文库http:/ 康华光,模拟电子技术基础(第四版)武汉:华中理工大学出版社,1999.5)千年之恋简谱http:/ uint unsigned int #define uchar unsigned charsbit wela=P27;sbit dula=P26;sbit beep=P23;sbit up=P31; /曲目上一曲选择键sbit start_pause=P32; /曲目开始和停止键sbit down=P33; /曲目下一曲选择键sbit lcden=P34;sbit rs=P35;sbit rd=P37;void write_shijian(uchar,uchar);uchar shi,ge,fen,miao;uchar timeh,timel,i;uchar num=0,count=0;uchar code table0= xianzaiqumu:0 ;uchar code table1= 00:00 ;uchar yinyue=0 xff,0 xfe,0 xfd,0 xfb,0 xf7,0 xef,0 xdf,0 xbf,0 x7f,0 x0,0 x0;/将音调转化为对应的LED样式uchar code chuzhi= 0 xff,0 xff,/占位 0 xFC,0 x8E,/中央C调1-7 0 xFC,0 xED, 0 xFD,0 x43, 0 xFD,0 x6A, 0 xFD,0 xB3, /用于产生不同的音调的定时器中装的初值 0 xFD,0 xF3, 0 xFE,0 x2D, 0 xFE,0 x47,/高八度1-7 0 xFE,0 x76, 0 xFE,0 xA1, 0 xFE,0 xC7, 0 xFE,0 xD9, 0 xFE,0 xF9, 0 xFF,0 x16 ;uchar code qumu1= /千年之恋0 x12,0 x22,0 x34,0 x84,0 x74,0 x54,0 x38,0 x42,0 x32,0 x22,0 x42,0 x34,0 x84,0 x72,0 x82,0 x94,0 xA8,0 x08,/前奏0 x32,0 x31,0 x21,0 x32,0 x52,0 x32,0 x31,0 x21,0 x32,0 x62,/竹林的灯火 到过的沙漠 0 x32,0 x31,0 x21,0 x32,0 x82,0 x71,0 x81,0 x71,0 x51,0 x32,0 x22,/七色的国度 不断飘逸风中 0 x32,0 x31,0 x21,0 x32,0 x52,0 x32,0 x31,0 x21,0 x32,0 x62,/有一种神秘 灰色的旋涡 0 x32,0 x31,0 x21,0 x32,0 x83,0 x82,0 x71,0 x72,0 x02,/将我卷入了迷雾中 0 x63,0 xA1,0 xA2,0 x62,0 x92,0 x82,0 x52,/看不清的双手 0 x31,0 x51,0 x63,0 x51,0 x63,0 x51,0 x63,0 x51,0 x62,0 x82,0 x7C,0 x02,/一朵花传来谁经过的温柔 0 x61,0 x71,0 x82,0 x71,0 x62,0 xA2,0 x71,0 x76,/穿越千年的伤痛 0 x61,0 x71,0 x82,0 x71,0 x62,0 x52,0 x31,0 x36,/只为求一个结果 0 x61,0 x71,0 x82,0 x71,0 x62,0 xA3,0 x73,0 x62,0 x53,/你留下的轮廓 指引我 0 x42,0 x63,0 x83,0 x83,0 x91,0 x91,/黑夜中不寂寞 0 x61,0 x71,0 x82,0 x71,0 x62,0 x0A2,0 x71,0 x76,/穿越千年的哀愁 0 x61,0 x71,0 x82,0 x71,0 x62,0 x52,0 x31,0 x36,/是你在尽头等我 0 x61,0 x71,0 x82,0 x71,0 x62,0 xA3,0 x73,0 x62,0 x53,/最美丽的感动 会值得 0 x42,0 x82,0 x88,0 x02,0 x74,0 x93,0 x89,0 xff/结束标志/用一生守候;uchar code qumu2=/两只老虎0 x14,0 x24,0 x34,0 x14,0 x14,0 x24,0 x34,0 x14,/两只老虎 两只老虎0 x34,0 x44,0 x54,0 x54,0 x34,0 x44,0 x54,0 x54,/跑得快 跑得快0 x52,0 x51,0 x61,0 x52,0 x51,0 x41,0 x34,0 x14,/一只没有眼睛0 x52,0 x51,0 x61,0 x52,0 x51,0 x41,0 x34,0 x14,/一直没有尾巴0 x14,0 x54,0 x14,0 x14,0 x14,0 x54,0 x14,0 x14,/真奇怪 真奇怪0 xff;uchar code qumu3=/铃儿响叮当0 x32,0 x32,0 x34,0 x34,0 x34,0 x32,0 x52,0 x12,0 x21,0 x21,0 x34,0 x04,/叮叮当,叮叮当,铃儿响叮当0 x44,0 x42,0 x41,0 x42,0 x32,0 x32,0 x31,0 x31,0 x52,0 x32,0 x22,0 x12,0 x52,0 x52,0 x02,/我们滑雪多快乐, 我们冲破大风雪0 x52,0 x52,0 x32,0 x22,0 x12,0 x62,0 x22,0 x64,/我们坐在雪橇上0 x62,0 x42,0 x32,0 x32,0 x22,0 x62,0 x04,0 x52,0 x52,0 x42,0 x22,0 x34,0 x04,0 x52,/奔驰过田野, 欢笑又歌唱0 x52,0 x32,0 x22,0 x12,0 x54,0 x52,0 x04,0 x52,0 x32,0 x22,0 x12,0 x64,0 x04,/铃声响叮当 我们精神多欢畅0 x62,0 x42,0 x32,0 x22,0 x52,0 x02,0 x52,0 x52,0 x62,0 x52,0 x42,0 x22,0 x14,0 x04,/今晚滑雪多块了, 把滑雪歌儿唱0 xff;void delay1(uint z)/延时125MS,即十六分音符uint x,y;for(x=z;x0;x-)for(y=14350;y0;y-);void delay2(uchar z)/延时1m秒uchar x,y;for(x=z;x0;x-)for(y=110;y0;y-);void write_common(uchar common)/LCD写命令rs=0;P0=common;delay2(5);lcden=1;delay2(5);lcden=0;void write_data(uchar dat)/LCD写数据rs=1;P0=dat;delay2(5);lcden=1;delay2(5);lcden=0;void init()/初始化函数uchar i,j;rd=0;TH0=0; /定时器T0和定时T1初始化TL0=0;TH1=(65535-10000)/256;TL1=(65535-10000)%256;EA=1;ET0=1;ET1=1;TMOD=0 x01;TMOD=0 x10;TR0=0;TR1=1;wela=1;/LCD初始化wela=0;dula=1;dula=0;lcden=0;write_common(0 x38);write_common(0 x0c);write_common(0 x06);write_common(0 x01);write_common(0 x80);for(i=0;i16;i+)write_data(table0i);delay2(10);write_common(0 x80+0 x40);for(j=0;j16;j+)write_data(table1j);void key_scan() /键盘扫描函数if(up=0)delay2(5);if(up=0)num+;if(num=4)num=0;miao=0;fen=0;while(!up);write_common(0 x80+13);write_data(0 x30+num);elseif(down=0)delay2(5);if(down=0)num-;miao=0;fen=0;if(num=-1)num=3; while(!down);write_common(0 x80+13);write_data(0 x30+num);elseif(start_pause=0)delay2(5);if(start_pause=0)count+;while(!start_pause);if(count=1)TR1=1;/启动定时器1elseTR1=0;count=0;void timer1() interrupt 3 /定时器1中断服务程序 TH1=(65535-10000)/256;TL1=(65535-10000)%256; count+;if(count=100)count=0;miao+;if(miao=60)miao=0;fen+;if(fen=60)fen=0; void timer0() interrupt 1 /定时器T0用于产生各种音调TH0=timeh;TL0=timel;beep=beep;void write_shijian(uchar dizhi,uchar date) /曲目时间计时显示shi=date/10;ge=date%10;write_common(0 x80+0 x40+dizhi);write_data(0 x30+shi);write_data(0 x30+ge); void song() /歌曲子函数uint temp;uchar jianpu;/jianpu是简谱i=0;while(1)if(num=0)/复位后液晶显示write_shijian(8,0);write_shijian(5,0);elsewrite_shijian(8,miao); write_shijian(5,fen);key_scan(); if(num=0)break;if(num=1)/选择曲目temp=qumu1i;while(!count )/ 如果键按下start_pause键,开始或暂停当前的曲目key_scan();TR0=0;beep=1;if(count)break;if(num=2)/选择曲目temp=qumu2i;while(!count )/ 如果键按下start_pause键,开始或暂停当前的曲目key_scan();TR0=0;beep=1;if(count)break;if(num=3)/选择曲目temp=qumu3i;while(!count )/ 如果键按下start_pause键,开始或暂停当前的曲目key_scan();TR0=0;beep=1;if(count)break;if(temp=0 xff)/如果为终止符,结束曲目break;jianpu=temp/16; /取数的高4位P1=yinyuejianpu;/将取出的音符对应的码值送到P1口,使P1口的二极管对应发光if(jianpu!=0)timeh=chuzhijianpu*2; /取出对应的简谱码timel=chuzhijianpu*2+1;TR0=1;elseTR0=0;beep=1;delay1(temp%16); /取数的低4位TR0=0;beep=1;delay2(10);/取出每个音符后延时10m秒 TR0=1; i+;TR0=0;beep=1;void main()/主函数init();while(1)song();/唱歌子函数
展开阅读全文