单片机制作电子琴共同探讨.docx
- 文档编号:7308995
- 上传时间:2023-01-22
- 格式:DOCX
- 页数:15
- 大小:73.58KB
单片机制作电子琴共同探讨.docx
《单片机制作电子琴共同探讨.docx》由会员分享,可在线阅读,更多相关《单片机制作电子琴共同探讨.docx(15页珍藏版)》请在冰豆网上搜索。
单片机制作电子琴共同探讨
1.实验任务
(1.由4X4组成16个按钮矩阵,设计成16个音。
(2.可随意弹奏想要表达的音乐。
2.电路原理图
图4.22.1
3.系统板硬件连线
(1.把“单片机系统”区域中的P1.0端口用导线连接到“音频放大模块”区域中的SPKIN端口上;
(2.把“单片机系统“区域中的P3.0-P3.7端口用8芯排线连接到“4X4行列式键盘”区域中的C1-C4 R1-R4端口上;
4.相关程序内容
(1.4X4行列式键盘识别;
(2.音乐产生的方法;
一首音乐是许多不同的音阶组成的,而每个音阶对应着不同的频率,这样我们就可以利用不同的频率的组合,即可构成我们所想要的音乐了,当然对于单片机来产生不同的频率非常方便,我们可以利用单片机的定时/计数器T0来产生这样方波频率信号,因此,我们只要把一首歌曲的音阶对应频率关系弄正确即可。
现在以单片机12MHZ晶振为例,例出高中低音符与单片机计数T0相关的计数值如下表所示
下面我们要为这个音符建立一个表格,有助于单片机通过查表的方式来获得相应的数据
低音0-19之间,中音在20-39之间,高音在40-59之间
TABLE:
DW0,63628,63835,64021,64103,64260,64400,64524,0,0
DW0,63731,63928,0,64185,64331,64463,0,0,0
DW0,64580,64684,64777,64820,64898,64968,65030,0,0
DW0,64633,64732,0,64860,64934,64994,0,0,0
DW0,65058,65110,65157,65178,65217,65252,65283,0,0
DW0,65085,65134,0,65198,65235,65268,0,0,0
DW0
2、音乐的音拍,一个节拍为单位(C调)
对于不同的曲调我们也可以用单片机的另外一个定时/计数器来完成。
下面就用AT89S51单片机产生一首“生日快乐”歌曲来说明单片机如何产生的。
在这个程序中用到了两个定时/计数器来完成的。
其中T0用来产生音符频率,T1用来产生音拍。
5.程序框图
图4.22.2
7.C语言源程序
#include
unsignedchartemp;
unsignedcharkey;
unsignedchari,j;
unsignedcharSTH0;
unsignedcharSTL0;
unsignedintcodetab[]={64021,64103,64260,64400,
64524,64580,64684,64777,
64820,64898,64968,65030,
65058,65110,65157,65178};
voidmain(void)
{
TMOD=0x01;
ET0=1;
EA=1;
while
(1)
{
P3=0xff;//将P3口取出
P3_4=0;//使P3_4为低电平,这样可以判断第一竖排有没有键按下
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)//判断是哪个键按下
{
case0x0e:
key=0;
break;
case0x0d:
key=1;
break;
case0x0b:
key=2;
break;
case0x07:
key=3;
break;
}
temp=P3;
P1_0=~P1_0;
P0=table[key];
STH0=tab[key]/256;//找出键对应的频率的时间,作为定时器中断初始值
STL0=tab[key]%256;
TR0=1;
temp=temp&0x0f;
while(temp!
=0x0f)
{
temp=P3;
temp=temp&0x0f;
}
TR0=0;
}
}
P3=0xff;
P3_5=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)
{
case0x0e:
key=4;
break;
case0x0d:
key=5;
break;
case0x0b:
key=6;
break;
case0x07:
key=7;
break;
}
temp=P3;
P1_0=~P1_0;
P0=table[key];
STH0=tab[key]/256;
STL0=tab[key]%256;
TR0=1;
temp=temp&0x0f;
while(temp!
=0x0f)
{
temp=P3;
temp=temp&0x0f;
}
TR0=0;
}
}
P3=0xff;
P3_6=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)
{
case0x0e:
key=8;
break;
case0x0d:
key=9;
break;
case0x0b:
key=10;
break;
case0x07:
key=11;
break;
}
temp=P3;
P1_0=~P1_0;
P0=table[key];
STH0=tab[key]/256;
STL0=tab[key]%256;
TR0=1;
temp=temp&0x0f;
while(temp!
=0x0f)
{
temp=P3;
temp=temp&0x0f;
}
TR0=0;
}
}
P3=0xff;
P3_7=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)
{
case0x0e:
key=12;
break;
case0x0d:
key=13;
break;
case0x0b:
key=14;
break;
case0x07:
key=15;
break;
}
temp=P3;
P1_0=~P1_0;
P0=table[key];
STH0=tab[key]/256;
STL0=tab[key]%256;
TR0=1;
temp=temp&0x0f;
while(temp!
=0x0f)
{
temp=P3;
temp=temp&0x0f;
}
TR0=0;
}
}
}
}
voidt0(void)interrupt1using0
{
TH0=STH0;
TL0=STL0;
P1_0=~P1_0;
}
上面是我从网上弄来的,电子琴程序;其中还存在很多问题,经过研究,自行修改了一些,修改之后明显有了乐感,但还是达不到音乐渐弱的感觉,如果哪位有兴趣的可以共同探讨,本人QQ:
1123658659
下面是我的修改程序;大家对比学习:
#include
//#include
unsignedchartemp;
unsignedcharkey;
unsignedchari,j,k;
unsignedcharSTH0;
unsignedcharSTL0;
sbitP3_4=P3^4;
sbitP1_0=P1^0;
sbitP3_5=P3^5;
sbitP3_6=P3^6;
sbitP3_7=P3^7;
unsignedintcodetab[]={64021,64103,64260,64400,
64524,64580,64684,64777,
64820,64898,64968,65030,
65058,65110,65157,65178};
//unsignedintcodetable[]={63628,63835
voidmain(void)
{
TMOD=0x11;
ET0=1;
ET1=1;
EA=1;
k=0;
while
(1)
{
P3=0xff;//将P3口取出
P3_4=0;//使P3_4为低电平,这样可以判断第一竖排有没有键按下
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)//判断是哪个键按下
{
case0x0e:
key=0;
break;
case0x0d:
key=1;
break;
case0x0b:
key=2;
break;
case0x07:
key=3;
break;
}
temp=P3;
//P1_0=~P1_0;
//P0=table[key];
STH0=tab[key]/256;//找出键对应的频率的时间,作为定时器中断初始值
STL0=tab[key]%256;
//TH0=STH0;
//TL0=STL0;//LLLLLLLL
TH1=0;
TL1=0;
TR0=1;
k=0;
TR1=1;
//for(k=50;k>0;k--)
//for(i=100;i>0;i--)
//for(j=100;j>0;j--);//LLLLLLL
temp=temp&0x0f;
while(temp!
=0x0f)
{
temp=P3;
temp=temp&0x0f;
}
//TR0=0;
//P1_0=1;//&&&&&&&&&&
}
}
P3=0xff;
P3_5=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)
{
case0x0e:
key=4;
break;
case0x0d:
key=5;
break;
case0x0b:
key=6;
break;
case0x07:
key=7;
break;
}
temp=P3;
//P1_0=~P1_0;
//P0=table[key];
STH0=tab[key]/256;
STL0=tab[key]%256;
TH1=0;
TL1=0;
TR0=1;
k=0;
TR1=1;
//for(k=25;k>0;k--)
//for(i=100;i>0;i--)
//for(j=100;j>0;j--);//LLLLLLL
while(temp!
=0x0f)
{
temp=P3;
temp=temp&0x0f;
}
//TR0=0;
//P1_0=1;
}
}
P3=0xff;
P3_6=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)
{
case0x0e:
key=8;
break;
case0x0d:
key=9;
break;
case0x0b:
key=10;
break;
case0x07:
key=11;
break;
}
temp=P3;
//P1_0=~P1_0;
//P0=table[key];
STH0=tab[key]/256;
STL0=tab[key]%256;
TH1=0;
TL1=0;
TR0=1;
k=0;
TR1=1;
//for(k=25;k>0;k--)
//for(i=100;i>0;i--)
//for(j=100;j>0;j--);//LLLLLLL
temp=temp&0x0f;
while(temp!
=0x0f)
{
temp=P3;
temp=temp&0x0f;
}
//TR0=0;
//P1_0=1;//&&&&&&&&&
}
}
P3=0xff;
P3_7=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)
{
case0x0e:
key=12;
break;
case0x0d:
key=13;
break;
case0x0b:
key=14;
break;
case0x07:
key=15;
break;
}
temp=P3;
//P1_0=~P1_0;
//P0=table[key];
STH0=tab[key]/256;
STL0=tab[key]%256;
TH1=0;
TL1=0;
TR0=1;
k=0;
TR1=1;
//for(k=25;k>0;k--)
//for(i=100;i>0;i--)
//for(j=100;j>0;j--);//LLLLLLL
temp=temp&0x0f;
while(temp!
=0x0f)
{
temp=P3;
temp=temp&0x0f;
}
//TR0=0;
//P1_0=1;
}
}
}
}
voidt0(void)interrupt1using0
{
TH0=STH0;
TL0=STL0;
P1_0=~P1_0;
}
voidt1(void)interrupt3using0//用另一个中断控制上面的中断
{
TH1=0;
TL1=0;
k++;
if(k==12){//通过改变k可以使节拍变化
TR0=0;
k=0;
TR1=0;
}
}
大家对比学习,如有不妥之处或有更好的欢迎指正:
可至邮件1123658659@
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 单片机 制作 电子琴 共同 探讨