×
嵌入式 > 嵌入式开发 > 详情

单片机编程 音乐编程程序

发布时间:2020-08-28 发布时间:
|
#include

#defineucharunsignedchar
#defineuintunsignedint
#defineulongunsignedlong


sbitBEEP=P2^0;//喇叭输出脚

ucharth0_f;//在中断中装载的T0的值高8位
uchartl0_f;//在中断中装载的T0的值低8位
ucharkey;

/*------------------------------------------------
函数声明
------------------------------------------------*/
ucharkeyscan(void);//键盘扫描程序
voiddelay(uinti);//延时子程序

/*--------T0的值,及输出频率对照表--------------*/
ucharcodefreq[36*2]={
0xA9,0xEF,//0x3F,0XEE,//00220HZ,1//0
0x93,0xF0,//0X3D,0XEF,//00233HZ,1#
0x73,0xF1,//0X30,0XF0,//00247HZ,2
0x49,0xF2,//0X18,0XF1,//00262HZ,2#
0x07,0xF3,//0XE6,0XF1,//00277HZ,3
0xC8,0xF3,//0XB7,0XF2,//00294HZ,4
0x73,0xF4,//0X71,0XF3,//00311HZ,4#
0x1E,0xF5,//0X2A,0XF4,//00330HZ,5
0xB6,0xF5,//0XCF,0XF4,//00349HZ,5#
0x4C,0xF6,//0X72,0XF5,//00370HZ,6
0xD7,0xF6,//0X09,0XF6,//00392HZ,6#
0x5A,0xF7,//0X97,0XF6,//00415HZ,7
0xD8,0xF7,//0X20,0XF7,//00440HZ1//12
0x4D,0xF8,//0X9F,0XF7,//00466HZ1#//13
0xBD,0xF8,//0X18,0XF8,//00494HZ2//14
0x24,0xF9,//0X88,0XF8,//00523HZ2#//15
0x87,0xF9,//0XF3,0XF8,//00554HZ3//16
0xE4,0xF9,//0X59,0XF9,//00587HZ4//17
0x3D,0xFA,//0X05,0XFA,//00622HZ4#//18
0x90,0xFA,//0X13,0XFA,//00659HZ5//19
0xDE,0xFA,//0X66,0XFA,//00698HZ5#//20
0x29,0xFB,//0XB9,0XFA,//00740HZ6//21
0x6F,0xFB,//0X05,0XFB,//00784HZ6#//22
0xB1,0xFB,//0X4D,0XFB,//00831HZ7//23
0xEF,0xFB,//0X90,0XFB,//00880HZ`1
0x2A,0xFC,//0XD0,0XFB,//00932HZ`1#
0x62,0xFC,//0X0C,0XFC,//00988HZ`2
0x95,0xFC,//0X44,0XFC,//01046HZ`2#
0xC7,0xFC,//0X7B,0XFC,//01109HZ`3
0xF6,0xFC,//0XAD,0XFC,//01175HZ`4
0x22,0xFD,//0XDD,0XFC,//01244HZ`4#
0x4B,0xFD,//0X0A,0XFD,//01318HZ`5
0x73,0xFD,//0X35,0XFD,//01397HZ`5#
0x98,0xFD,//0X5D,0XFD,//01480HZ`6
0xBB,0xFD,//0X83,0XFD,//01568HZ`6#
0xDC,0xFD,//0XA6,0XFD,//01661HZ`7//35
};

//定时中断0,用于产生唱歌频率
timer0()interrupt1
{
TL0=tl0_f;TH0=th0_f;//调入预定时值
BEEP=~BEEP;//取反音乐输出IO
}

//音乐符号串解释函数
//入口:要解释的音乐符号串,输出的音调串,输出的时长串
changedata(uchar*song,uchar*diao,uchar*jie)
{
uchari,i1,j;
chargaodi;//高低+/-12音阶
ucharbanyin;//有没有半个升音阶
ucharyinchang;//音长
ucharcodejie7[8]={0,12,14,16,17,19,21,23};//C调的7个值
*diao=*song;
for(i=0,i1=0;;)
{
gaodi=0;//高低=0
banyin=0;//半音=0
yinchang=4;//音长1拍
if((*(song+i)==|)||(*(song+i)==))i++;
//拍子间隔和一个空格过滤
switch(*(song+i))
{
case,:gaodi=-12;i++;//低音
break;
case`:gaodi=12;i++;//高音
break;
}
if(*(song+i)==0)//遇到0结束
{
*(diao+i1)=0;//加入结束标志0
*(jie+i1)=0;
return;
}
j=*(song+i)-0x30;i++;//取出基准音
j=jie7[j]+gaodi;//加上高低音
yinc:switch(*(song+i))
{
case#://有半音j加一个音阶
i++;j++;
gotoyinc;
case-://有一个音节加长
yinchang+=4;
i++;
gotoyinc;
case_://有一个音节缩短
yinchang/=2;
i++;
gotoyinc;
case.://有一个加半拍
yinchang=yinchang+yinchang/2;
i++;
gotoyinc;
}
*(diao+i1)=j;//记录音符
*(jie+i1)=yinchang;//记录音长
i1++;
}
}

//奏乐函数
//入口:要演奏的音乐符号串
voidplay(uchar*songdata)
{
uchari,c,j=0;
uintn;
uchardiaodata[48];//音调缓冲
ucharjiedata[48];//音长缓冲
changedata(songdata,diaodata,jiedata);//解释音乐符号串
TR0=1;
for(i=0;diaodata[i]!=0;i++)//逐个符号演奏
{
tl0_f=freq[diaodata[i]*2];//取出对应的定时值送给T0
th0_f=freq[diaodata[i]*2+1];
for(c=0;c{key=keyscan();
for(n=0;n<29500;n++);//29500
if(key!=0xff)//((!K1)||(!K2)||(!K3)||(!K4))//发现按键,立即退出播放
{
TR0=0;
return;
}
}
TR0=0;
for(n=0;n<460;n++);//460音符间延时
TR0=1;
}
TR0=0;
}

//一分钱
ucharcodeyifenqian[]={
"5`1|6_`1_5|3_5_2_3_|5-|"
"3_5_6_`1_|5_6_5_3_|1.3__|2-|"
"3_2_1_2_|3-|6_5_3_5_|6-|"
"5_`1_6_5_|3_5_2|5_2_3_2_|1-|"
};

//世上只有妈妈好
ucharcodemamahao[]={
"6.5_35|`16_5_6-|35_6_53_2_|1_,6_5_3_2-|"
"2.3_55_6_|321-|5.3_2_1_,6_1_|,5--"
};
//找朋友
ucharcodezhaopengyou[]={"5_6_5_6_|5_6_5|5_`1_7_6_|53|"
"5_5_3_4_|5_5_3|1_4_3_2_|1_2_1|"
};
//茉莉花
ucharcodemolihua[]={"33_5_6_`1_`1_6_|55_6_5-|33_5_6_`1_`1_6_|55_6_5-|"
"5553_5_|665-|32_3_53_2_|11_2_1|"
//"3_2_1_3_2.3_|56_`1_5-|23_5_2_3_1_,6_|,5-,61|"
//"2.3_1_2-1_,6_|,5--"
};
//新年好
ucharcodexinnianhao[]={
"1_1_1,5|3_3_31|1_3_55|4_3_2-|"
"2_3_4-|3_2_31|1_3_2,5|,7_2_1-|"
};
//小星星
ucharcodexingxing[]={
"1155|665-|4433|221-|"
"5544|332-|5544|332-|"
"1155|665-|4433|221-|"
};
//外婆的澎湖湾
ucharcodewaipodephw[]={
"3_5_5_5_6_`1_6_5_|`1_`1_`1_6_5-|"
"`3_`3_`3_`3_`4_`3_`2_`1_|`2_`2_`2_`3_`2-|"
"`3_`3_`3_`3_`4_`3_`2_`1_|6_`1_`1_6_5-|"
};
}

//春天在哪里
ucharcodechuntian[]={"3_3_3_1_|,5,5|3_3_3_1_|3-|5_5_3_1_|,5_,5_,5|,6_,7_1_3_|2-|"
"3_3_3_1_|,5,5|3_3_3_1_|3-|5_6_5_6_|5_4_3_1_|,53|1-|"
};

//两只老虎
ucharcodelaohu[]={"1231|1231|345-|345-|5_6_5_4_31|5_6_5_4_31|"
"151-|151-"
};

/*------------------------------------------------
键盘扫描程序
------------------------------------------------*/
ucharkeyscan(void)//键盘扫描函数,使用行列反转扫描法
{
ucharcord_h,cord_l;//行列值中间变量
P3=0x0f;//行线输出全为0
cord_h=P3&0x0f;//读入列线值
if(cord_h!=0x0f)//先检测有无按键按下
{
delay(100);//去抖
if(cord_h!=0x0f)
{
cord_h=P3&0x0f;//读入列线值
P3=cord_h|0xf0;//输出当前列线值
cord_l=P3&0xf0;//读入行线值
return(cord_h+cord_l);//键盘最后组合码值
}
}
return(0xff);//返回该值
}
/*------------------------------------------------
延时程序
------------------------------------------------*/
voiddelay(uinti)//延时函数
{
while(i--);
}
//乐谱方式输入的音乐播放,
voidmain(void)//主程序
{
ucharcodejie8[8]={12,14,16,17,19,21,23,24};//1234567`1八个音符在频率表中的位置
uchari=0;
ucharn=0;
TMOD=0x01;//使用定时器0的16位工作模式
TR0=0;
ET0=1;
EA=1;

while(1)
{
key=keyscan();
switch(key)
{
case0x7e:
while(key==0x7e)
{
key=keyscan();
}
play(molihua);
break;//0
case0x7d:
while(key==0x7d)
{
key=keyscan();
}
play(yifenqian);
break;//1
case0x7b:while(key==0x7b)
{
key=keyscan();
}
play(chuntian);
break;//2
case0x77:while(key==0x77)
{
key=keyscan();
}
play(waipodephw);
break;//3
case0xbe:while(key==0xbe)
{
key=keyscan();
}
play(xingxing);
break;//4
case0xbd:while(key==0xbd)
{
key=keyscan();
}
play(xinnianhao);
break;//5
case0xbb:while(key==0xbb)
{
key=keyscan();
}
play(mamahao);
break;//6
case0xb7:while(key==0xb7)
{
key=keyscan();
}
play(zhaopengyou);
break;//7
case0xde:while(!(key^0xde))
{
tl0_f=freq[jie8[0]*2];//置一个音符的值
th0_f=freq[jie8[0]*2+1];
TR0=1;
key=keyscan();
//for(n=0;n<10000;n++);//延时
}
break;//8
case0xdd:while(!(key^0xdd))
{
tl0_f=freq[jie8[1]*2];//置一个音符的值
th0_f=freq[jie8[1]*2+1];
TR0=1;
key=keyscan();
//for(n=0;n<10000;n++);//延时
}
break;//9
case0xdb:while(!(key^0xdb))
{
tl0_f=freq[jie8[2]*2];//置一个音符的值
th0_f=freq[jie8[2]*2+1];
TR0=1;
key=keyscan();
//for(n=0;n<10000;n++);//延时
}
break;//a
case0xd7:while(!(key^0xd7))
{
tl0_f=freq[jie8[3]*2];//置一个音符的值
th0_f=freq[jie8[3]*2+1];
TR0=1;
key=keyscan();
//for(n=0;n<10000;n++);//延时
}
break;//b
case0xee:while(!(key^0xee))
{
tl0_f=freq[jie8[4]*2];//置一个音符的值
th0_f=freq[jie8[4]*2+1];
TR0=1;
key=keyscan();
//for(n=0;n<10000;n++);//延时
}break;//c
case0xed:while(!(key^0xed))
{
tl0_f=freq[jie8[5]*2];//置一个音符的值
th0_f=freq[jie8[5]*2+1];
TR0=1;
key=keyscan();
//for(n=0;n<10000;n++);//延时
}break;//d
case0xeb:while(!(key^0xeb))
{
tl0_f=freq[jie8[6]*2];//置一个音符的值
th0_f=freq[jie8[6]*2+1];
TR0=1;
key=keyscan();
//for(n=0;n<10000;n++);//延时
}break;//e
case0xe7:while(!(key^0xe7))
{
tl0_f=freq[jie8[7]*2];//置一个音符的值
th0_f=freq[jie8[7]*2+1];
TR0=1;
key=keyscan();
//for(n=0;n<10000;n++);//延时
}break;//f
default:break;
}
TR0=0;
/*if(!K1)
{
tl0_f=freq[jie8[0]*2];//置一个音符的值
th0_f=freq[jie8[0]*2+1];
TR0=1;
for(n=0;n<10000;n++);//延时
}
if(!K2)
{
tl0_f=freq[jie8[1]*2];//置一个音符的值
th0_f=freq[jie8[1]*2+1];
TR0=1;
for(n=0;n<10000;n++);//延时
}
if(!K3)
{
tl0_f=freq[jie8[2]*2];//置一个音符的值
th0_f=freq[jie8[2]*2+1];
TR0=1;
for(n=0;n<10000;n++);//延时
}
if(!K4)
{
tl0_f=freq[jie8[3]*2];//置一个音符的值
th0_f=freq[jie8[3]*2+1];
TR0=1;
for(n=0;n<10000;n++);//延时
}
TR0=0;
if(!K1)
{
while(!K1);
play(molihua);//播放音乐
}
if(!K2)
{
while(!K2);
play(dami);//播放音乐
}
if(!K3)
{
while(!K3);
play(mamahao);//播放音乐
}
if(!K4)
{
switch(i)
{
case0:
play(xianjian);//播放音乐
break;
case1:
play(song3);//播放音乐
break;
case2:
play(mamahao);//播放音乐
break;
case3:
play(boluo);//播放音乐
break;
case4:
play(xingxing);//播放音乐
break;
case5:
play(dami);//播放音乐
break;
}
i++;if(i==6)i=0;
}*/
}



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
Recogni:将高端AI芯片推向自动驾驶边缘