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单片机电子琴程序

#include<reg51.h>#include<absacc.h>#include<stdio.h>#include<math.h>#define uchar unsigned char#define uint unsigned intuchar STH0; //定时器计数初值uchar STL0;bit FY=0; //放乐曲时FY=1,电子琴弹奏时FY=0uchar Song_Index=0,Tone_Index=0; //放音乐的参数uchar k,key;sbit SPK=P3^7;sbit LED1=P1^0;sbit LED2=P1^1;uchar code DSY_CODE[]={0x3f,0x06,0x5b,0x4f,0x66,0x6f,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79 ,0x71};uchar code Song[][50]={{1,2,3,5,7,8,4,3,4,3,4,5,4,6,3,4,5},{5,5,3,5,4,2,4,5,7,4,2,10,10,10,2,1,2,1,2,10,10},{5,5,10,9,8,5,5,5,5,10,9,8,6,6,6,11,12,9,6,8-1},{13,14,13,12,12,10,12,13,14,15,14,14},{6,6,11,10,9,12,12,12,12,13,12,11,9,8,10,10,10,-1},{9,13,13,13,13,8,13,13,13,13,14,15,14,13,13,14,12,13},};uchar code Len[][50]={{1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,1,1,1,2,2,2,1,2,2,1,2,2},{1,1,1,1,1,1,2,1,1,1,2,2,1,1,1,1,-1},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,-1},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,-1},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,-1},{1,1,2,0,1,1,2,0,1,1,1,1,1,1,1,1,1,1,1},{1,1,1,1,1,1,1,1,2,0,1,2,1,2,1,2,1,2,1,2},{2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,-1},}; //音符与计数值对应表uint 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 delay1(uint ms) //播放歌曲时实现节拍的延时函数{uchar t;while(ms--) for(t=0;t<120;t++);}//键消抖延时函数void delay(void){uchar i;for(i=300;i>0;i--);}//键扫描函数uchar getkey(void){uchar scancode,tmpcode;if((P0&0xf0)==0xf0)return(0);scancode=0xfe;while((scancode&0x10)!=0){P0=scancode; //输入行扫描码if((P0&0xf0)!=0xf0) //本行有键按下{tmpcode=(P0&0xf0)|0x0f;return((~scancode)+~(tmpcode));}else scancode=(scancode<<1)|0x01;}}//外部中断0void EX0_INT() interrupt 0{FY=0;LED1=1;LED2=0;}//外部中断1,这里是播放按键void EX1_INT() interrupt 2{FY=1;LED1=0;LED2=1;}//定时器0中断服务子程序void time0_int(void) interrupt 1 using 0{TH0=STH0;TL0=STL0;SPK=!SPK;P2=DSY_CODE[k];void main(void){LED1=1;LED2=0;P2=0x3f;IE=0x87;TMOD=0x01;IT0=1;IT1=1;while(1){P0=0xf0;if((P0&0xf0)!=0xf0){delay();if((P0=0xf0)!=0xf0){key=getkey();switch(key){case 0x11:k=0;break;case 0x21:k=1;break;case 0x41:k=2;break;case 0x81:k=3;break;case 0x12:k=4;break;case 0x22:k=5;break;case 0x42:k=6;break;case 0x82:k=7;break;case 0x14:k=8;break;case 0x24:k=9;break;case 0x44:k=10;break;case 0x84:k=11;break;case 0x18:k=12;break;case 0x28:k=13;break;case 0x48:k=14;break;case 0x88:k=15;break;default:break;}if(FY==0){STH0=tab[k]/256;STL0=tab[k]%256;TR0=1;while((P0&0xf0)!=0xf0);TR0=0;}else{while(FY==1){if(Song[k][Tone_Index]==-1)Tone_Index=0;STH0=(tab[Song[k][Tone_Index]])/256;STL0=(tab[Song[k][Tone_Index]])%256;P2=DSY_CODE[Song[k][Tone_Index]];TR0=1;delay1(300*Len[k][Tone_Index]);Tone_Index++;TR0=0;}}}}}}关于“世上只有妈妈好”的单片机音乐演奏程序2009-11-22 21:45单片机演奏一个音符,是通过引脚,周期性的输出一个特定频率的方波。
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单片机设计电子琴报告含代码

电子琴设计报告一、实验目的1.更深刻的了解、学习8051单片机的发声原理,利用定时器可以发出不同频率的脉冲,不同频率的脉冲经喇叭驱动电路放大滤波后,就会发出不同的音调。
2.其次,定时器按设置的定时参数产生中断,这一次中断发出脉冲低电平,下一次反转发出脉冲高电平,由于定时参数不同,所以发出不同频率的脉冲。
3.进一步熟悉定时器的编程方法和定时初值的计算,进一步熟悉键盘扫描电路的工作原理和编程方法,了解单片机芯片的接口技术。
二、实验要求1.能够通过键盘演奏音符。
2.能够保存演奏的音乐,并实现回放。
3.有音调调整功能(如:C调,G调)。
4.自由发挥其他功能。
5.要求有单片机硬件系统框图,电路原理图,软件流程图。
三、实验基本原理简易电子琴有主控、蜂鸣器、键盘输入、电源四部分组成。
主控部分以AT89S52 为核心,用C 语言编程,充分运用AT89S52 的8k字节闪烁可编程可擦除只读存储器及其丰富的I/O 口,实现了对键盘数据的采集,和对蜂鸣器声音的控制;键盘输入部分采用4×4的键盘键盘输入,可以实现多个音调;供电部分可对整个电路进行供电。
经测试,整机基本实现预计功能,可以实现键盘演奏音符、调整音调、保存并回放的功能。
四、实验设计分析根据实验所要求实现的功能设计实现该项实验设计的软件电路及硬件电路。
五、实验要求实现A.电路设计1. 整体设计计划利用AT89S52 单片机的功能结合C 语言编程,实现电子琴播放音符等的简单功能,然后结合AT89S52 单片机的控制功能,利用蜂鸣器将输入表达出来,结合程序编制过程中,对各个I/O 的利用设置了键盘的扫描读入,结合电子琴需要多键位的现实,加入了4×4 键盘输入,达到了预期的效果。
2.分块设计1.控制模块AT89S52单片机是美国ATMEL公司生产的低功耗,高性能CMOS 8位单片机,片内含有8kb的可系统编程的Flash只读程序存储器,器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准8051指令系统及引脚。
简易电子琴单片机c51程序

#include "reg51.h"void tinit(void);void delay_ms(unsigned int);sbit P27=P2^7;sbit P26=P2^6;sbit P25=P2^5;unsigned char code Music_Code[]={0xf8,0x8b,0xf9,0x5b,0xfa,0x14,0xfa,0x66,0xfb,0x03,0xfb,0x8f,0xfc,0x0b,0xfb,0xee} ;unsigned char const yinful[3][14]={0xf8,0x8b,0xf9,0x5b,0xfa,0x14,0xfa,0x66,0xfb,0x03,0xfb,0x8f,0xfc,0x0b, 0xfc,0x43,0xfc,0xab,0xfd,0x08,0xfd,0x33,0xfd,0x81,0xfd,0xc7,0xfe,0x05, 0xfb,0x21,0xfe,0x55,0xfe,0x84,0xfe,0x99,0xfe,0xc0,0xfe,0xe3,0xff,0x02 } ;unsigned char const length[]={1,2,4,8,16,32,64};unsigned char sth,stl;void main(void){unsigned char j;unsigned int i;tinit();while(1){switch(P1){case 0xfe: delay_ms(10);if(P1==0xfe){i=0;TR0=0;sth=Music_Code[2*i];stl=Music_Code[2*i+1];TR0=1;for(j=0;j<=100;j++){delay_ms(10);if(P1==0xfe)continue;else break;}TR0=0;for(;;){while(P1==0xfe)delay_ms(10);if(P1==0xfe) continue;else break;}}TR0=0;break;case 0xfd: delay_ms(10);if(P1==0xfd){i=1;TR0=0;sth=Music_Code[2*i];stl=Music_Code[2*i+1];TR0=1;for(j=0;j<=100;j++){delay_ms(10);if(P1==0xfd)continue;else break;}TR0=0;for(;;){while(P1==0xfd)delay_ms(10);if(P1==0xfd) continue;else break;}}TR0=0;break;case 0xfb: delay_ms(10);if(P1==0xfb){i=2;TR0=0;sth=Music_Code[2*i];stl=Music_Code[2*i+1];TR0=1;for(j=0;j<=100;j++){delay_ms(10);if(P1==0xfb)continue;else break;}TR0=0;for(;;){while(P1==0xfb)delay_ms(10);if(P1==0xfb) continue;else break;}}TR0=0;break;case 0xf7: delay_ms(10) ;if(P1==0xf7){i=3;TR0=0;sth=Music_Code[2*i];stl=Music_Code[2*i+1];TR0=1;for(j=0;j<=100;j++){delay_ms(10);if(P1==0xf7)continue;else break;}TR0=0;for(;;){while(P1==0xf7)delay_ms(10);if(P1==0xf7) continue;else break;}}TR0=0;break;case 0xef: delay_ms(10);if(P1==0xef){i=4;TR0=0;sth=Music_Code[2*i];stl=Music_Code[2*i+1];TR0=1;for(j=0;j<=100;j++){delay_ms(10);if(P1==0xef)continue;else break;}TR0=0;for(;;){while(P1==0xef)delay_ms(10);if(P1==0xef) continue;else break;}}TR0=0;break;case 0xdf: delay_ms(10);if(P1==0xdf){i=5;TR0=0;sth=Music_Code[2*i];stl=Music_Code[2*i+1];TR0=1;for(j=0;j<=100;j++){delay_ms(10);if(P1==0xdf)continue;else break;}TR0=0;for(;;){while(P1==0xdf)delay_ms(10);if(P1==0xdf) continue;else break;}}TR0=0;break;case 0xbf: delay_ms(10);if(P1==0xbf){i=6;TR0=0;sth=Music_Code[2*i];stl=Music_Code[2*i+1];TR0=1;for(j=0;j<=100;j++){delay_ms(10);if(P1==0xbf)continue;else break;}TR0=0;for(;;){while(P1==0xbf)delay_ms(10);if(P1==0xbf) continue;else break;}}TR0=0;break;case 0x7f: delay_ms(10);if(P1==0x7f){i=7;TR0=0;sth=Music_Code[2*i];stl=Music_Code[2*i+1];TR0=1;for(j=0;j<=100;j++){delay_ms(10);if(P1==0x7f)continue;else break;}TR0=0;for(;;){while(P1==0x7f)delay_ms(10);if(P1==0x7f) continue;else break;}}TR0=0;break;default: break;}}}void delay_ms(unsigned int k){unsigned int i0;unsigned char i,j;for(i0=0;i0<k;i0++){for(i0=0;i0<k;i0++)for(i=5;i>0;i--)for(j=97;j>0;j--);}}void tinit(void){TMOD=0x01;TH0=sth;TL0=stl;ET0=1;EA=1;TR0=0;}void t0(void) interrupt 1 {TR0=0;TH0=sth;TL0=stl;P27=!P27;TR0=1;}。
简易电子琴设计方案51单片机

简易电子琴(51单片机)目录简易电子琴(51单片机) (1)目录 (1)摘要 (1)ABSTRACT (1)引言 (1)1 方案论证 (1)1.1原理图 (1)1.2系统板硬件连线 (1)1.3 主要芯片简介 (2)1.3.1 AT89S51简介 (2)1.3.2 LM386 (4)图1-3 LM386内部电路原理图 (4)Fig1-3 LM386 internal circuit diagram (4)1.3.3 LED数码管 (5)2 实现过程 (6)2.1 4X4行列式键盘识别及显示 (6)2.1.1 系统板上硬件连线设计 (7)2.1.2 程序设计内容(1)4×4矩阵键盘识别处理,每个按键有它的行值和列值,行值和列值的组合就是识别这个按键的编码。
矩阵的行线和列线分别通过两并行接口和CPU通信。
每个按键的状态同样需变成数字量“0”和“1”,开关的一端(列线)通过电阻接VCC,而接地是通过程序输出数字“0”实现的。
(8)图2.1.1 行列式键盘电路 (8)Figure 2.1.1 determinant keyboard circuit (8)摘要随着社会的发展进步,音乐逐渐成为我们生活中很重要的一部分,有人曾说喜欢音乐的人不会向恶。
我们都会抽空欣赏世界名曲,作为对精神的洗礼。
本论文设计一个基于单片机的简易电子琴。
我们对于电子琴如何实现其功能,如音色选择、声音强弱控制、节拍器、自动放音功能等等也很好奇。
电子琴是现代电子科技与音乐结合的产物,是一种新型的键盘乐器。
它在现代音乐扮演着重要的角色,单片机具有强大的控制功能和灵活的编程实现特性,它已经溶入现代人们的生活中,成为不可替代的一部分。
本文的主要内容是用AT89S51单片机为核心控制元件,设计一个电子琴。
以单片机作为主控核心,与键盘、扬声器等模块组成核心主控制模块,在主控模块上设有16个按键和扬声器。
本系统运行稳定,其优点是硬件电路简单,软件功能完善,控制系统可靠,性价比较高等,具有一定的实用和参考价值。
51单片机电子琴,支持弹奏14音、播放21音、支持重放弹奏曲目、支持节拍显示和音调显示

矩阵按键分布:K0 K1 K2 K3K4 K5 K6 K7K8 K9 K10 K11K12 K13 K14 K15按键功能介绍:弹奏模式下:K0:录制按键。
按下后,开始录制接下来弹奏的歌曲,再次按下录制结束。
按右下角的播放按键,播放刚才弹奏的歌曲。
K1~K3:低5音~低7音K4:0音K5~K11:中1音~中7音K12~K15 :高1音~高4音。
播放模式下:K12:上一首歌曲K13:暂停、再次播放K14:下一首歌曲K15:播放模式时功能是,退出播放程序:#include <reg52.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned int#define PSMG P0 //数码管IO口#define PKEY P1 //定义4x4按键接的IO 口行扫描#define PLED P2 //LED接的IO口sbit PLAY = P3^1;sbit SPK = P3^0;#define ALLSONG 3 //歌曲总数按实际写#define CODEMAX 30 //最大音符数uchar tone_h;uchar tone_l;uchar t1_flag = 0; //用于记录定时器1进入中断的次数uchar PressTime = 0; //按键按下的时间(节拍)uchar code chuzhi[3][16]={ //音调对应的计数初值0xff,0xff, //用任意值占0位,因为音调从1开始0xf8,0x8c,//低10xf9,0x5b,// 20xfa,0x15,// 30xfa,0x67,// 40xfb,0x04,// 50xfb,0x90,// 60xfc,0x0c,//低70xff,0xff,//占0位0xfc,0x44,//中10xfc,0xac,// 20xfd,0x09,// 30xfd,0x34,// 40xfd,0x82,// 50xfd,0xc8,// 60xfe,0x06,//中70xff,0xff,//占0位0xfe,0x22,//高10xfe,0x56,// 20xfe,0x85,// 30xfe,0x9a,// 40xfe,0xc1,// 50xfe,0xe4,// 60xff,0x03 //高7};//共阴数码管段码表uchar code YDTAB[23]={0x00, //各段全灭【0】0x77,0x7c,0x39,0x5e,0x79,0x71,0x3d, //a -g 【1~7】0x3f, //0【8】0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, //1 -7 【9~15】0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87 //1. -7. 【16~22】};//发光二极管闪烁表uchar code LEDTAB[9]={0xff,0x7f,0x3f,0x1f,0x0f,0x07,0x03,0x01,0x00};//****** 生日快乐 ******uint code srkl[] = {205,205,406,405,411,807,205,205,406,405,412,811,205,205,415,413,411,407,406,314,114,413,411,413,812,305,105,406,405,411,807,305,105,406,405,412,811,305,105,415,413,411,407,406,314,114,413,411,412,811,410,0xffff};//*******恋曲1990*******uint code lq1990[] = {613,213,412,411,613,213,412,411,613,213,412,411,1213, 110,//前奏215,215,215,215,413,412, //乌溜溜的黑眼珠613,211,211,212,413,1206, //和你的笑脸212,213,212,213,415,213,212, //怎么也难忘记612,211,211,206,405,1213,110, //你容颜的转变215,215,215,215,213,212, //轻飘飘的旧时613,211,211,212,213,1206, //光就这么溜走212,213,212,213,415,213,212, //转头回去看看612,205,213,212,413,1211,110, //时已匆匆数年215,215,215,215,413,412, //苍茫茫的天涯613,211,211,212,413,1206, //路是你的漂泊212,213,212,213,415,213,212, //寻寻觅觅长相612,211,211,206,405,1213,110, //守是我的脚步215,215,215,215,213,212, //黑漆漆的孤枕613,211,211,212,213,1206, //边是你的温柔212,213,212,213,415,213,212, //醒来时的清晨612,205,213,212,413,1211,110, //里是我的哀愁215,215,215,215,413,412, //轰隆隆的雷雨613,211,211,212,413,1206, //声在我的窗前212,213,212,213,415,213,212, //怎么也难忘记612,211,211,206,405,1213,110, //你离去的转变215,215,215,215,213,212, //孤单单的身影613,211,211,212,213,1206, //后寂寥的心情212,213,212,213,415,213,212, //永远无怨612,205,213,212,413,1211,110, //的是我的双眼615,213,415,416, //或许明日621,216,421,416, //太阳西下415,415,415,416,1213, //倦鸟已归时212,213,212,213,415,413, //你将已经踏上612,211,411,413,1212,210, //旧时的归途613,213,412,413, //人生难得615,213,415,416, //再次寻觅421,421,421,422,1216, //相知的伴侣221,221,221,221,416,415, //生命终究难舍212,412,212,412,413,1215,1610, 1610, //蓝蓝的白云天0xFFFF,};//==========================//粗略延时函数//==========================void delayms(uint ms)//延时?个 ms{uchar a,b,c;while(ms--){for(c=1;c>0;c--)for(b=142;b>0;b--)for(a=2;a>0;a--);}}//======================//定时器1 测量按键持续的节拍数//======================void Timer1_Init(void){EA = 1;ET1 = 1;TMOD &= 0x0F;TMOD |= 0x10;TH1 = (65536-25000)/256;TL1 = (65536-25000)%256; //25ms中断一次}void timer1() interrupt 3{TH1 = (65536-25000)/256;TL1 = (65536-25000)%256; //25ms中断一次t1_flag++;if(t1_flag == 5) //125ms{t1_flag = 0;if(PressTime < 16) //最多16 即最长4秒PressTime++;//8个LED显示节拍if(PressTime <= 8)PLED = LEDTAB[PressTime];else PLED = LEDTAB[8];}}//======================//按键扫描函数【行扫描】//低4位接行,高4位接列/*键值分布0 1 2 34 5 6 78 9 10 1112 13 14 15*///====================== uchar keyScan(void){uchar hang;uchar key;uchar temp;for(hang = 0;hang < 4;hang++){PKEY = ~(1<<hang);temp = PKEY&0xF0; //取高4位的值temp >>= 4; //将高四位右移到低四位if(temp != 0x0F) //有按键按下{switch(temp){case 14: key = 4*hang+0;break; //temp:1110 case 13: key = 4*hang+1;break; //temp:1101 case 11: key = 4*hang+2;break; //temp:1011case 7: key =4*hang+3;break; //temp:0111}break; //有键按下,获取键值后,终止扫描}else //没有按键按下返回255key = 255;}return key;}//======================//节拍延时//======================void delay125ms(uint pai) //延时?*125ms 即?个节拍{uchar a,b,c;while(pai--){for(c=239;c>0;c--)for(b=104;b>0;b--)继续阅读。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
} P3=0xff; P37=0; temp=P3; temp=temp&0x0f; if(temp!=0x0f) {
for(i=50;i>0;i--) for(j=200;j>0;j--);
temp=P3; temp=temp & 0x0f; if(temp!=0x0f) {
temp=P3; temp=temp&0x0f; switch(temp) { case 0x0e:
0xF2,0xF3,0xF5,0xF5,0xF6,0xF7,0xF8,
0xF9,0xF9,0xFA,0xFA,0xFB,0xF3,4,5,6,7,8,i
0xFC,0xFD,0xFD,0xFD,0xFD,0xFE,
0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFF,
key=8; break; case 0x0d: key=9; break; case 0x0b: key=10; break; case 0x07: key=11; break; } speaker=~speaker; STH1=tab[key]/256; STL1=tab[key]%256; TR0=1; temp=P3; temp=temp & 0x0f; while(temp!=0x0f) { temp=P3; temp=temp & 0x0f; } TR0=0; }
temp=P3; temp=temp&0x0f; switch(temp) { case 0x0e:
key=0; break; case 0x0d: key=1; break; case 0x0b: key=2; break; case 0x07: key=3; break; } speaker=~speaker; STH1=tab[key]/256; STL1=tab[key]%256; TR0=1; temp=P3; temp=temp & 0x0f; while(temp!=0x0f) { temp=P3; temp=temp & 0x0f; }
} void timer0(void) interrupt 1 using 0 { if(sw==1)
{ TH0=STH1; TL0=STL1;} else { TH0=STH0; TL0=STL0;} speaker=!speaker; } void delay(unsigned char t) { unsigned char t1; unsigned long t2; for(t1=0;t1<t;t1++) { for(t2=0;t2<8000;t2++) { ; } } TR0=0; } void song() { TH0=STH0; TL0=STL0; TR0=1; delay(time); } void music(void) { m=0; time=1; sw=1; while(time&&sw==0) { if(sw) {i=0;continue;} else {
51单片机简易电子琴程序
2009-04-16 19:59
感谢网上的诸多前辈,小弟我将这个程序写了出来。这个简易电子琴应用了4*4矩阵键盘,每
一个按键赋予了不同的音调,共计有两个八度。并预存了一首乐曲《世上只有妈妈好》。(附
有 protues 仿真图)
#include<reg51.h>
#define uchar unsigned char
k=sszymmh[m]+7*sszymmh[m+1]-1; STH0=FREQH[k]; STL0=FREQL[k]; time=sszymmh[m+2]; m=m+3; song(); } } } void main() { TMOD=0x01; ET0=1; EA=1; while(1) { if(sw==1)key_music(); else music(); } }
5,2,1,
3,2,1, 2,2,4,
2,2,3, 3,2,1, 5,2,2,
5,2,1,
6,2,1,
3,2,2, 2,2,2,
1,2,4, 5,2,3, 3,2,1,
2,2,1,
1,2,1,
6,1,1, 1,2,1,
5,1,6, 0,0,0
};
// 音阶频率表 高八位
code unsigned char FREQH[]={
#define uint unsigned int
uint key,i,j,time,m,k;
uchar temp;
uchar STH0,STL0,STH1,STL1;
sbit sw=P2^7;
sbit speaker=P2^4;
sbit P37=P3^7;
sbit P36=P3^6;
sbit P35=P3^5;
0x47,0x77,0xA2,0xB6,0xDA,0xFA,0x16,
};
unsigned int code tab[]={64021,64103,64260,64400, 64524,64580,64684,64777, 64820,64898,64968,65030, 65058,65110,65157,65178};
} } P3=0xff; P36=0; temp=P3; temp=temp&0x0f; if(temp!=0x0f) {
for(i=50;i>0;i--) for(j=200;j>0;j--);
temp=P3; temp=temp&0x0f; if(temp!=0x0f) {
temp=P3; temp=temp&0x0f; switch(temp) { case 0x0e:
TR0=0; } } P3=0xff; P35=0; temp=P3; temp=temp&0x0f; if(temp!=0x0f) { for(i=50;i>0;i--)
for(j=200;j>0;j--); temp=P3; temp=temp&0x0f; if(temp!=0x0f) {
temp=P3; temp=temp&0x0f; switch(temp) { case 0x0e:
void key_music() {
P3=0xff; P34=0; temp=P3; temp=temp&0x0f; if(temp!=0x0f) {
for(i=50;i>0;i--) for(j=200;j>0;j--);
temp=P3; temp=temp&0x0f; if(temp!=0x0f) {
key=4; break; case 0x0d: key=5; break; case 0x0b: key=6; break; case 0x07: key=7; break; } speaker=~speaker; STH1=tab[key]/256; STL1=tab[key]%256; TR0=1; temp=P3; temp=temp & 0x0f; while(temp!=0x0f) { temp=P3; temp=temp & 0x0f; } TR0=0;
sbit P34=P3^4;
//世上只有妈妈好数据表
code unsigned char sszymmh[]={ 6,2,3,
5,2,1,
3,2,2, 5,2,2, 1,3,2,
6,2,1, 5,2,1,
6,2,4,
3,2,2,
5,2,1, 6,2,1,
5,2,2, 3,2,2, 1,2,1,
6,1,1,
};
// 音阶频率表 低八位
code unsigned char FREQL[]={
0x42,0xC1,0x17,0xB6,0xD0,0xD1,0xB6,
0x21,0xE1,0x8C,0xD8,0x68,0xE9,0x5B,0x8F, //1,2,3,4,5,6,7,8,i
0xEE,0x44, 0x6B,0xB4,0xF4,0x2D,