您的位置 首页 应用

mcu音乐程序的规划与试验

利用单片机(或单板机)奏乐大概是无线电爱好者感兴趣的问题之一。本文从单片机的基本发间实验出发,谈谈音乐程序的设计原理,并给出具体实

使用单片机(或单板机)吹打大概是无线电爱好者感兴趣的问题之一。本文从单片机的根本发间试验动身,谈谈音乐程序的规划原理,并给出详细实例,以供参阅。

1.单片机的根本发音试验

咱们知道,声响的频谱规模约在几十到几千赫兹,若能使用程序来操控单处机某个口线的“高”电平或低电平,则在该口线上就能发生必定频率的矩形波,接上喇叭就能宣布必定频率的声响,若再使用延时程序操控“高”“低”电平的持续时刻,就能改动输出频率,然后改动腔调。

例如,要发生200HZ的音频信号,按图1接入喇叭(若属暂时试验,也可将喇叭直接接在P1口线上),试验程序为:

其间子程序DEL为延时子程序,当R3为1时,延时时刻约为20us,R3中寄存延时常数,对200HZ音频,其周期为1/200秒,即5ms。这样,当P1.4的高电平或低电平的持续时刻为2.5ms,即R3的时刻常数取2500/20=125(7DH)时,就能宣布200HZ的腔调。将上述程序键入学习机,并不断修正R3的常数能够感到腔调的改动。

乐曲中,每一音符对应着确认的频率,表1给出C调时各音符频率及其相应的时刻常数。

读者能够依据表1所供给的常数,将其16进制代码送入R3,重复操练领会。依据表1能够奏出音符。仅这还不行,要精确奏出一首曲子,有必要精确地操控乐曲节奏,即一音符的持续时刻。

音符的节拍咱们能够用守时器T0来操控,送入不同的初值,就能够发生不同的守时时刻。便如某歌曲的节奏为每分钟94拍,即一拍为0.64秒。其它节拍与时刻的对应联系见表2。

但时,因为T0的最大守时时刻只能为131毫秒,因而不可能直接用改动T0的时刻初值来完结不同节拍。咱们能够用T0来发生10毫秒的时刻基准,然后设置一个中止计数器,经过判别中止计数器的值来操控节拍时刻的长短。表2中也给出了各种节拍所对应的时刻常数。例如对1/4拍音符,守时时刻为0.16秒,相应的时刻常数为16(即10H);对3拍音符,守时时刻为1.92秒,相应时刻长数为192(即C0H)。

咱们将每一音符的时刻常数和其相应的节拍常数作为一组,按次序将乐曲中的一切常数排列成一个表,然后由查表程序顺次取出,发生音符并操控节奏,就能够完结演奏作用。

此外,结束符和体止符能够分别用代码00H和FFH来表明,若查表成果为00H,则表明曲子终了;若查表成果为FFH,则发生相应的中止作用。

为了发生手弹的节奏感,在某些音符(例如两个相同音符)音刺进一个时刻单位的频率略有不同的音符。

程序框图如图2所示。

可直接在TD-III型学习机上演奏,对其它不同类型的学习机,只需相应地改动一下地址即可。本程序演奏的是民歌“八月桂花遍地开”,C调,节奏为94拍/分。读者也能够自行找出一首歌,按表1和表2给定的常数,将乐曲翻译成码表输入机器,而程序不变。本试验办法简洁,即便不明白音乐的人,将一首生疏的曲子翻译成代码也是易事,和着机器的演奏学唱一首歌曲,其趣味无穷。

from:http://www.c51.cn/mcu/mcs51yy/200604/mcu_20060422123021_4081.html

下面这个比如是我在网上找的简略易懂,只不过是用C编写的,并且根本思想跟上面讲的相同。

#i nclude
#i nclude
//本例选用89C52, 晶振为11.0592MHZ
//关于怎么编制音乐代码, 其实非常简略,各位能够看以下代码.
//频率常数即音乐术语中的腔调,而节拍常数即音乐术语中的多少拍;
//所以拿出谱子, 打听编吧!

unsigned char n=0;//n为节拍常数变量
unsigned char code music_tab[] ={
0x18, 0x30, 0x1C , 0x10, //格局为: 频率常数, 节拍常数, 频率常数, 节拍常数,
0x20, 0x40, 0x1C , 0x10,
0x18, 0x10, 0x20 , 0x10,
0x1C, 0x10, 0x18 , 0x40,
0x1C, 0x20, 0x20 , 0x20,
0x1C, 0x20, 0x18 , 0x20,
0x20, 0x80, 0xFF , 0x20,
0x30, 0x1C, 0x10 , 0x18,
0x20, 0x15, 0x20 , 0x1C,
0x20, 0x20, 0x20 , 0x26,
0x40, 0x20, 0x20 , 0x2B,
0x20, 0x26, 0x20 , 0x20,
0x20, 0x30, 0x80 , 0xFF,
0x20, 0x20, 0x1C , 0x10,
0x18, 0x10, 0x20 , 0x20,
0x26, 0x20, 0x2B , 0x20,
0x30, 0x20, 0x2B , 0x40,
0x20, 0x20, 0x1C , 0x10,
0x18, 0x10, 0x20 , 0x20,
0x26, 0x20, 0x2B , 0x20,
0x30, 0x20, 0x2B , 0x40,
0x20, 0x30, 0x1C , 0x10,
0x18, 0x20, 0x15 , 0x20,
0x1C, 0x20, 0x20 , 0x20,
0x26, 0x40, 0x20 , 0x20,
0x2B, 0x20, 0x26 , 0x20,
0x20, 0x20, 0x30 , 0x80,
0x20, 0x30, 0x1C , 0x10,
0x20, 0x10, 0x1C , 0x10,
0x20, 0x20, 0x26 , 0x20,
0x2B, 0x20, 0x30 , 0x20,
0x2B, 0x40, 0x20 , 0x15,
0x1F, 0x05, 0x20 , 0x10,
0x1C, 0x10, 0x20 , 0x20,
0x26, 0x20, 0x2B , 0x20,
0x30, 0x20, 0x2B , 0x40,
0x20, 0x30, 0x1C , 0x10,
0x18, 0x20, 0x15 , 0x20,
0x1C, 0x20, 0x20 , 0x20,
0x26, 0x40, 0x20 , 0x20,
0x2B, 0x20, 0x26 , 0x20,
0x20, 0x20, 0x30 , 0x30,
0x20, 0x30, 0x1C , 0x10,
0x18, 0x40, 0x1C , 0x20,
0x20, 0x20, 0x26 , 0x40,
0x13, 0x60, 0x18 , 0x20,
0x15, 0x40, 0x13 , 0x40,
0x18, 0x80, 0x00
};

void int0()interrupt 1//选用中止0 操控节拍
{TH0=0xd8;
TL0=0xef;
n–;
}

void delay (unsigned char m)//操控频率延时
{
unsigned i=3*m;
while(–i);
}

void delayms(unsigned char a)//豪秒延时子程序
{
while(–a);//选用while(–a) 不要选用while(a–); 各位可编译一下看看汇编成果就知道了!
}

void main()
{ unsigned char p,m;//m为频率常数变量
unsigned char i=0;
TMOD&=0x0f;
TMOD =0x01;
TH0=0xd8;TL0=0xef;
IE=0x82;
play:
while(1)
{
a: p=music_tab[i];
if(p==0x00){ i=0, delayms(1000); goto play;}//假如碰到结束符,延时1秒,回到开端再来一遍
else if(p==0xff){ i=i+1;delayms(100),TR0=0; goto a;}//若碰到休止符,延时100ms,持续取下一音符
else{m=music_tab[i++], n=music_tab[i++];}//取频率常数 和 节拍常数
TR0=1;//开守时器1
while(n!=0) P1=~P1,delay(m);//等候节拍完结, 经过P1口输出音频(可多声道哦!)
TR0=0;//关守时器1
}
}

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/yingyong/257357.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部