跳到主要内容

【PWM】蜂鸣器实验

本节实例我们将学习蜂鸣器,并用蜂鸣器制作电子琴

实验原理

当涉及到蜂鸣器时,我们通常会遇到两种类型:无源蜂鸣器和有源蜂鸣器。它们在工作原理和使用方式上有所不同

有源蜂鸣器(Active Buzzer)

有源蜂鸣器是一种集成了驱动电路的蜂鸣器,它可以直接通过电流激励产生声音,不需要外部设备。有源蜂鸣器内部集成了振片、驱动电路和共振腔。当给有源蜂鸣器提供电流时,它会根据电流的变化产生声音。 有源蜂鸣器通常具有更好的声音质量和音量控制能力。在使用有源蜂鸣器时,我们可以通过控制电流的大小和频率来控制蜂鸣器的声音。一般来说,我们可以通过改变输入电流的大小来调整音量,通过改变输入电流的频率来调整音调和音乐效果

1
注意

这里的 不是指电源,而是指震荡源

无源蜂鸣器

无源蜂鸣器是一种简单的声音发生器,它通常由振片和共振腔组成。无源蜂鸣器不具备驱动电路,因此需要外部的电子设备来产生声音。当给无源蜂鸣器施加交变电压时,振片会振动并产生声音。 无源蜂鸣器的工作频率由施加的电压频率决定。在使用无源蜂鸣器时,我们需要通过控制电压的频率和占空比来控制蜂鸣器的声音。通过改变交变电压的频率和占空比,我们可以产生不同的音调和音乐效果

1

需要注意的是,无论是无源蜂鸣器还是有源蜂鸣器,其工作电压和电流都需要在规定范围内,以免损坏蜂鸣器或引起其他问题

总结起来,无源蜂鸣器和有源蜂鸣器是两种常见的蜂鸣器类型。无源蜂鸣器需要外部设备来产生声音,而有源蜂鸣器内部集成了驱动电路,可以直接产生声音。在使用时,我们通过控制电压的频率、占空比或电流的大小和频率来控制蜂鸣器的声音

硬件电路设计

物料清单(BOM 表):

材料名称数量
按键开关6
无源蜂鸣器1
有源蜂鸣器1
杜邦线(跳线)若干
面包板1

有源蜂鸣器正极接 D22,无源蜂鸣器正极接 D23;6 个按键依次接 D25,D26,D27,D14,D12,D13

1

软件程序设计

1. 有源蜂鸣器定时闹钟

我们可以通过外部中断和定时器中断来制作一个闹钟,按下按键时中断闹钟

#define BUTTON  13
#define BUZZER 22


hw_timer_t *timer = NULL;

// 初始化闹钟触发时间
int second = 5;

// 定时器中断处理函数
void timer_interrupt(){
digitalWrite(BUZZER, HIGH);
}

// 外部中断处理函数
void handle_interrupt(){
digitalWrite(BUZZER, LOW);
}

void setup() {
// 配置引脚模式
pinMode(BUTTON, INPUT_PULLUP);
pinMode(BUZZER, OUTPUT);

// 初始化定时器
timer = timerBegin(0,80,true);

// 配置定时器
timerAttachInterrupt(timer,timer_interrupt,true);

// 定时模式
timerAlarmWrite(timer,second*1000*1000,false);

// 启动定时器
timerAlarmEnable(timer);

// 配置外部中断引脚
attachInterrupt(digitalPinToInterrupt(BUTTON), handle_interrupt, FALLING);

}

void loop() {

}

2. 6音符电子琴

我们想要弹奏一首歌就需要他的乐谱,最简单的就是小星星,

1

蜂鸣器是通过不同的频率发出不同声调的,具体对应数值如下图:

1

我们可以按照上图乐谱,用 6 个按键分别控制不同的音符,代码如下:

#define BUZZER      23
#define CHANNEL 0
#define RESOLUTION 8
#define FREQ 20000


// 定义按键数组
int button_array[6] = {25, 26, 27, 14, 12, 13};

// 定义音符频率数组
int tone_array[7] = {262, 294, 330, 350, 393, 441, 495};

// 初始化发声频率
int tone_value = 0;

void setup() {
// 配置引脚模式
pinMode(BUZZER, OUTPUT);

for (int i=0;i<6;i++) {
pinMode(button_array[i], INPUT_PULLUP);
}

// LEDC 外设
ledcSetup(CHANNEL, FREQ, RESOLUTION);
ledcAttachPin(BUZZER, CHANNEL);
}

void loop() {
// 检测按键是否按下
for (int i=0;i<6;i++) {
if (!digitalRead(button_array[i])) {
tone_value = tone_array[i];
}
}

// 蜂鸣器发声
ledcWriteTone(CHANNEL, tone_value);

tone_value = 0;
delay(10);
}

3. 播放音乐

我们也可以自动播放这首歌,代码如下:

#define BUZZER      23
#define CHANNEL 0
#define RESOLUTION 8
#define FREQ 20000


// 定义音符频率数组
int tone_array[8] = {0, 262, 294, 330, 350, 393, 441, 495};

// 乐谱
int music[] = {1, 1, 5, 5, 6, 6, 5, 0,
4, 4, 3, 3, 2, 2, 1, 0,
5, 5, 4, 4, 3, 3, 2, 0,
5, 5, 4, 4, 3, 3, 2, 0,
1, 1, 5, 5, 6, 6, 5, 0,
4, 4, 3, 3, 2, 2, 1, 0};

// 初始化发声频率
int tone_value = 0;

void setup() {
// 配置引脚模式
pinMode(BUZZER, OUTPUT);

// LEDC 外设
ledcSetup(CHANNEL, FREQ, RESOLUTION);
ledcAttachPin(BUZZER, CHANNEL);
}

void loop() {
for (int i=0; i<sizeof(music)/sizeof(music[0]);i++) {
ledcWriteTone(CHANNEL, tone_array[music[i]]);
delay(500);
}

delay(2000);
}