如何编写51单片机音乐程序

如题所述

第1个回答  2017-05-27
一、总体原理:
乐曲中不同的音符,实质就是不同频率的声音。通过单片机产生不同的频率的脉冲信号,
经过放大电路,由蜂鸣器放出,就产生了美妙和谐的乐曲。
二、单片机产生不同频率脉冲信号的原理:
1)要产生音频脉冲,只要算出某一音频的脉冲(1/频率),然后将此周期除以2,即为半周
期的时间,利用定时器计时这个半周期的时间,每当计时到后就将输出脉冲的I/O 反相,然
后重复计时此半周期的时间再对I/O 反相,就可以在I/O 脚上得到此频率的脉冲。
2)利用8051 的内部定时器使其工作在计数器模式MODE1 下,改变计数值TH0 及TL0 以
产生不同频率的方法如下:
例如,频率为523Hz,其周期天/523 S=1912uS,因此只要令计数器计时956uS/1us=956,
在每计数956 次时就将I/O 反接,就可得到中音DO(532Hz)。
计数脉冲值与频率的关系公式如下:
N=Fi/2/Fr
(N:计数值,Fi:内部计时一次为1uS,故其频率为1MHz,Fr:要产生的频率)
三、其计数值的求法如下:
T=65536-N=65536-Fi/2/Fr
计算举例:
设K=65536,F==Fi=1MHz,求低音DO(261Hz)、中音DO(523Hz)、高音DO(1046Hz)
的计数值。
T=65536-N=65536-Fi/2/Fr=6/2/Fr=65536-/Fr
低音DO 的T=65536-/262=63627
中音DO 的T=65536-/523=64580
高音DO 的T=65536-/1047=65059
参考程序:
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit BEEP=P3^7;
// 生日快乐歌的音符频率表,不同频率由不同的延时来决定
uchar code SONG_TONE[]={212,212,190,212,159,169,212,212,190,212,142,159,
212,212,106,126,159,169,190,119,119,126,159,142,159,0};
// 生日快乐歌节拍表,节拍决定每个音符的演奏长短
uchar code SONG_LONG[]={9,3,12,12,12,24,9,3,12,12,12,24,
9,3,12,12,12,12,12,9,3,12,12,12,24,0};
// 延时
void DelayMS(uint x)
{
uchar t;
while(x--) for(t=0;t<120;t++);
}
// 播放函数
void PlayMusic()
{
uint i=0,j,k;
while(SONG_LONG[i]!=0||SONG_TONE[i]!=0)
{ //播放各个音符,SONG_LONG 为拍子长度
for(j=0;j<SONG_LONG[i]*20;j++)
{
BEEP=~BEEP;
//SONG_TONE延时表决定了每个音符的频率
for(k=0;k<SONG_TONE[i]/3;k++);
}
DelayMS(10);
i++;
}
}
void main()
{
BEEP=0;
while(1)
{
PlayMusic(); //播放生日快乐
DelayMS(500); //播放完后暂停一段时间
}
}本回答被提问者采纳
相似回答