基于51单片机的简易电子琴正确版
(完整版)基于51单片机的简易电子琴设计

(完整版)基于51单⽚机的简易电⼦琴设计基于51单⽚机的简易电⼦琴设计⼀.问题提出为什么选择简易电⼦琴设计?1.对于⾳乐的兴趣我们对⾳乐都有着浓厚的兴趣,喜欢听钢琴曲,如理查德·克莱德曼演奏的《思乡曲》《星空》《秋⽇的私语》等,⾳乐在我们的⽣活中扮演着很重要的⾓⾊。
有⼈曾说,喜欢⾳乐的⼈不会向恶。
以前不以为然,可是随着这些年来慢慢喜欢上阴郁,听了越来越多的钢琴曲之后,觉得这句话⾮常有道理。
⾳乐是⽤艺术家⽤⾳符记录世界,传达情感的⼀种艺术形式,⾳乐⾥有⼀种和谐之美,听⾳乐可以让⼈⼼情舒畅,与外界和谐统⼀。
⾳乐现在已经成为我⽣活中很重要的⼀部分,我们每周都会抽些时间去欣赏世界名曲,作为对精神的洗礼。
2.对于电⼦琴的好奇好奇是⼈的天性,⼈类对于⾃然的认识,对于科学的探索,⽆不始于好奇。
我们对电⼦琴如何实现其功能,如⾳⾊选择、声⾳强弱控制、节拍器、⾃动放⾳功能等等也很好奇,想通过学习单⽚机这个机会,深⼊了解电⼦琴的功能实现原理。
3.对于51单⽚机强⼤功能的信赖51单⽚机有基本特性:(1)⾯向控制的8位CPU和指令系统(2)4K字节的程序存储器(ROM或EPROM)(3)128字节的数据存储器(4)可编程的并⾏I/O⼝P0~P3,有32位双向输⼊/输出线(5)⼀个全双⼯串⾏⼝(6)两个16位定时器/计数器(7)五个中断源,两个优先级的中断结构(8)⼀个⽚内时钟振荡器和时钟电路(9)可以寻址64K字节的程序存储器和64K字节的外部数据存储器51单⽚机功能强⼤,性能⽇趋完善,在⼯业测控、智能仪器仪表、机电⼀体化产品、家电领域中应⽤⼴泛,因此基于51单⽚机设计简易的电⼦琴可⾏性⾮常⼤。
⼆.功能需求1.能够实现基本的琴键功能即每按下⼀个琴键,单⽚机能够检测到键盘的按键,并根据按键的位置,通过程序来控制,使蜂鸣器发出不同频率(⾳调)的声⾳,声⾳延迟⼀段时间,等到按键放开后,声⾳停⽌。
然后再继续扫描,看是否有键按下,如此循环下去,即可实现基本的琴键功能。
51单片机简易电子琴

51单片机简易电子琴因本人初学单片机程序过于简陋请见谅程序:#include<reg51.h>sbit P2_0=P2^0;sbit P1_0=P1^0;//sbit P3_0=P3^0;unsigned char temp;unsigned int tone1;unsigned int tone2;unsigned char yinfu[]={0xfb,0xe9, //Do0xfc,0x5c, //Re0xfc,0xc1, //Mi0xfc,0xef, //Fa0xfd,0x45, //So0xfd,0x92, //La0xfd,0xd0, //Si0xfd,0xee, //Do#0xfa,0x14, //So低0xfa,0xb9, //La低0xfb,0x4d, //Si低0x00,0x00 //音符之间的间隔,只要间隔时间小于65ms时,//喇叭不会发出声音,用作拍子之间的短暂停顿};void delay500us(void) //延时五百US{unsigned char a,b;for(b=71;b>0;b--)for(a=2;a>0;a--);}void anjian(void) 按键//按键扫描程序{P1=0xf0;temp=P1;if(temp!=0xf0) //按键扫描{delay500us(); //消抖动temp = P1;if(temp!=0xf0){P1=0xfe;temp=P1;if((temp&0xf0)!=0xf0) {switch(temp){case 0xbe:tone1=yinfu[15];tone2=yinfu[16];TR0=1;break;case 0xde:tone1=yinfu[14];tone2=yinfu[15];TR0=1;break;case 0xee:tone1=yinfu[12];tone2=yinfu[13];TR0=1;break;case 0x7e:break;default:break;}}P1=0xfd;temp=P1;if((temp&0xf0)!=0xf0) {switch(temp){case 0xbd:tone1=yinfu[10];tone2=yinfu[11];TR0=1;break;case 0xdd:tone1=yinfu[8];tone2=yinfu[9];TR0=1;break;case 0xed:tone1=yinfu[6];TR0=1;break;case 0x7d:break;default:break;}}P1=0xfb;temp=P1;if((temp&0xf0)!=0xf0) {switch(temp){case 0xbb:tone1=yinfu[4];tone2=yinfu[5];TR0=1;break;case 0xdb:tone1=yinfu[2];TR0=1;break;case 0xeb:tone1=yinfu[0];tone2=yinfu[1];TR0=1;break;case 0x7b:break;default:break;}}P1=0xf7;temp=P1;if((temp&0xf0)!=0xf0) {switch(temp){case 0xd7:break;case 0x77:break;case 0xb7:case 0xe7: //清零按键break;default:break;}}}}P1=0xf0;while(P1!=0xf0){while(P1!=0xf0);//等待放开按键// delay500us();}// P2_0=0;TR0=0; //关闭定时计数器0// P3_0=0;}void time0(void) {TMOD=0X01; P2_0=0;TH0=tone1;TL0=tone2;EA=1;ET0=1;TR0=0;}void main() {P2_0=0;P3_0=0;time0();while(1){anjian();//else//{//tone1=0xfc;//tone2=0x5c;//}}}void timer0(void) interrupt 1 using 1 //产生矩形波驱动蜂鸣器{static unsigned char f=1;if(f==1){f=0;P2_0=1;}else{f=1;P2_0=0;}TH0=tone1;TL0=tone2;}原理图:。
基于51单片机的简单电子琴代码

基于51单片机的简单电子琴代码#include <AT89X52.h>sbit P10=P1^0;//高音阶,红灯sbit P11=P1^1;//中音阶,黄灯sbit P12=P1^2;//低音阶,绿灯sbit P13=P1^3;//蜂鸣器控制端口sbit P31=P3^0;//低音阶按键行sbit P32=P3^1;//中音阶按键行sbit P33=P3^2;//高音阶按键行sbit P35=P3^4;//播放音乐按键unsigned int i,j,k=0,l=0;unsigned char count1=0xff,count0=0x50;/*********************************数码管码表(P0)***********************************/unsigned char Tab[]={0XBF,0X06,0X5B,0X4F,0X66,//数码管0~40X6D,0X7D,0X07,0X7F,0X6F,//数码管5~90X77,0X7C,0X39,0X5E,0X79,0X71,0X00};//数码管A~F/************************************音阶控制**************************************/music_data_high[]={0xf8,0xf9,0xfa,0xfa,0xfb,0xfb,0xfc,//数组0~6 低音0xfc,0xfc,0xfd,0xfd,0xfd,0xfd,0xfe,//数组7~13 中音0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xff};//数组14~20 高音music_data_low[]= {0xf3,0xb8,0x15,0xb9,0x4a,0xcf,0x0c,//数组0~6 低音0x44,0xac,0x09,0x34,0x82,0xc8,0x05,//数组7~13 中音0x4c,0x6d,0x94,0xad,0xd2,0xf3,0x02};//数组14~20 高音/******************************************************函数名:delayms*参数:n 延时毫秒数*功能:延时N毫秒*****************************************************/void delayms(unsigned char n){unsigned char a,b;for(a=100;a>0;a--)for(b=10*n;b>0;b--);}/******************************************************函数名:key_check*参数:无*功能:扫描按键并运行对应功能*****************************************************/void key_check(void){P2=0xff;P3=0xfe;if(P2!=0xff){ delayms(20);if(P2!=0xff){P10=1;P11=1;P12=0;switch(P2){case0xfe:EA=1;count1=0xf8;count0=0xf3;P0=Tab[1];delayms(50);bre ak;case0xfd:EA=1;count1=0xf9;count0=0xb8;P0=Tab[2];delayms(50);br eak;case0xfb:EA=1;count1=0xfa;count0=0x15;P0=Tab[3];delayms(50);bre ak;case0xf7:EA=1;count1=0xfa;count0=0xb9;P0=Tab[4];delayms(50);bre ak;case0xef:EA=1;count1=0xfb;count0=0x4a;P0=Tab[5];delayms(50);bre ak;case0xdf:EA=1;count1=0xfb;count0=0xcf;P0=Tab[6];delayms(50);bre ak;case0xbf:EA=1;count1=0xfc;count0=0x0c;P0=Tab[7];delayms(50);bre ak;defaule:break;}}}//else {EA=0;P13=1;}P2=0xff;P3=0xfd;if(P2!=0xff){ delayms(20);if(P2!=0xff){P10=1;P11=0;P12=1;switch(P2){case0xfe:EA=1;count1=0xfc;count0=0x79;P0=Tab[1];delayms(50);bre ak;case0xfd:EA=1;count1=0xfc;count0=0xbc;P0=Tab[2];delayms(50);bre ak;case0xfb:EA=1;count1=0xfd;count0=0x09;P0=Tab[3];delayms(50);br eak;case0xf7:EA=1;count1=0xfd;count0=0x44;P0=Tab[4];delayms(50);bre ak;case 0xef:EA=1;count1=0xfd;count0=0xa2;P0=Tab[5];delayms(50);break;case0xdf:EA=1;count1=0xfd;count0=0xd8;P0=Tab[6];delayms(50);br eak;case0xbf:EA=1;count1=0xfe;count0=0x05;P0=Tab[7];delayms(50);br eak;// defaule:break;}}}//else {EA=0;P13=1;}P2=0xff;P3=0xfb;if(P2!=0xff){ delayms(20);if(P2!=0xff){P10=0;P11=1;P12=1;switch(P2){case0xfe:EA=1;count1=0xfe;count0=0x4c;P0=Tab[1];delayms(50);bre ak;case0xfd:EA=1;count1=0xfe;count0=0x6d;P0=Tab[2];delayms(50);br eak;case0xfb:EA=1;count1=0xfe;count0=0x9f;P0=Tab[3];delayms(50);bre ak;case0xf7:EA=1;count1=0xfe;count0=0xad;P0=Tab[4];delayms(50);bre ak;case0xef:EA=1;count1=0xfe;count0=0xd2;P0=Tab[5];delayms(50);bre ak;case0xdf:EA=1;count1=0xfe;count0=0xf3;P0=Tab[6];delayms(50);bre ak;case0xbf:EA=1;count1=0xff;count0=0x02;P0=Tab[7];delayms(50);bre ak;// defaule:break;}}}if(P2==0xff) {EA=0;P13=1;}/******************************************************函数名:play_music*参数:无*功能:播放音乐*****************************************************/ void play_music(void){count1=music_data_high[0];count0=music_data_low[0]; EA=1;delayms(50);EA=0;delayms(5);}/******************************************************函数名:TIM0_init*参数:无*功能:定时器0初始化*****************************************************/ void TIM0_init(void){TMOD=0x01;TH0=count1;TL0=count0;EA=1;ET0=1;TR0=1;}void timer0(void) interrupt 1 using 0{TH0=count1;TL0=count0;P13=!P13;/***************************************************** *函数名:main*参数:无*功能:开跑程序*****************************************************/ void main(void){ P35=1;TIM0_init();//play_music();//while(1){ if(P35==0) {delayms(20);P35=1;play_music();} key_check();}}。
基于51单片机bluesky开发板的电子琴程序

#include<STC12C5A60S2.h>#include<LCD1602.h> //包含LCD1602的显示函数等#include<KEY_SCAN.h> //包含键值扫描函数,输出key_num#define FSCLK 11059200 //晶振频率sbit BEEP=P1^4; //蜂鸣器输出脚unsigned int fre[16]={100,200,300,400,500,600,700,800,900,1000,1100,1200,1300,1 400,1500,1600};//存好预定的频率值,可以设定任意想要的频率/********************************************************** ********************** 函数功能:延时函数,函数名Delay_ms() ** 函数说明:利用软件延时,占用CPU,经调试最小单位大约为1ms ** 入口参数:time:需要延时的时间,单位ms** 出口参数:无void Delay_ms(unsigned int time)unsigned int i,j;for(i = 0;i < time;i ++)for(j = 0;j < 930;j ++);** 函数功能:定时翻转跟蜂鸣器相连的引脚的电平,输出一定频率的脉冲信号** 函数说明:定时器0中断服务函数** 入口参数:无** 出口参数:无void time0() interrupt 1 //使用定时器0的工作方式2,定时器中断服务程序TH0 = (65536-FSCLK/(12*fre[piano]))/256; //每次中断,重新配置定时器的高8位TL0 = (65536-FSCLK/(12*fre[piano]))%256; //每次中断,程序配置定时器的低8位BEEP=!BEEP; //然后取反音乐输出,输出一个反电平} //短时间内多次取反则输出一定频率的脉冲/********************************************************** ********************** 函数功能:主函数** 入口参数:无** 出口参数:无void main()unsigned char piano=0,key=0; //初始值LCD_1602_Init(); //液晶显示前进行初始化TMOD = 0X01; //定时器使能TH0 = (65536-FSCLK/(12*fre[0]))/256; //配置定时器的高8位TL0 = (65536-FSCLK/(12*fre[0]))%256; //配置定时器的低8位ET0 = 1; //允许定时器0中断EA = 1; //打开总中断Write_1602_String("Welcome",0X80); //开机显示欢迎语:WelcomeWrite_1602_String("By 20192305007",0X80+0x40); //显示作者:20192305007Delay_ms(5000); //延时5s后开始进入正式程序LCD_1602_Init(); //液晶屏初始化Write_1602_String("Happy Play",0X80); //显示开始使用:Happy Playwhile(1){ //在这段函数中,不断扫描键值,每当键值不等于0时,说明有键被按下,//此时开始播放对应的音阶。
基于51单片机的简易电子琴设计

基于51单⽚机的简易电⼦琴设计基于51单⽚机的简易电⼦琴设计⼀、设计任务及要求1、在该简易电⼦琴设计中,设置8个按键,8个按键可以发出do、re、mi、fa、sol、la、si、Do 8个⾳阶。
2、设计三个拨码开关,三个拨码开关可以调节⾼⾳、中⾳、低⾳三个⾳调。
3、画出电路的总体⽅框图和电路原理图。
⼆、设计原理⾳乐由许多不同的⾳阶组成的,⽽每个⾳阶对应着不同的频率,这样,我们就可以利⽤不同的频率组合,构成我们想要的⾳乐。
简易电⼦琴是摁下拨码开关时,单⽚机AT89C51会发出声⾳,声⾳从P1.0端⼝经过LM386,经过放⼤以后传⼊喇叭。
声⾳主要是经过单⽚机4×4矩阵键盘的按键产⽣,这⾥只⽤到8个按键来产⽣⾼中低的8个⾳阶,来产⽣do re mi fa sol la si Do。
下⾯是计数初值:三、设计⽅案本次设计的电⼦琴主要是利⽤AT89C51单⽚机为核⼼控制元件,同时还包括键盘、拨码开关和扬声器等控制模块,由键盘选择⼋个⾳阶。
1、电路原理图的总体设计总体电路需要c51单⽚机⼀⽚,⾳乐按键及喇叭等外围电路,要进⾏⾳调控制和⾳频放⼤,设计好的电路图如下图所⽰:2、键盘控制模块的设计矩阵按键部分由8个轻触按键按照2⾏4列排列,连接到P3端⼝。
将⾏线所接的单⽚机的I/O⼝作为输出端,⽽列线所接的I/O,则作为输⼊。
⾏线输出是低电平,有健按下,则输⼊线就会被拉低,这样,通过读输⼊线的状态就可得知是否有键按下。
3、键盘消抖当⽤⼿按下⼀个键时,如图所⽰,往往按键在闭合位置和断开位置之间跳⼏下才稳定到闭合状态的情况;在释放⼀个键时,也回会出现类似的情况。
这就是抖动。
抖动的持续时间随键盘材料和操作员⽽异,不过通常总是不⼤于10ms。
⽤软件⽅法可以很容易地解决抖动问题,这就是通过延迟10ms来等待抖动消失,此后再读⼊键盘码。
⼀个单⽚机⼯作于12M晶振,它的时钟周期是1/12(微秒)。
它的⼀个机器周期是12*(1/12)也就是1微秒。
(完整word版)基于C51的电子琴

陕西国防工业职业技术学院单片机课程实训报告专业:班级:姓名:学号:指导老师:实训地点:成绩:一摘要介绍了用单片机实训微型电子琴的方法。
给出了电路、程序框图及程序。
本实训包括单片机学习的外设,如LED灯、独立键盘、矩阵键盘、蜂鸣器等。
关键词:单片机,电子琴,程序。
二实训要求实训一个简易电子琴。
(1)用喇叭发1、2、3、4、5、6、7、ⅰ。
(2)要求按下按键发声,松开延时一段时间停止。
(3)中间再按别的键则发另一音调的声音。
(4)键盘输入功能。
(5)按键同时对应指示灯点亮,按键结束,指示灯熄灭。
三方案实训1.音乐产生原理由于一首音乐是许多不同的音阶组成的,而每个音阶对应着不同的频率,这样我们就可以利用不同的频率的组合,即可构成我们所想要的音乐了,当然对于单片机来产生不同的频率非常方便,我们可以利用单片机的定时/计数器T0来产生这样方波频率信号,因此,我们只要把一首歌曲的音阶对应频率关系弄正确即可。
本次实训中单片机晶振为12MHZ,那么定时器的计数周期为1MHZ,假如选择工作方式1,那T值便为T=216--5﹡105/相应的频率,那么根据不同的频率计算出应该赋给定时器的计数值,列出不同音符与单片机计数T0相关的计数S6 中音la 68S7 中音xi 61S8 高音do 572.方案实训(1)方案一:采用CPLD外接扬声器、键盘、数码管等。
8个译码输出显示的数码管,以显示目标芯片的32 位输出信号,且8个发光管也能显示目标器件的8位输出信号。
时钟为50MHz ,输出接扬声器。
具体过程:主系统可由两个模块组成:当系统检测到有按键按下时,对应音符的频率由模块1获得,这是一个数控分频器。
由其clk端输入一具有较高频率的信号,分频后输出。
音符的持续时间须根据乐曲的速度及每个音符的节拍数决定,模块2的功能是为模块1提供决定所发音的分频预置值,而此数在模块1输入口停留的时间即为此音符的节拍值。
(2)方案二:采用单片机外接扬声器、键盘、数码管等。
基于51单片机学习板的简易电子琴__本科毕业设计论文

中国矿业大学徐海学院技能考核培训姓名:申鹏飞学 号: 22120768专业:信息12-2班题目:基于单片机的技能考核专题:简易的电子琴制作,数据收发指导教师:有鹏设计地点:电工电子实验室时间: 2015 年 6 月通信系统综合设计训练任务书学生姓名 申鹏飞 专业年级 信息12-2班 学号 22120768设计日期: 2015 年 6 月 20 日 至 2015 年7 月3日设计题目:设计专题题目:设计主要内容和要求:1. 主要内容:(1)系统硬件设计及说明)系统硬件设计及说明)系统硬件设计及说明(2)系统硬件设计及说明)单片机学习板主要功能介绍(3)单片机学习板主要功能介绍)系统软件设计(4)系统软件设计2. 功能扩展要求(1)2.4GHz射频收发芯片nRF2401及其应用及其应用)简易的电子琴制作的步骤和功能(2)简易的电子琴制作的步骤和功能指导教师签字:摘要:随着电子技术的发展,电子技术与音乐的结合不断加深。
由此而产生的电子琴在这种形势下,因其体积小,易于携带,经济适用,是一般家庭都能承受得了的经济投入。
而且电子琴键盘操作直观易于掌握。
子琴键盘操作直观易于掌握。
这样对初学者,这样对初学者,尤其对识谱的人来说是很容易弹奏的,尤其对识谱的人来说是很容易弹奏的,一首简一首简单的曲子灵感好的人甚至不用很多的练习和教师的指导就能很快的弹奏出来。
这样就强烈地激发了学习者的学习兴趣,迅速地提高了电子琴的普及率。
激发了学习者的学习兴趣,迅速地提高了电子琴的普及率。
关键词:关键词:5151单片机,电子琴单片机,电子琴 ,数据收发,数据收发目录第一章第一章 前言前言 .............................................. 6 1.1 系统开发背景系统开发背景 ...................................... 6 1.2 系统开发意义系统开发意义 ...................................... 6 第二章第二章 设计任务及要求设计任务及要求设计任务及要求 ................................... 7 第三章第三章 系统硬件设计及说明系统硬件设计及说明 ................................ 8 3.1系统组成及总体框图系统组成及总体框图 ................................. 8 第四章第四章 单片机学习板主要功能介绍单片机学习板主要功能介绍 .......................... 9 4.1AT89S52简介简介 ....................................... .......................................9 4.1.1功能特性:功能特性: ................................... 10 4.1.2主要性能主要性能..................................... ..................................... 11 4.1.3管脚说明管脚说明..................................... ..................................... 11 4.2 LED 数码管数码管 ....................................... ....................................... 12 4.3显示电路显示电路 ......................................... ......................................... 13 4.4键盘扫描模块电路图键盘扫描模块电路图 ................................ 13 4.5数码管显示模块电路原理图数码管显示模块电路原理图 .......................... 14 4.6电源模块电路原理图电源模块电路原理图 ............................... 15 第5章 系统软件设计系统软件设计 ..................................... 16 5.1音乐相关知识音乐相关知识...................................... ...................................... 16 5.2如何用单片机实现音乐的节拍如何用单片机实现音乐的节拍 ........................ 16 5.3如何用单片机产生音频脉冲如何用单片机产生音频脉冲 .......................... 16 5.4系统总体功能流程图系统总体功能流程图 (18)第六章2.4GHz 射频收发芯片nRF2401 模块介绍模块介绍 ............... 20 6.1芯片结构芯片结构 ......................................... ......................................... 21 6.2引脚说明引脚说明 ......................................... ......................................... 21 6.3工作模式工作模式 ......................................... .........................................23 6.3.1收发模式收发模式..................................... ..................................... 23 6.3.2直接收发模式直接收发模式 ................................. 24 6.3.3配置模式配置模式..................................... ..................................... 25 6.3.4空闲模式空闲模式..................................... ..................................... 25 6.3.5关机模式关机模式..................................... ..................................... 25 6.4.6.4.器件配置器件配置器件配置 ......................................... 25 6.5.6.5.应用电路应用电路应用电路 ......................................... 26 6.6无线音频系统无线音频系统...................................... ...................................... 27 第七章第七章 51 51单片机与NRF24L01模块融合模块融合 ..................... 28 第八章第八章 收获与总结收获与总结收获与总结 ...................................... 29 第九章第九章 参考文献参考文献 ......................................... 30 附录一附录一.................................................. 31 附录二附录二 .. (42)第一章 前言1.1 1.1 系统开发背景系统开发背景随着电子科技的飞速发展,电子技术正在逐渐改善着人们的学习、生活、工作,因此开发本系统希望能够给人们多带来一点生活上的乐趣。
基于51单片机的电子琴完整版

基于51单片机的电子琴完整版#include<reg52.h>#include <intrins.h>#define uint unsigned int#define uchar unsigned charsbit feng = P0^7; // 蜂鸣器uint FTemp;uint code tab[] = { //定时半周期的初始值64021,64103,64260,64400, //低音3 4 5 664524,64580,64684,64777, //低音7,中音1 2 364820,64898,64968,65030, //中音4 5 6 765058,65110,65157,65178}; //高音1 2 3 4//用扫描法读P1 外接4×4 键盘uchar Keyscan(void){uchar i, j, temp, Buffer[4] = {0xfe, 0xfd, 0xfb, 0xf7};for(j = 0; j < 4; j++) //循环四次,扫描四行{P1 = Buffer[j]; //在低四位分别输出一个低电平_nop_();temp = 0x80; //计划先读出P1.7位for(i = 0; i < 4; i++) //循环四次,检查四列{if(!(P1& temp)) //从高四位,截取1位{return (i + j * 4); //返回取得的按键值}temp >>= 1; //换右边一位}}return 16; //没有键按下就返回16}void Main(void){uchar Key_Value = 16, Key_Temp1, Key_Temp2;//读出的键值 TMOD = 0x01; //T0定时方式1ET0 = 1; //允许T0中断EX0 = 1; //允许INT0中断EA = 1;//开总中断while(1){TR0 = 0; //T0工作停,暂不发音Key_Temp1 = Keyscan(); //第一次读入按键if(Key_Temp1 != 16){ //有键按下Key_Temp2 = Keyscan(); //再读一次if (Key_Temp1 == Key_Temp2) //两次相等{Key_Value = Key_Temp1; //就确认下来FTemp = tab[Key_Value]; //根据键值,取出定时半周期的初始值TR0 = 1; //启动定时器T0,发音while (Keyscan() < 16); //等待释放feng = 1; //停止发音}}}}//========================================================= =====void T0_INT(void) interrupt 1{TL0 = FTemp; //载入定时半周期的初始值TH0 = FTemp >> 8;feng = ~feng; //发音。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
//简易电子琴#include<reg52.h> //包含51单片机寄存器定义的头文件sbit P14=P1^4; //将P14位定义为P1.4引脚sbit P15=P1^5; //将P15位定义为P1.5引脚sbit P16=P1^6; //将P16位定义为P1.6引脚sbit P17=P1^7; //将P17位定义为P1.7引脚unsigned char keyval; //定义变量储存按键值sbit sound=P3^6; //将sound位定义为P3.7unsigned int C; //全局变量,储存定时器的定时常数unsigned int f; //全局变量,储存音阶的频率//以下是C调低音的音频宏定义#define l_dao 262 //将“l_dao”宏定义为低音“1”的频率262Hz#define l_re 286 //将“l_re”宏定义为低音“2”的频率286Hz#define l_mi 311 //将“l_mi”宏定义为低音“3”的频率311Hz#define l_fa 349 //将“l_fa”宏定义为低音“4”的频率349Hz#define l_sao 392 //将“l_sao”宏定义为低音“5”的频率392Hz#define l_la 440 //将“l_a”宏定义为低音“6”的频率440Hz#define l_xi 494 //将“l_xi”宏定义为低音“7”的频率494Hz //以下是C调中音的音频宏定义#define dao 523 //将“dao”宏定义为中音“1”的频率523Hz#define re 587 //将“re”宏定义为中音“2”的频率587Hz#define mi 659 //将“mi”宏定义为中音“3”的频率659Hz#define fa 698 //将“fa”宏定义为中音“4”的频率698Hz#define sao 784 //将“sao”宏定义为中音“5”的频率784Hz#define la 880 //将“la”宏定义为中音“6”的频率880Hz#define xi 987 //将“xi”宏定义为中音“7”的频率53//以下是C调高音的音频宏定义#define h_dao 1046 //将“h_dao”宏定义为高音“1”的频率1046Hz #define h_re 1174 //将“h_re”宏定义为高音“2”的频率1174Hz #define h_mi 1318 //将“h_mi”宏定义为高音“3”的频率1318Hz#define h_fa 1396 //将“h_fa”宏定义为高音“4”的频率1396Hz #define h_sao 1567 //将“h_sao”宏定义为高音“5”的频率1567Hz #define h_la 1760 //将“h_la”宏定义为高音“6”的频率1760Hz #define h_xi 1975 //将“h_xi”宏定义为高音“7”的频率1975Hz /************************************************************** 函数功能:软件延时子程序**************************************************************/ void delay20ms(void){unsigned char i,j;for(i=0;i<100;i++)for(j=0;j<60;j++);}/*******************************************函数功能:节拍的延时的基本单位,延时200ms******************************************/void delay(){unsigned char i,j;for(i=0;i<250;i++)for(j=0;j<250;j++);}/*******************************************函数功能:输出音频入口参数:F******************************************/void Output_Sound(void){C=(46083/f)*10; //计算定时常数TH0=(8192-C)/32; //可证明这是13位计数器TH0高8位的赋初值方法TL0=(8192-C)%32; //可证明这是13位计数器TL0低5位的赋初值方法TR0=1; //开定时T0delay(); //延时200ms,播放音频TR0=0; //关闭定时器sound=1; //关闭蜂鸣器keyval=0xff; //播放按键音频后,将按键值更改,停止播放}/*******************************************函数功能:主函数******************************************/void main(void){EA=1; //开总中断ET0=1; //定时器T0中断允许ET1=1; //定时器T1中断允许TR1=1; //定时器T1启动,开始键盘扫描TMOD=0x10; //分别使用定时器T1的模式1,T0的模式0TH1=(65536-500)/256; //定时器T1的高8位赋初值TL1=(65536-500)%256; //定时器T1的高8位赋初值while(1) //无限循环{switch(keyval){case 1:f=dao; //如果第1个键按下,将中音1的频率赋给fOutput_Sound(); //转去计算定时常数break;case 2:f=l_xi; //如果第2个键按下,将低音7的频率赋给fOutput_Sound(); //转去计算定时常数case 3:f=l_la; //如果第3个键按下,将低音6的频率赋给f Output_Sound(); //转去计算定时常数break;case 4:f=l_sao; //如果第4个键按下,将低音5的频率赋给f Output_Sound(); //转去计算定时常数break;case 5:f=sao; //如果第5个键按下,将中音5的频率赋给f Output_Sound(); //转去计算定时常数break;case 6:f=fa; //如果第6个键按下,将中音4的频率赋给f Output_Sound(); //转去计算定时常数break;case 7:f=mi; //如果第7个键按下,将中音3的频率赋给f Output_Sound(); //转去计算定时常数break;case 8:f=re; //如果第8个键按下,将中音2的频率赋给f Output_Sound(); //转去计算定时常数break;case 9:f=h_re; //如果第9个键按下,将高音2的频率赋给f Output_Sound(); //转去计算定时常数break;case 10:f=h_dao; //如果第10个键按下,将高音1的频率赋给f Output_Sound(); //转去计算定时常数break;case 11:f=xi; //如果第11个键按下,将中音7的频率赋给f Output_Sound(); //转去计算定时常数break;case 12:f=la; //如果第12个键按下,将中音6的频率赋给f Output_Sound(); //转去计算定时常数case 13:f=h_la; //如果第13个键按下,将高音6的频率赋给fOutput_Sound(); //转去计算定时常数break;case 14:f=h_sao; //如果第14个键按下,将高音5的频率赋给fOutput_Sound(); //转去计算定时常数break;case 15:f=h_fa; //如果第15个键按下,将高音4的频率赋给fOutput_Sound(); //转去计算定时常数break;case 16:f=h_mi; //如果第16个键按下,将高音3的频率赋给fOutput_Sound(); //转去计算定时常数break;}}}/**************************************************************函数功能:定时器T0的中断服务子程序,使P3.7引脚输出音频方波**************************************************************/void Time0_serve(void ) interrupt 1 using 1{TH0=(8192-C)/32; //可证明这是13位计数器TH0高8位的赋初值方法TL0=(8192-C)%32; //可证明这是13位计数器TL0低5位的赋初值方法sound=!sound; //将P3.7引脚取反,输出音频方波}/**************************************************************函数功能:定时器T1的中断服务子程序,进行键盘扫描,判断键位**************************************************************/void time1_serve(void) interrupt 3 using 2 //定时器T1的中断编号为3,使用第2组寄存器{TR1=0; //关闭定时器T0P1=0xf0; //所有行线置为低电平“0”,所有列线置为高电平“1”if((P1&0xf0)!=0xf0) //列线中有一位为低电平“0”,说明有键按下{delay20ms(); //延时一段时间、软件消抖if((P1&0xf0)!=0xf0) //确实有键按下{P1=0xfe; //第一行置为低电平“0”(P1.0输出低电平“0”)if(P14==0) //如果检测到接P1.4引脚的列线为低电平“0”keyval=1; //可判断是S1键被按下if(P15==0) //如果检测到接P1.5引脚的列线为低电平“0”keyval=2; //可判断是S2键被按下if(P16==0) //如果检测到接P1.6引脚的列线为低电平“0”keyval=3; //可判断是S3键被按下if(P17==0) //如果检测到接P1.7引脚的列线为低电平“0”keyval=4; //可判断是S4键被按下P1=0xfd; //第二行置为低电平“0”(P1.1输出低电平“0”)if(P14==0) //如果检测到接P1.4引脚的列线为低电平“0”keyval=5; //可判断是S5键被按下if(P15==0) //如果检测到接P1.5引脚的列线为低电平“0”keyval=6; //可判断是S6键被按下if(P16==0) //如果检测到接P1.6引脚的列线为低电平“0”keyval=7; //可判断是S7键被按下if(P17==0) //如果检测到接P1.7引脚的列线为低电平“0”keyval=8; //可判断是S8键被按下P1=0xfb; //第三行置为低电平“0”(P1.2输出低电平“0”)if(P14==0) //如果检测到接P1.4引脚的列线为低电平“0”keyval=9; //可判断是S9键被按下if(P15==0) //如果检测到接P1.5引脚的列线为低电平“0”keyval=10; //可判断是S10键被按下if(P16==0) //如果检测到接P1.6引脚的列线为低电平“0”keyval=11; //可判断是S11键被按下if(P17==0) //如果检测到接P1.7引脚的列线为低电平“0”keyval=12; //可判断是S12键被按下P1=0xf7; //第四行置为低电平“0”(P1.3输出低电平“0”)if(P14==0) //如果检测到接P1.4引脚的列线为低电平“0”keyval=13; //可判断是S13键被按下if(P15==0) //如果检测到接P1.5引脚的列线为低电平“0”keyval=14; //可判断是S14键被按下if(P16==0) //如果检测到接P1.6引脚的列线为低电平“0”keyval=15; //可判断是S15键被按下if(P17==0) //如果检测到接P1.7引脚的列线为低电平“0”keyval=16; //可判断是S16键被按下}}TR1=1; //开启定时器T1TH1=(65536-500)/256; //定时器T1的高8位赋初值TL1=(65536-500)%256; //定时器T1的高8位赋初值}。