基于单片机的电子琴设计论文

上传人:仙*** 文档编号:33402702 上传时间:2021-10-17 格式:DOC 页数:40 大小:387.54KB
返回 下载 相关 举报
基于单片机的电子琴设计论文_第1页
第1页 / 共40页
基于单片机的电子琴设计论文_第2页
第2页 / 共40页
基于单片机的电子琴设计论文_第3页
第3页 / 共40页
点击查看更多>>
资源描述
电子琴设计目录摘要2Abstract21. 总体方案任务及要求3电子琴系统的组成4系统框图52. 方案论证与比较 61. 控制器部分 62. 显示部分 63. 键盘部分 74. 音频部分 75. 供电部分 83. 系统的具体设计及实现105. 硬件设计 101. 1602液晶屏显示设计112. 键盘设计 143. 音频功放设计156. 软件设计201. 主程序流程142. 音频与键盘程序流程213. LCD1602流程254. 测试、结果及分析257. 基本功能268. 发挥功能部分269. 其他发挥部分26参考文献27附录一、系统原理图28附录二、系统源代码28摘 要电子琴是现代电子科技与音乐结合的产物,是一种新型的键盘乐器。它在现代音乐扮演着重要的角色,单片机具有强大的控制功能和灵活的编程实现特性,它已经溶入现代人们的生活中,成为不可替代的一部分。本文的主要内容是用AT89c51单片机为核心控制元件,设计一个电子琴。以单片机作为主控核心,与键盘、扬声器等模块组成核心主控制模块,在主控模块上设有16个按键和扬声器。本系统运行稳定,其优点是硬件电路简单,软件功能完善,控制系统可靠,性价比较高等,具有一定的实用和参考价值。Abstract Electronic organ is a modern electronic music technology and the product is a new type of keyboard instruments. It played an important role in modern music. SCM has powerful control functions and flexible programming characteristics. It has converged with modern peoples lives, become an irreplaceable part. The main content is AT89C51 control of the core components, design of a electronic organ. SCM as a host to the core, with the keyboard, speaker and other core modules. In the main control module has 16 keys and a speaker. The system is steady, its simple hardware circuits, software functions, reliability of control system and high cost performance is its advantages. It also has certain practical and reference value.设计任务与要求1.任务设计制作一个电子琴2要求1.基本要求:1)可以通过按键控制发音,能够发出1、2、3、4、5、6、7、i等八个音符;2)可以播放已存储的音乐;3)能够自动演奏多首(两首以上)乐曲,且演奏方式可选择(如重复播放或者顺序播放等)。2.扩展要求:1)可以发出八个以上的音符;2)进行音调、音量的选择;3)可以对编奏乐曲进行录音,在按下放音键时能演奏出来;4)其他。 电子琴系统的组成单片机因体积小、功能强、价格低廉而得到广泛应用。AT89C51单片机设计微型电子琴的方法,仅需AT89C51最小系统,扩展一组矩阵键盘,再接一组发光二极管用来指示电子琴的工作状态。本系统分为两个部分,一个是音乐另一个就是电子琴。音乐播放部分:乐音实际上是有固定周期的信号。本文介绍用AT89C51的两个定时器(如T0,T1)控制,在P3.7脚上输出方波周期信号,产生乐音,通过矩阵键盘按键产生不同的音符,由此操作人员可以随心所欲的弹奏自己所喜爱的乐曲,当不想弹奏时通过按放歌键可以演奏事先存放在单片机中的几首动听的曲子供消遣。当歌曲演奏完时,通过按复位键便可回到初始状态,这样就做出了一台微型电子琴。由于一首音乐是许多不同的音阶组成的,而每个音阶对应着不同的频率,这样我们就可以利用不同的频率的组合,即可构成我们所想要的音乐了,当然对于单片机来产生不同的频率非常方便,我们可以利用单片机的定时/计数器T0来产生这样方波频率信号,因此,我们只要把一首歌曲的音阶对应频率关系弄正确即可。乐曲中,每一音符对应着确定的频率,我们将每一音符的时间常数和其相应的节拍常数作为一组,按顺序将乐曲中的所有常数排列成一个表,然后由查表程序依次取出,产生音符并控制节奏,就可以实现演奏效果。电子琴弹奏部分:实际上就是把每个按键所对应的值经过处理后发给单片机,再在单片机内把数字当作指针指向所对应的音符。系统框图该系统通过电子琴按键随意键入所要表达的音符,作为电平送给主体电路,中央处理器通过识别,解码输出音符,在扬声器中发出有效的声音。通过这样可以不断的弹奏音乐。嵌入式电路,按键电路,LED显示电路和两个功能键组成,通过功能键可以选择播放音乐。其主要模块由五个部分组成,具体关系如图3-1所示:功能选择 (弹奏/播放,还可给矩阵键盘赋第二功能)4X4矩阵式键盘音频51单片机AT89C51LED显示图3-1 带存储的电子琴框图上图即为此次设计中的电子琴的硬件结构图,我们运用单片机的最小系统,用P2口的高四位和P2口的低四位作4X4矩阵式按键的接口,用P1口作lcd1602的接口。二.方案论证与比较1控制器 采用STC89C52单片机作为主控芯片。优点:STC89C52作为一种比较成熟的单片机型号,广范应用于各领域技术比较熟练,价格相对便宜。并且与51有相同的内核,熟悉程度深,操作快捷方便,可以直接用窗口下载程序,便于程序下载调试。2.显示部分方案一:LED流水灯。优点:价格低廉,操作方便,控制容易,布板省时,使用得当非常地引人注目。缺点:显示的信息不大直观,往往只能起到单纯装饰的作用。方案二:LCD1602。优点:可以较好的显示所要表达的内容,直观明了。缺点:接线比较复杂,需要驱动多,需要输入比较多的内容来生成字符,增加了难度,花费较多的时间。论证:为了比较好的显示内容,达到要求效果,使用方案二。3.键盘 方案一 :独立式键盘。优点: 利用I/O口直接连接的独立式键盘,每键都有相应的I/O口对应,编程容易控制,实现方便;缺点:但IO口有限,能接的按键不能太多,而本系统需用户根据需要调整的参数较多,用独立按键会使操作变得复杂。方案二 :利用PA口接成4*4键盘。(用附加键增加原放音键的功能)优点:利用8个IO口得到16个按键,可使操作界面变得简单,接线也相对短,经过精心设计,不但不用担心飞线,还能减少空间。操作也方便,并且因为给了同一个键双重定义,是在不增加按键的情况下使功能更多,节省了大量资源。缺点:软件处理比独立按键复杂。论证:通过比较,方案二为最佳方案。3.音频部分 方案一:蜂鸣器。优点:简便,价格低廉。缺点:声音有些难听。 方案二:三极管+喇叭。 优点:相对而言接线也不太复杂,便于调试,音质相对较好。 缺点:二极管容易设计出问题,并且不是很稳定。 方案三:LM386+喇叭 优点:音质比较好,用了比较专门的音频功放,稳定性也比较好。 缺点:必须学习功放的相关知识,接线复杂,由于对元件较陌生成功率会低一些。论证:本着学习,与挑战自我,并追求完美的想法,尝试使用新的东西,用以完成更好的效果。5.供电端口方案一:电池+二极管降压 优点:非常容易实现 缺点:稳定性不高,电压比标准值大一些。方案二:USB供电 优点:稳定性好 缺点:带负载能力不强 方案三:稳压电源 优点:带负载能力强,电压稳定论证:使用方案三。三.系统设计与实现 1.硬件设计1.1 1602液晶显示的设计在日常生活中,我们对液晶显示器并不陌生。液晶显示模块已作为很多电子产品的通过器件,如在计算器、万用表、电子表及很多家用电子产品中都可以看到,显示的主要是数字、专用符号和图形。在单片机的人机交流界面中,一般的输出方式有以下几种:发光管、LED数码管、液晶显示器。发光管和LED数码管比较常用,软硬件都比较简单,在前面章节已经介绍过,在此不作介绍,本章重点介绍字符型液晶显示器的应用。在单片机系统中应用晶液显示器作为输出器件有以下几个优点:由于液晶显示器每一个点在收到信号后就一直保持那种色彩和亮度,恒定发光,而不像阴极射线管显示器(CRT)那样需要不断刷新新亮点。因此,液晶显示器画质高且不会闪烁。液晶显示器都是数字式的,和单片机系统的接口更加简单可靠,操作更加方便。液晶显示器通过显示屏上的电极控制液晶分子状态来达到显示的目的,在重量上比相同显示面积的传统显示器要轻得多。相对而言,液晶显示器的功耗主要消耗在其内部的电极和驱动IC上,因而耗电量比其它显示器要少得多。1)液晶显示简介液晶显示原理液晶显示的原理是利用液晶的物理特性, 通过电压对其显示区域进行控制,有电就有显示,这样即可以显示出图形。液晶显示器具有厚度薄、适用于大规模集成电路直接驱动、易于实现全彩色显示的特点,目前已经被广泛应用在便携式电脑、数字摄像机、PDA移动通信工具等众多领域。液晶显示器的分类液晶显示的分类方法有很多种,通常可按其显示方式分为段式、字符式、点阵式等。除了黑白显示外,液晶显示器还有多灰度有彩色显示等。如果根据驱动方式来分,可以分为静态驱动(Static)、单纯矩阵驱动(Simple Matrix)和主动矩阵驱动(Active Matrix)三种。液晶显示器各种图形的显示原理:点阵图形式液晶由MN个显示单元组成,假设LCD显示屏有64行,每行有128列,每8列对应1字节的8位,即每行由16字节,共168=128个点组成,屏上6416个显示单元与显示RAM区1024字节相对应,每一字节的内容和显示屏上相应位置的亮暗对应。例如屏的第一行的亮暗由RAM区的000H00FH的16字节的内容决定,当(000H)=FFH时,则屏幕的左上角显示一条短亮线,长度为8个点;当(3FFH)=FFH时,则屏幕的右下角显示一条短亮线;当(000H)=FFH,(001H)=00H,(002H)=00H,(00EH)=00H,(00FH)=00H时,则在屏幕的顶部显示一条由8段亮线和8条暗线组成的虚线。这就是LCD显示的基本原理。用LCD显示一个字符时比较复杂,因为一个字符由68或88点阵组成,既要找到和显示屏幕上某几个位置对应的显示RAM区的8字节,还要使每字节的不同位为“1”,其它的为“0”,为“1”的点亮,为“0”的不亮。这样一来就组成某个字符。但由于内带字符发生器的控制器来说,显示字符就比较简单了,可以让控制器工作在文本方式,根据在LCD上开始显示的行列号及每行的列数找出显示RAM对应的地址,设立光标,在此送上该字符对应的代码即可。2)1602LCD主要技术参数:显示容量:162个字符芯片工作电压:4.55.5V工作电流:2.0mA(5.0V)模块最佳工作电压:5.0V字符尺寸:2.954.35(WH)mm3)引脚功能说明1602LCD采用标准的14脚(无背光)或16脚(带背光)接口,各引脚接口说明如表10-13所示:编号符号引脚说明编号符号引脚说明1VSS电源地9D2数据2VDD电源正极10D3数据3VL液晶显示偏压11D4数据4RS数据/命令选择12D5数据5R/W读/写选择13D6数据6E使能信号14D7数据7D0数据15BLA背光源正极8D1数据16BLK背光源负极4)电路原理图2.2矩阵键盘 在本系统中,针对用户调整各项参数时的需要,我们采用了4*4键盘,只占用8个IO口(P1口)就实现了16个按键,使操作界面更加人性化,操作过程更加简单、方便。键盘的原理图如下图所示。PCB设计3. LM386及喇叭LM386是美国国家半导体公司生产的音频功率放大 器,主要应用于低电压消费类产品。为使外围元件最少,电压增益内置为20。但在1脚和8脚之间增加一只外接电阻和电容,便可将电压增益调为任意值,直至 200。输入端以地位参考,同时输出端被自动偏置到电源电压的一半,在6V电源电压下,它的静态功耗仅为24mW,使得LM386特别适用于电池供电的场 合。LM386是一种音频集成功放,具有自身功耗低、电压增益可调整、电源电压范围大、外接元件少和总谐波失真小等优点,广泛应用于录音机和收音机之中。1)LM386内部电路LM386内部电路原理图如图所示。与通用型集成运放相类似,它是一个三级放大电路。第一级为差分放大电路,T1和T3、T2和T4分别构成复合管,作为差分放大电路的放大管;T5和T6组成镜像电流源作为T1和T2的有源负载;T3和T4信号从管的基极输入,从T2管的集电极输出,为双端输入单端输出差分电路。使用镜像电流源作为差分放大电路有源负载,可使单端输出电路的增益近似等于双端输出电容的增益。第二级为共射放大电路,T7为放大管,恒流源作有源负载,以增大放大倍数。第三级中的T8和T9管复合成PNP型管,与NPN型管T10构成准互补输出级。二极管D1和D2为输出级提供合适的偏置电压,可以消除交越失真。引脚2为反相输入端,引脚3为同相输入端。电路由单电源供电,故为OTL电路。输出端(引脚5)应外接输出电容后再接负载。电阻R7从输出端连接到T2的发射极,形成反馈通路,并与R5和R6构成反馈网络,从而引入了深度电压串联负反馈,使整个电路具有稳定的电压增益。2)LM386的引脚图LM386的外形和引脚的排列如右图所示。引脚2为反相输入端,3为同相输入端;引脚5为输出端;引脚6和4分别为电源和地;引脚1和8为电压增益设定端;使用时在引脚7和地之间接旁路电容,通常取10F。LM386的封装形式有塑封8引线双列直插式和贴片式。3)特性(Features): 静态功耗低,约为4mA,可用于电池供电。 工作电压范围宽,4-12V or 5-18V。 外围元件少。 电压增益可调,20-200。 低失真度4)电路设计原理图5)PCB设计图三.软件设计1.主程序流程图扫描主按键开始按下?有键接N进入子菜单执行 主体程序流程图2.音频按键控制流程2.1变音调在弹奏的基础上设计偏移量,实现同一按键的不同声调值(弹奏同图1)进进入相应的子目录执行进开始N退出有无主按键按下2.2弹奏播音流程 扫描矩阵键盘弹奏音符、显示音高开始有键接下?有无主按键按下N退出2.3播放音乐流程进入子菜单目录执行相应操作开始扫描子菜单按键扫描主控制键扫描键盘有键接下?有无主按键按下NY退出2.4录音控制流程 按顺序播放弹奏的音乐开始检查数组是否为空退出有无主按键按下NY 3. LCD1602运行流程四.测试结果与分析1.基本功能要求功能实现情况可以通过按键控制发音,能够发出1、2、3、4、5、6、7、i等八个音符;实现的比较好,音效也比较好可以播放已存储的音乐;可流畅播放多首歌曲能够自动演奏多首(两首以上)乐曲,且演奏方式可选择(如重复播放或者顺序播放等)。实现此功能,可以自动播放,同时扩展了弹奏键的功能,效果更好2.扩展功能要求功能实现功能可以发出八个以上的音符实行此功能,由弹奏键扩展了更多的音调,声音丰富进行音调、音量的选择在比较大范围内调,音效也比较好可以对编奏乐曲进行录音,在按下放音键时能演奏出来可以,但是是从单片机内部存储,效果不是很好,能存的量也比较小,播放不很顺畅其他增加一块液晶用以显示歌名音量等,可以实现,当播放略有延迟。参考文献8051单片机实践与应用沈庆明 清华大学出版社C语言程序设计谭浩强 清华大学出版社C51单片机及应用系统设计徐煜明 电子工业出版社新概念51单片机C语言教程郭天祥 哈尔滨工业大学出版社十天学会单片机教程 郭天祥单片机原理及接口技术梅丽 清华大学出版社Altium designer 6 设计教程北京工业大学出版社Protues入门仿真与实例人民邮电出版社Altium Designer6.9 PCB设计教程郭天祥附录一完整原理图附录二系统源代码#include#include#define MK P3 /定义P3口为主控键#define KEY_PORT P2 、/矩阵键盘接口#define LCD_DATE P1/液晶接口sbit lcdrs=P32;sbit lcdrw=P31;sbit lcden=P30;unsigned char temp,temp1,tem,num;unsigned char STH0,STL0;sbit SPK =P00; 、/蜂鸣器unsigned char ni10=0,0,0,0;unsigned char code str0=WELCOME!;unsigned char code str1=lanhuacao;unsigned char code str2=Edlewaiss;unsigned char code str3=childhood;unsigned char code str4=DO RE MI FA SO LA SI;unsigned char code song55=6,10,10,10,10,10,9,8,9,8,7,6,6,13,13,13,13,13,13,12,3,12,12,11,10,10,10,13,13,12,10,10,9,8,9,8,7,6,6,3,3,8,8,7,6,6,10,9,8,7,5,13,13,-1, 8,9,10,8,8,9,10,8,10,11,12,10,11,12, 12,13,12,11,10,8,12,13,12,11,10,8,8,12,8,8,5,8,-1, 5,5,8,9,10,10,11,10,8,9,8,6,8,5,8,9,10,10,11,12,8, 11,11,10,12,9,10,10,9,9,10,12,14,14,14,13,13,12,12,13,14,13,12,10,-1;unsigned char code len55=1,1,1,1,2,1,1,1,1,1,2,2,1,1,1,1,1,2,1,1,1,1,1,1,2,2,1,1,1,1,2,1,1,1,1,1,1,2,1,1,1,1,1,1,2,1,1,1,1,1,1,2,2,-1, 2,2,2,2,2,2,2,2,2,2,4,2,2,4,1,1,1,1,2,2,1,1,1,1,2,2,2,2,4,2,2,4,-1, 2,2,2,2,2,1,1,2,2,4,2,2,8,4,2,2,2,1,1,2,2, 2,1,1,2,1,1,1,1,6,4,2,2,2,1,1,4,2,1,1,2,1,1,8,-1; 、/音符对应的T值表 unsigned int code tab=0,63628,63835,64021,64103,64260,64400,64524,64580,64684,64777,64820,64898,64968,65030,65058,65110,65157,65178,65217,65252,65283;void delay(unsigned int z) /延时zms unsigned int x,y;for(x=z;x0;x-)for(y=110;y0;y-); /TR0=0; void time0(void) interrupt 1 using 0 /定时器0中断 TH0=STH0; TL0=STL0; SPK=!SPK; unsigned char mkey() /检查主控制按钮,并返回按键值 unsigned char m1=0;MK=0xff;tem=MK;tem=tem&0xff;while(tem!=0xff)&(m1=0) delay(5); tem=MK; tem=tem&0xff; if(tem!=0xff) m1=1; return tem; void write_com(unsigned char com)lcdrs=0;/根据LCD1602的时序图在数据线不同的高低电平状态下写入数据,从而区分是命令还是数据LCD_DATE =com;delay(5);lcden=1;delay(5);lcden=0; /*函数名称: write_dat 函数参数:uchar dat函数功能: 向LCD芯片写入要显示的数据(dat)函数入口:uchar dat*/void write_dat(unsigned char dat)lcdrs=1;/根据LCD1602的时序图在数据线不同的高低电平状态下写入数据,从而区分是命令还是数据LCD_DATE =dat;delay(5);lcden=1;delay(5);lcden=0; /*函数名称:LCD1602_init 函数参数: 无函数功能: 初始化LCD1602,完成一系列的命令写入函数入口:无*/void LCD1602_init ()lcden=0;lcdrw=0;write_com(0x38);/初始化write_com(0x0f);/ 显示和开关设置write_com(0x06);/ 显示和开关设置write_com(0x01);/清屏write_com(0x80);/初始数据指针void gsh(unsigned char a) /显示歌曲名 unsigned int i; / LCD1602_init(); for(i=0;i9;i+) write_dat(ai); delay(2); / write_com(0x01);void ysh(unsigned char a) /显示音高 unsigned int i; / LCD1602_init(); write_com(0x80+0x40); for(i=0;ia;i+) write_dat(|); delay(8); /write_com(0x01);unsigned char keyscan(unsigned char offset) /扫描矩阵键盘,并加上偏移量实现音调的可调 LCD1602_init ();num=99; KEY_PORT=0x7f;/扫描第一行 temp=KEY_PORT; / 如果第一行有键按下,则值发生变化 temp=temp&0x0f; while(temp!=0x0f)/如何有键按下再扫描值,有键按下了temp值就不为0xf0了 delay(5) ; temp=KEY_PORT; /延迟5毫秒之后再扫描按键 temp=temp&0x0f; while(temp!=0x0f)/temp值真的发生变化则说明有键按下temp=KEY_PORT;switch(temp)case 0x77: num=0;break;case 0x7b: num=1;break;case 0x7d: num=2;break;case 0x7e : num=3;/对键赋值,定义用户想要的值break;num=(num+offset)%21;SPK=!SPK;STH0=tabnum/256;STL0=tabnum%256;TR0=1;while(temp!=0x0f)temp=KEY_PORT;temp=temp&0x0f; /松手检测,对temp赋新值,使跳出扫描循环 TR0=0;ysh(num+1); KEY_PORT=0xbf; /扫描第二行 temp=KEY_PORT; temp=temp&0x0f; while(temp!=0x0f)/如何有键按下再扫描值,有键按下了temp值就不为0xf0了 delay(5) ; temp=KEY_PORT; temp=temp&0x0f; while(temp!=0x0f)temp=KEY_PORT;switch(temp)case 0xb7: num=4;break;case 0xbb: num=5;break;case 0xbd: num=6;break;case 0xbe: num=7;/对键赋值,定义用户想要的值break;num=(num+offset)%21; SPK=!SPK;STH0=tabnum/256;STL0=tabnum%256;TR0=1;while(temp!=0x0f)temp=KEY_PORT;temp=temp&0x0f; /松手检测,对temp赋新值,使跳出扫描循环TR0=0;ysh(num+1); KEY_PORT=0xdf;/扫描第三行 temp=KEY_PORT; temp=temp&0x0f; while(temp!=0x0f)/如何有键按下再扫描值,有键按下了temp值就不为0xf0了 delay(5) ; temp=KEY_PORT; temp=temp&0x0f; while(temp!=0x0f)temp=KEY_PORT;switch(temp)case 0xd7 : num=8;break;case 0xdb : num=9;break;case 0xdd : num=10;break;case 0xde: num=11;/对键赋值,定义用户想要的值break;num=(num+offset)%21; SPK=!SPK;STH0=tabnum/256;STL0=tabnum%256;TR0=1;while(temp!=0x0f)temp=KEY_PORT;temp=temp&0x0f; /松手检测,对temp赋新值,使跳出扫描循环 TR0=0;ysh(num+1); KEY_PORT=0xef;/扫描第四行 temp=KEY_PORT; temp=temp&0x0f; while(temp!=0x0f)/如何有键按下再扫描值,有键按下了temp值就不为0xf0了 delay(5) ; temp=KEY_PORT; temp=temp&0x0f; while(temp!=0x0f)temp=KEY_PORT;switch(temp)case 0xe7 : num=12;break;case 0xeb: num=13;break;case 0xed : num=14;break;case 0xee: num=15;/对键赋值,定义用户想要的值break;num=(num+offset)%21;SPK=!SPK;STH0=tabnum/256;STL0=tabnum%256;TR0=1;while(temp!=0x0f)temp=KEY_PORT;temp=temp&0x0f; /松手检测,对temp赋新值,使跳出扫描循环 TR0=0;ysh(num+1); return num; unsigned char play() /弹奏音乐 unsigned char hi, i,t,m=0; while(m=0) hi=keyscan(8); if(hi!=99) nii=hi; i+; t=mkey();if(t!=0xff) m=1;return t; unsigned char fg(unsigned char k) /放第k首歌曲 unsigned char b, t,j=0,m=0;unsigned char *pe;LCD1602_init ();switch(k) case 0:gsh(str1); pe=str1;break; case 1:gsh(str2); pe=str2;break; case 2:gsh(str3);pe=str3;break;while(songkj!=-1) &(m=0) b=songkj ; STH0=(tabb)/256; STL0=(tabb)%256; TR0=1; LCD1602_init (); gsh(pe); write_com(0x80+0x40); ysh(b); delay(120*lenkj); TR0=0; t=mkey(); if(t!=0xff) m=1;KEY_PORT=0xfe;/扫描第一行temp=KEY_PORT; / 如果第一行有键按下,则值发生变化 temp=temp&0xf0; while(temp!=0xf0)&(m=0)/如何有键按下再扫描值,有键按下了temp值就不为0xf0了 delay(5) ; temp=KEY_PORT; /延迟5毫秒之后再扫描按键 temp=temp&0xf0; while(temp!=0xf0)&(m=0)/temp值真的发生变化则说明有键按下/temp=KEY_PORT; m=1;t=temp; j+;if(m!=1) t=0xf0;return t;unsigned char shxu() /顺序播放音乐 unsigned char p,q=0; p=fg(q); while(p=0xf0) &q3) q+; p=fg(q); return p;unsigned char danqu(unsigned char k) /单曲播放音乐 unsigned char p; p=fg(k); while(p=0xf0) p=fg(k); return p; unsigned char msong() /放音乐的主函数 unsigned char m=0,i=0;while(m=0) /temp=mkey(); /if(temp!=0xf0) /m=1; /else/ KEY_PORT=0xfe;/扫描第一行 temp=KEY_PORT; / 如果第一行有键按下,则值发生变化 temp=temp&0xf0; while(temp!=0xf0)&(m=0)/如何有键按下再扫描值,有键按下了temp值就不为0xf0了 delay(5) ; temp=KEY_PORT; /延迟5毫秒之后再扫描按键 temp=temp&0xf0; while(temp!=0xf0)&(m=0)/temp值真的发生变化则说明有键按下/temp=KEY_PORT;switch(temp) case 0xe0: tem=shxu();break;case 0xd0 :tem=danqu(0);break;case 0xb0 :tem=danqu(1);break;case 0x70: tem=danqu(2);break;if(tem=0xef)|(tem=0xdf)|(tem=0xbf)|(tem=0x7f) 、/检查有无主控制键按下 m=1; temp=tem;else temp=tem; return temp; 、/返回主键值 unsigned char upplay() /弹奏高音音乐 unsigned char t,m=0; while(m=0) keyscan(15);t=mkey();if(t!=0xff) m=1;return t; unsigned char lowplay() /低音弹奏音乐 unsigned char t,m=0; while(m=0) keyscan(1);t=mkey();if(t!=0xff) m=1;return t;unsigned char bf() /录音主程序 unsigned char t,li,i=0,m=0; unsigned char ti=No record!; while(m=0) t=mkey(); if(t!=0xff) m=1; else if(nii!=0) li=nii; STH0=tabli/256; STL0=tabli%256; TR0=1; delay(150); TR0=0; i=(i+1)%20; else gsh(ti); t=0xef;m=1; return t; void main()/主函数 unsigned char temp1; LCD1602_init() ; /1602初始化 TMOD=0x01; ET0=1; EA=1;/开中断 while(1) gsh(str0); MK=0xff; temp1=MK; temp1=temp1&0xff; while(temp1!=0xff)/检查有无主控制键按下 delay(5); temp1=MK; temp1=temp1&0xff; while(temp1!=0xff) switch(temp1) /进入各个子菜单执行 case 0xef:temp1=play();break;case 0xdf:temp1=msong();break;case 0xbf:temp1=upplay();break;case 0x7f:temp1=lowplay();break;case 0xf7:temp1= bf();break;default:break;
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!