公告:

基于51单片机制作(触摸)简易电子琴

作者:智凡单片机 / 时间:6个月前 (06/14) / 分类:51单片机 / 阅读:45763 / 评论:0

       在网上查有关蜂鸣器的资料,无意中发现了有关电子琴的资料,接着就看看前辈们制作的电子琴,看起来挺有意思,听起来也挺悦耳!此时便萌生了制作电子琴的念头。于是,开始在网上查相关的资料,好多都是用按键开关作为琴的按键,但是吾感觉不爽,按键这东西不太好用,而且按起来也不轻松,还得考虑延时消抖。所以放弃用按键当琴的按键,在无尽的搜索中发现了有做触摸按键电子琴的,感觉触摸这东西挺神奇的,有点意思。于是,仔细查询有关制作触摸电子琴的资料,幸运中找到了一个不错的博客-----杜洋工作室,他是用铜丝做琴弦,每个I/O口接一根铜丝,铜丝另一端当然了这里的铜丝可以用网线(刨去一段皮),再在铜丝的旁边再加一根铜丝,作为琴弦,这里的铜丝的一端需要接电源,利用的是I/O的高阻态原理。开始,两根铜丝没有接触,蜂鸣器没有发出声响,当用手将两根铜丝拨到一块儿时,构成了通路,用于此前给每个I/O口对应一个音符频率,当与某个I/O的两根铜丝接触时就会发出相应的音调。

       这里我用了21个I/O口,分别对应高,中,低的DO,RE,MI,FA,SO,LA,XI。

       线面就是实物图

基于51单片机制作(触摸)简易电子琴 51单片机 第1张

基于51单片机制作(触摸)简易电子琴 51单片机 第2张

基于51单片机制作(触摸)简易电子琴 51单片机 第3张

基于51单片机制作(触摸)简易电子琴 51单片机 第4张

基于51单片机制作(触摸)简易电子琴 51单片机 第5张

基于51单片机制作(触摸)简易电子琴 51单片机 第6张

基于51单片机制作(触摸)简易电子琴 51单片机 第7张

基于51单片机制作(触摸)简易电子琴 51单片机 第8张

基于51单片机制作(触摸)简易电子琴 51单片机 第9张

程序代码:

#include <reg52.H> //STC12C5A60S2.H
void INIT(void);
sbit SPEAKER  = P1^0;//扬声器,低使能
sbit KEY11   = P2^0;
sbit KEY12   = P2^1;
sbit KEY13   = P2^2;
sbit KEY14   = P2^3;
sbit KEY15   = P2^4;
sbit KEY16   = P2^5;
sbit KEY17   = P2^6;
sbit KEY21   = P2^7;
sbit KEY22   = P1^7;
sbit KEY23   = P1^6;
sbit KEY24   = P1^5;
sbit KEY25   = P0^7;
sbit KEY26   = P0^6;
sbit KEY27   = P0^5;
sbit KEY31   = P0^4;
sbit KEY32   = P0^3;
sbit KEY33   = P0^2;
sbit KEY34   = P0^1;
sbit KEY35   = P0^0;
sbit KEY36   = P1^2;
sbit KEY37   = P1^1;//
unsigned char MUSIC;
unsigned char STH0,STL0;
unsigned int code tab[]={ //音阶表
63628,63835,64021,64103,64260,64400,64524,  //低音1-7
64580,64684,64777,64820,64898,64968,65030, //中音1-7
65058,65110,65157,65178,65217,65252,65283 //高音1-7
};
void delay1ms (unsigned int a){ // 1ms延时程序(12MHz 10倍于51单片机速度时)
 unsigned int i;
 while( --a != 0){
  for(i = 0; i < 600; i++);
         
}
void INIT(void){//初始化程序
 TMOD=0x11;
 EA=1;
 ET0=1;
 ET1=1;
 P0M1 = 0xff;//I/O接口工作方式
 P0M0 = 0x00;//P0全为高阻输入
 P1M1 = 0xfe;//P1.0为准双向,其他为高阻输入
 P1M0 = 0x00;
 P2M1 = 0xff;//P2全为高阻输入
 P2M0 = 0x00;
 P3M1 = 0xfc;//P3.0为强推,其他为标准双向
 P3M0 = 0x01;
// P4M1 = 0xff;//P4全为高阻输入
// P4M0 = 0x00;
// P4SW = 0xff; 
 SPEAKER = 1;
}
void main(void){
 INIT(); //初始化
 while(1)
 {
  if(KEY37 == 0){delay1ms(20);if(KEY37 == 0){MUSIC = 20;}} //高音B(37)
  if(KEY36 == 0){delay1ms(20);if(KEY36 == 0){MUSIC = 19;}}
  if(KEY35 == 0){delay1ms(20);if(KEY35 == 0){MUSIC = 18;}}
  if(KEY34 == 0){delay1ms(20);if(KEY34 == 0){MUSIC = 17;}}
  if(KEY33 == 0){delay1ms(20);if(KEY33 == 0){MUSIC = 16;}}
  if(KEY32 == 0){delay1ms(20);if(KEY32 == 0){MUSIC = 15;}}
  if(KEY31 == 0){delay1ms(20);if(KEY31 == 0){MUSIC = 14;}}
//3 
  if(KEY27 == 0){delay1ms(20);if(KEY27 == 0){MUSIC = 13;}}
  if(KEY26 == 0){delay1ms(20);if(KEY26 == 0){MUSIC = 12;}}
  if(KEY25 == 0){delay1ms(20);if(KEY25 == 0){MUSIC = 11;}}
  if(KEY24 == 0){delay1ms(20);if(KEY24 == 0){MUSIC = 10;}}
  if(KEY23 == 0){delay1ms(20);if(KEY23 == 0){MUSIC = 9;}}
  if(KEY22 == 0){delay1ms(20);if(KEY22 == 0){MUSIC = 8;}}
  if(KEY21 == 0){delay1ms(20);if(KEY21 == 0){MUSIC = 7;}} 
//2 
  if(KEY17 == 0){delay1ms(20);if(KEY17 == 0){MUSIC = 6;}}
  if(KEY16 == 0){delay1ms(20);if(KEY16 == 0){MUSIC = 5;}}
  if(KEY15 == 0){delay1ms(20);if(KEY15 == 0){MUSIC = 4;}}
  if(KEY14 == 0){delay1ms(20);if(KEY14 == 0){MUSIC = 3;}}
  if(KEY13 == 0){delay1ms(20);if(KEY13 == 0){MUSIC = 2;}}
  if(KEY12 == 0){delay1ms(20);if(KEY12 == 0){MUSIC = 1;}}
  if(KEY11 == 0){delay1ms(20);if(KEY11 == 0){MUSIC = 0;}} 
//1
  if(MUSIC!=0xff)
  { //如果有音阶数值(非0XFF时)
      TR0=1; //启动定时器
   STH0=tab[MUSIC]/256; //将音阶的频率值装入定时器T0
      STL0=tab[MUSIC]%6;
   MUSIC = 0xff; //清除寄存器
  }else
  { //否则
      TR0=0; //关定时器
   SPEAKER = 1; //关扬声器
   LED = 0;
  }
    }
}

void t0(void) interrupt 1 using 0
{//定时器0产生音频
  TH0=STH0;
  TL0=STL0;
  SPEAKER=~SPEAKER; //取反频率产生音调
}

总结感想

       从买开发板到自学单片机正好两个月了,开始时,边听郭天祥的教程视频,边做练习。感觉单片机也没那么难,不过越学感觉与有意思。当听完了一遍视频后,觉得该做点东西了。不能老停留在理论盒软件编程上,也该动动手,做点东西。郭老师说得好,只有实战(做东西)才能真正学到东西。于是,有了我的处女作,ds12c887实时时钟,说实话,做的不是很好。因为焊接过程中出现了很多问题,连线太多,太乱,焊的也不是很好。好长时间没有焊东西了,很生疏,而且在连线时考虑的也不周到。没有层次和逻辑。导致了布线很乱,出现线路问题时,找起来很费劲。不过庆幸的是,最终显示出了时间。可是遗憾的是,按键不好使,或者说就不能使。关于这个问题,之后我一定会解决。

        时钟之后吗,接着又学习点阵,先让其动态显示数字,字符。不过这都是在漫无目的的学习。总想着再做点东西。于是,有时间就在网上看别人的作品,某天看到一个作品,名叫触摸电子琴,还有视频演示,看了看挺有意思,而且用的器件也不多。随即便萌生了制作的念头,于是按照教程说的买器件。接着就是按照原理图焊接。花了两天多时间终于焊接完毕,作者很给力还带有源程序。于是,照搬了过来。想直接编译,然后下载,可是出现了好多错误,提到好多变量还有寄存器没有定义,估计是头文件的问题,于是想打开头文件看看,可是根本就打不开,LAI说这个kei软件根本就没有这个头文件,你直接用51头文件就行,只需要在里面加一些你需要的寄存器,于是,我又通过网络查一下stc12c5a60s2的头文件里面的设置,然找那个头文件在51头文件中加上。果然没有错误了。下载到单片机,可是蜂鸣器一直响,根据程序的意思,初始化的时候应该是关闭蜂鸣器,当触摸琴弦键时蜂鸣器才能响,而且正常情况下还能发出音调。这是一个问题,可能是线路连接的问题,也可能是程序本身就有问题。我先查线路,用万用表测线路通断情况,电压情况。确认无误后。断定是程序有问题。然后就仔细阅读程序,程序很简单,也读不出什么错误。纠结了好长时间,后来LAI(人名)也参与进来帮忙,他早就学习单片机,有经验。一开始他也没检查出来。也不知过了多久,他提到,你可以不检测按键等于1,而像检测独立按键那样,检测是否等于0,试试。接着我又把原来检测按键是否为1的位置改成检测是否为0。可是改过之后,虽然蜂鸣器开始确实不响了,但是触摸按键也不响。这是为什么?然后我检查蜂鸣器的连接和程序中关于蜂鸣器的设置。没有问题呀!后来,他屏蔽一部分按键检测,留下一部分。这次触摸按键时蜂鸣器有了音调。原以为这样就成功了,可是当再加上几个按键时,蜂鸣器一开始就响了,再去触摸按键没有任何反应。我们都崩溃了,到底是哪里出了错误。为什么这么简单一个程序和这么简单一个线路愣是找不到错误所在呢?休息片刻后,我想到应该再去仔细阅读一下芯片stc12c5a60s2的资料,估计I/O口有问题,因为这个单片机跟51系列的不一样,他有P4.4,P4.5,P4.6口。于是我又看了看管脚介绍。果然,这三个口不能像普通I/O口那样拿来直接用。必须在这三个口为1时才能当普通I/O口用。也就是如果用他们接触摸按键,需要检测是否为1。可当我把其改为1后效果不是很好,感觉对其他按键有影响。因此,我选择放弃这三个口,改用P1.5,P1.6,P1.7。嗯,这次成功了。每个按键都起到了作用,触摸时蜂鸣器发出了音调。

 

注:做的不是很好,但是也花了不少心血,大家可以看看,多提意见。。。。。。。。


没有评论,留下你的印记,证明你来过。


发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。