有人说现在可以唱歌的扬声器那么普遍,为什么要用蜂鸣器播放音乐呢?其实用蜂鸣器播放音乐的地方有很多,有些地方需要做一些特别的提示音,如果用扬声器的话成本又划不来,而使用蜂鸣器就十分合适了。同时用这个做那种音乐的贺卡也很合适。
正文开始
蜂鸣器分为有源和无源两大类,有源的只要两边有电压差又可以发声,无源的则需要一定频率的方波在可以发声。也就是说有源的内部已经集成了一个方波发生电路。而这次发声我用的就是无源的,以为这个发出的声音会更好一些。
电路部分:
蜂鸣器是无法直接被单片机驱动的,因为蜂鸣器需要的电流很大,而单片机提供不了这么大的电流,所以需要驱动电路。简单的驱动电路长这样的
然后就是程序部分
首先得弄清楚音符与频率的对于关系,如下图
详细的文档在文末的连接里
然后我把他宏定义一下
#define L_1 0x1168
#define L_2 0x1140
#define L_3 0x1126
#define L_4 0x110e
#define L_5 0x10f0
#define L_6 0x10d6
#define L_7 0x10be
#define M_1 0x10b4 //1
#define M_2 0x10a0 //2
#define M_3 0x1092 //3
#define M_4 0x1086 //4
#define M_5 0x1078 //5
#define M_6 0x106a //6
#define M_7 0x105e //7
#define H_1 0x105a //
#define H_2 0x1050
#define H_3 0x1048
#define H_4 0x1042
#define H_5 0x103a
#define H_6 0x1034
#define H_7 0x1030
注意,我这里使用的是4个十六进制,其中最高的那个十六进制是控制码,作用是区分后面的数字是频率值还是延时值。
然后就是想办法实现一个方波,这里我用的是定时器0,首先初始化定时器
void Timer0Init(void) //10微秒@11.0592MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x02; //设置定时器模式
TL0 = 0xF7; //设置定时初值
TH0 = 0xF7; //设置定时重载值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器中断
EA = 1; //使能总中断
}
然后就是在中断服务函数里产生波形
void Timer0_ISR() interrupt 1
{
cnt++; //这是一个全局变量用于计基本时间
if(cnt > period) //如果超出范围就是清零
{
cnt = 0;
beep = 0;
}
else if(cnt < period / 2) //这里产生的是方波
{
beep = 1;
}
else
{
beep = 0;
}
}
再来个延时用来控制节拍
void Delay_ms(uint16_t ms) //@11.0592MHz
{
unsigned char i, j, k;
for(k = ms; k > 0; k --)
{
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
}
}
最后就是播放程序了
void play(uint16_t sound[], uint16_t lenth)
{
uint16_t i;
for(i = 0; i < lenth; i ++)
{
if((sound[i] & 0x1000) == 0x1000) //这个用来判断是不是音调的吗
{
P1 = 0X00;
period = sound[i] & 0x0fff;
}
if(sound[i]== 0x2000) //这个是一个音的停止
{
cnt = 0;
period = 0;
ET0 = 0;
beep = 0;
Delay_ms(30);
}
if(sound[i] == 0x4000) //这个是一个音的开始
{
ET0 = 1;
}
if((sound[i] & 0x1000) == 0x0000) //这个是两个音之间的延时
{
Delay_ms(sound[i] & 0x0fff);
}
}
}
然后就是作曲了
先看一下简谱
其中设一个拍子的时间是1s,下面一个横线就是持续0.5s,两个横线就是持续0.25s,两个音符画在一起表示一个牌子,音符后面的点表示再加0.5个相对单位,比如五上面的那个就是5持续0.75s,星上面的5持续0.25秒,飘上面的那个5就是1.75秒;音符后面的长横线表示持续3s。
于是又宏定义了一些时间
#define P0_25 0X00fa
#define P0_50 0x01f4
#define p0_75 0x02ee
#define P1_00 0X03e8
#define P1_25 0X04e2
然后就开始发声与结束发声的定义
#define up 0x4000
#define down 0x2000
最后就是那首歌
uint16_t code music[100] = {up,L_5,P1_25,down,up,M_5,P0_25,down,
up,M_1,P1_00,down,up,L_5,P1_00,down,up,M_3,P1_00,down,
up,M_1,P1_00,down,up,M_5,P1_25,down,up,M_6,P0_50,down,
up,M_5,P1_00,down,up,M_5,P1_25,down,up,M_5,P0_25,down,
up,H_1,P1_00,down,up,H_1,P1_00,down,up,M_6,P1_25,down,
up,M_5,P1_00,down,up,M_4,P0_50,down,up,M_6,P1_00,down,
up,M_5,P1_00,P1_00,P1_00,down};
相关工程看下面的链接:
链接:https://pan.baidu.com/s/1LDg-Y-ss9ntSTrT3oA0Lrw
提取码:pk0x
友情捐助c币
欢迎关注我的公众号\(0^◇^0)/