前言
蜂鸣器在生活中的应用实则相当广泛。通过本章你将学会制造噪声 (笑~)你将学会驱动它们,并发出响声。
硬件介绍
蜂鸣器简介
蜂鸣器的英文为Buzzer
,是将电信号转化为音频信号的基本电子器件。蜂鸣器有无源蜂鸣器和有源蜂鸣器两种。
- 无源蜂鸣器:即压电式蜂鸣器。内部不带振荡源,须提供脉冲信号驱动。通过改变频率调节音调高低,改变占空比调节音量大小。无正负极之分。
- 有源蜂鸣器:即电磁式蜂鸣器。内部自带振荡源,只需通直流电即响,驱动简单,但频率固定。有正负极之分。
这里的源与电源无关,指的是内部是否有振荡源。有源蜂鸣器有正负极之分,接反会导致蜂鸣器不工作,一般长脚为正极,短脚为负极。
有源蜂鸣器通常用于只需要发出响声的场景,如:按键音、报警器等等。无源蜂鸣器由于可以改变电压,可以应用于电子琴、变声器中。
图1 无源蜂鸣器 |
|
判断有源无源的方法
- 用万用表测试
- 无源蜂鸣器电阻大致为10Ω左右。对于脉冲信号才能发声。
- 有源蜂鸣器电阻大致为几百欧姆。且接通持续发声。
- 看表面封装
- 无源蜂鸣器一般都是无贴纸标识。
- 有源蜂鸣器一般都是有贴纸标识。
扬声器简介
扬声器的英文为Loudspeaker
,俗称喇叭,也是一种电声换能器件。扬声器的工作频率宽,音色好,常应用于较高端的电子消费领域,如蓝牙音箱,手机,电脑等。
扬声器的重要参数
- 额定阻抗:即扬声器在共振峰后所呈现的最小阻抗,有4Ω、6Ω、8Ω、16Ω和32Ω等几种典型值。
- 直流阻抗:即扬声器音圈的直流电阻
- 额定功率:指扬声器长时间正常连续工作而无明显失真的输入平均电功率。
- 频率响应范围:一般低音扬声器的频率范围在
20HZ~3kHZ
之间,中音扬声器的频率范围在500HZ~5kHZ
之间,高音扬声器的频率范围在2~20kHZ
之间。扬声器的频响曲线越平坦,说明频率失真越小,有效频率范围越宽。 - 谐振频率:是决定扬声器低频特性的重要参数,谐振频率越低,扬声器低音的质感和力度也越好。
扬声器和蜂鸣器的异同
- 除了有源蜂鸣器是直接通直流发声,无源蜂鸣器和扬声器本质上都是通过音圈(线圈)和磁铁的引力和斥力从而产生振动发声。因此需要交变的电流驱动,直流PWM也可以驱动,电压的通断也会使振膜的振动。
- 扬声器的音域更广,而蜂鸣器的音域狭窄。
- 扬声器多用于音箱等对于音质要求较高的场合,而蜂鸣器多作为报警提示音使用。
PWM基础
即脉冲宽度调制(pulse-width modulation
),是一种功率控制技术。
占空比(duty
),即单个脉冲周期中高电平所占的比例。
D
u
t
y
=
t
T
Duty = \frac{t}{T}
Duty=Tt
频率(frequency
),即PWM脉冲信号的频率。
f
r
e
q
u
e
n
c
y
=
1
T
frequency = \frac{1}{T}
frequency=T1
在一些单片机中已集成硬件PWM输出电路,但51单片机中没有,一般采用软件方式模拟,输出的PWM信号不及硬件PWM稳定。
乐理基础
进入声学篇章,必须对乐理知识有一个初步的了解,这里参考了江科大的视频、知乎等进行了总结。
音调是由频率决定的。以钢琴音阶为例,白键+黑键共88个音阶,其对应的频率为
序号 | 音名 | 频率(Hz) | 序号 | 音名 | 频率(Hz) | 序号 | 音名 | 频率(Hz) | 序号 | 音名 | 频率(Hz) |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | A2 | 27.500 | 13 | A1 | 55.000 | 25 | A | 110.00 | 37 | a | 220.00 |
2 | #A2 | 29.135 | 14 | #A1 | 58.270 | 26 | #A | 116.541 | 38 | #a | 233.082 |
3 | B2 | 30.868 | 15 | B1 | 61.735 | 27 | B | 123.471 | 39 | b | 246.942 |
4 | C1 | 32.703 | 16 | C | 65.406 | 28 | c | 130.813 | 40 | c1 | 261.626 |
5 | #C1 | 34.648 | 17 | #C | 69.296 | 29 | #c | 138.591 | 41 | #c1 | 277.183 |
6 | D1 | 36.708 | 18 | D | 73.416 | 30 | d | 146.832 | 42 | d1 | 293.665 |
7 | #D1 | 38.891 | 19 | #D | 77.782 | 31 | #d | 155.563 | 43 | #d1 | 311.127 |
8 | E1 | 41.203 | 20 | E | 82.407 | 32 | e | 164.814 | 44 | e1 | 329.628 |
9 | F1 | 43.654 | 21 | F | 87.307 | 33 | f | 174.614 | 45 | f1 | 349.228 |
10 | #F1 | 46.249 | 22 | #F | 92.499 | 34 | #f | 184.997 | 46 | #f1 | 369.994 |
11 | G1 | 48.999 | 23 | G | 97.999 | 35 | g | 195.998 | 47 | g1 | 391.995 |
12 | #G1 | 51.913 | 24 | #G | 103.826 | 36 | #g | 207.652 | 48 | #g1 | 415.305 |
序号 | 音名 | 频率(Hz) | 序号 | 音名 | 频率(Hz) | 序号 | 音名 | 频率(Hz) | 序号 | 音名 | 频率(Hz) |
---|---|---|---|---|---|---|---|---|---|---|---|
49 | a1 | 440.000 | 61 | a2 | 880.000 | 73 | a3 | 1760.000 | 85 | a4 | 3520.000 |
50 | #a1 | 466.164 | 62 | #a2 | 932.328 | 74 | #a3 | 1864.655 | 86 | #a4 | 3729.310 |
51 | b1 | 493.883 | 63 | b2 | 987.767 | 75 | b3 | 1975.533 | 87 | b4 | 3951.066 |
52 | c2 | 523.251 | 64 | c3 | 1046.502 | 76 | c4 | 2093.005 | 88 | c5 | 4186.009 |
53 | #c2 | 554.365 | 65 | #c3 | 1108.731 | 77 | #c4 | 2217.461 | |||
54 | d2 | 587.330 | 66 | d3 | 1174.659 | 78 | d4 | 2349.318 | |||
55 | #d2 | 622.254 | 67 | #d3 | 1244.508 | 79 | #d4 | 2489.016 | |||
56 | e2 | 659.255 | 68 | e3 | 1318.510 | 80 | e4 | 2637.020 | |||
57 | f2 | 698.456 | 69 | f3 | 1396.913 | 81 | f4 | 2793.826 | |||
58 | #f2 | 739.989 | 70 | #f3 | 1479.978 | 82 | #f4 | 2959.955 | |||
59 | g2 | 783.991 | 71 | g3 | 1567.982 | 83 | g4 | 3135.963 | |||
60 | #g2 | 830.609 | 72 | #g3 | 1661.219 | 84 | #g4 | 3322.438 |
其中,以中央A键a1
为基准,其标准频率为440Hz,根据十二平均律,各音阶之间以等比数列分配频率,每12个音阶频率扩大一倍。
简谱的音符是相对音高,它与绝对音高存在映射关系,一共有12个大调音阶:C大调、bD大调、D大调、 bE大调、E大调、F大调、bG大调、 G大调、bA大调、 A大调、bB大调、 B大调。
图1 C大调键位 |
|
节拍决定了每个音符持续的时长。一般约定以500ms左右为一拍,而为了说明每个音符所占时长,又分为全音符、二分音符、四分音符、八分音符、十六分音符等,它们之间存在相对倍数关系。
因此,只需要正确对应每个音符的频率以及节拍,按顺序演奏,即成曲。
原理图分析
蜂鸣器驱动电路
一般IO输出电流小于20mA,不能直接驱动蜂鸣器,需要相应的驱动电路,一般利用三级管的放大和开关作用驱动蜂鸣器。
如图所示,R8用于限制基极电流,R7用于限制蜂鸣器电流,8550为PNP型三极管,当IO引脚为低电平时导通。
对于有源蜂鸣器而言,IO引脚输出低电平就能持续发声。
对于无源蜂鸣器而言,需要IO引脚输出PWM脉冲信号来使之发声。
扬声器驱动电路
单片机开发板上没有扬声器,我在网上买了一个1W 8Ω的小扬声器和一个3W 4Ω的大扬声器,这里的1W指的是额定功率,8Ω指的是额定阻抗,可以大致算出小扬声器的电压有效值为2.8V,大扬声器的电压有效值为3.5V,驱动电路与蜂鸣器类似,记得必须串联一个限流电阻,防止扬声器过热烧毁。
扬声器实际上不分正负极的,但有的扬声器也会有正负极的标识。其主要目的是当两只或两只扬声器以上串联或并联时,若极性接反了,就会大大影响到放音的效果和音量,因为只有在极性相同时扬声器的纸盆的运动方向才会一致,单只扬声器使用可以不考虑极性问题。
软件实现
1. 蜂鸣器短鸣
#include <REG52.H>
#define DELAY_TIME 100
typedef unsigned char u8;
typedef unsigned int u16;
sbit BEEP = P1^5; //信号端与P1.5引脚相连
void delay(u16 i){
while(i--);
}
void main(){
u8 i = 0;
while(1){
while(i < DELAY_TIME){
BEEP = !BEEP; //内部上拉,初始为1,占空比为50%
delay(100); //延时1ms,周期2ms,即频率为500Hz
i++;
}
}
}
通过调节不同的频率,可以得到不同音调的声音;调节占空比,可以控制音量高低。
2. 扬声器演奏音乐
下面程序对于无源蜂鸣器也同样适用,但扬声器音色效果更好。
music.h
#ifndef __MUSIC_H__
#define __MUSIC_H__
#include "delay.h"
// 88个自然音阶频率对应定时器初值
u8 code music_Timer_init[88][2] = {
{0xBE, 0x8C},
{0xC2, 0x38},
{0xC5, 0xB0},
{0xC8, 0xF6},
{0xCC, 0x0C},
{0xCE, 0xF7},
{0xD1, 0xB7},
{0xD4, 0x50},
{0xD6, 0xC4},
{0xD9, 0x15},
{0xDB, 0x44},
{0xDD, 0x54},
{0xDF, 0x46},
{0xE1, 0x1C},
{0xE2, 0xD8},
{0xE4, 0x7B},
{0xE6, 0x06},
{0xE7, 0x7B},
{0xE8, 0xDC},
{0xEA, 0x28},
{0xEB, 0x62},
{0xEC, 0x8A},
{0xED, 0xA2},
{0xEE, 0xAA},
{0xEF, 0xA3},
{0xF0, 0x8E},
{0xF1, 0x6C},
{0xF2, 0x3D},
{0xF3, 0x03},
{0xF3, 0xBE},
{0xF4, 0x6E},
{0xF5, 0x14},
{0xF5, 0xB1},
{0xF6, 0x45},
{0xF6, 0xD1},
{0xF7, 0x55},
{0xF7, 0xD1},
{0xF8, 0x47},
{0xF8, 0xB6},
{0xF9, 0x1F},
{0xF9, 0x82},
{0xF9, 0xDF},
{0xFA, 0x37},
{0xFA, 0x8A},
{0xFA, 0xD9},
{0xFB, 0x23},
{0xFB, 0x68},
{0xFB, 0xAA},
{0xFB, 0xE9},
{0xFC, 0x24},
{0xFC, 0x5B},
{0xFC, 0x8F},
{0xFC, 0xC1},
{0xFC, 0xEF},
{0xFD, 0x1B},
{0xFD, 0x45},
{0xFD, 0x6C},
{0xFD, 0x91},
{0xFD, 0xB4},
{0xFD, 0xD5},
{0xFD, 0xF4},
{0xFE, 0x12},
{0xFE, 0x2D},
{0xFE, 0x48},
{0xFE, 0x60},
{0xFE, 0x78},
{0xFE, 0x8E},
{0xFE, 0xA3},
{0xFE, 0xB6},
{0xFE, 0xC9},
{0xFE, 0xDA},
{0xFE, 0xEB},
{0xFE, 0xFA},
{0xFF, 0x09},
{0xFF, 0x17},
{0xFF, 0x24},
{0xFF, 0x30},
{0xFF, 0x3C},
{0xFF, 0x47},
{0xFF, 0x51},
{0xFF, 0x5B},
{0xFF, 0x64},
{0xFF, 0x6D},
{0xFF, 0x75},
{0xFF, 0x7D},
{0xFF, 0x84},
{0xFF, 0x8B},
{0xFF, 0x92},
};
// 12大调音阶
typedef enum{
C_Major_scale = 0, // C大调
bD_Major_scale, // #C(bD)大调
D_Major_scale, // D大调
bE_Major_scale, // #D(bE)大调
E_Major_scale, // E大调
F_Major_scale, // F大调
bG_Major_scale, // #F(bG)大调
G_Major_scale, // G大调
bA_Major_scale, // #G(bA)大调
A_Major_scale, // A大调
bB_Major_scale, // #A(bB)大调
B_Major_scale, // B大调
}Music_Major_Scale;
// 不同音阶下简谱与频率的索引对应关系
u8 Mapping[3][21] = {
{40, 42, 44, 45, 47, 49, 51, 52, 54, 56, 57, 59, 61, 63, 64, 66, 68, 69, 71, 73, 75},
{0,},
{42, 44, 46, 47, 49, 51, 53, 54, 56, 58, 59, 61, 63, 65, 66, 68, 70, 71, 73, 75, 77},
};
小星星乐谱C大调(0表示休止符, 0xff为结束标志)
//u8 code music[][2] = {
// {8,4} , {8,4} , {12,4}, {12,4},
// {13,4}, {13,4}, {12,2},
// {11,4}, {11,4}, {10,4}, {10,4},
// {9,4} , {9,4} , {8,2} ,
// {12,4}, {12,4}, {11,4}, {11,4},
// {10,4}, {10,4}, {9,2},
// {12,4}, {12,4}, {11,4}, {11,4},
// {10,4}, {10,4}, {9,2},
// 0xff
//};
// 《突然好想你》乐谱D大调(0表示休止符, 0xff为结束标志)
u8 code music[][2] = {
{13,8},{14,8},
{15,4},{17,4},{16,4},{15,8},{16,8},
{12,4},{16,4},{15,4},{13,8},{14,8},
{15,4},{17,4},{16,4},{15,4},
{17,2},{0,4},{13,8},{14,8},
{15,4},{17,4},{16,4},{19,8},{16,8},
{18,8},{17,16},{16,16},{16,16},{17,8},{16,16},{16,16},{15,5},{13,8},{14,8},
{15,4},{17,4},{16,4},{15,4},
{15,1},
0xff
};
#endif
main.c
#include "music.h"
#include "timer.h"
#define MUSIC_SPEED 500
sbit BEEP_PORT = P1^3;
Music_Major_Scale Scale = D_Major_scale; // D大调
u8 num = 0; // 简谱索引
u8 index; // 钢琴谱频率索引
u16 music_delay = 100; // 节拍
int main(void){
TIMERx_init(0, 4608); // 用于控制节拍,5ms
TIMERx_init(1, 0); // 用于输出不同频率的音阶
TR0 = 1;
while(1);
}
// 定时器0的中断服务程序模板
void TIMER0_serve() interrupt 1{
static u16 counter = 0;
u8 music_notation;
TL0 = 0; //低8位
TH0 = 238; //高8位
counter++;
if(counter == music_delay - 1){
// 每拍结束暂停5ms
TR1 = 0;
}else if(counter >= music_delay){
counter = 0;
// 更新乐符
music_notation = music[num][0];
if(music_notation != 0xff){
// 更新节拍
music_delay = MUSIC_SPEED / music[num][1];
if(music_notation != 0){
index = Mapping[Scale][music_notation - 1];
TR1 = 1;
}
// 下一个音符
num++;
}else{
// 关闭,全曲终
TR0 = 0;
TR1 = 0;
}
}
}
// 定时器1的中断服务程序模板
void TIMER1_serve() interrupt 3{
TL1 = music_Timer_init[index][1]; //低8位
TH1 = music_Timer_init[index][0]; //高8位
BEEP_PORT = !BEEP_PORT; // 取反
}
在music.h
文件中,我写了《小星星》和《突然好想你》两个乐谱(部分),各位也可以换成自己喜爱的音乐,按照简谱的规则模仿书写即可(第一列为对应简谱音符,第二列为节拍数)。
在main.c
中,我使用了2个定时器,定时器0用来控制节拍,定时器1用来控制频率。
参数MUSIC_SPEED
可以调整整体音乐的节奏,数值越大,节奏越慢。
参数BEEP_PORT
用于定义蜂鸣器或扬声器的引脚。若使用板载蜂鸣器,则使用P1.5
引脚,若采用外接扬声器,则可选择P1.3
引脚。
总结
本章相对轻松,了解了蜂鸣器和扬声器的主要类别与驱动方式。蜂鸣器与扬声器本身的控制很简单,它也经常和其他元器件一起搭配使用。继续加油!