无源蜂鸣器驱动代码例程
硬件连接
| MCU引脚 |
连接 |
| GPIO PA0 (TIM2_CH1) |
→ 1kΩ电阻 → S8050基极 |
| S8050集电极 |
→ 蜂鸣器(-) |
| 蜂鸣器(+) |
→ VCC (3.3V/5V) |
| S8050发射极 |
→ GND |
例程一:Arduino 环境
#define BUZZER_PIN 9
#define NOTE_C4 262
#define NOTE_D4 294
#define NOTE_E4 330
#define NOTE_F4 349
#define NOTE_G4 392
#define NOTE_A4 440
#define NOTE_B4 494
#define NOTE_C5 523
#define NOTE_0 0 // 休止符
int melody[] = {
NOTE_C4, NOTE_C4, NOTE_G4, NOTE_G4,
NOTE_A4, NOTE_A4, NOTE_G4,
NOTE_F4, NOTE_F4, NOTE_E4, NOTE_E4,
NOTE_D4, NOTE_D4, NOTE_C4,
NOTE_G4, NOTE_G4, NOTE_F4, NOTE_F4,
NOTE_E4, NOTE_E4, NOTE_D4,
NOTE_G4, NOTE_G4, NOTE_F4, NOTE_F4,
NOTE_E4, NOTE_E4, NOTE_D4,
NOTE_C4, NOTE_C4, NOTE_G4, NOTE_G4,
NOTE_A4, NOTE_A4, NOTE_G4,
NOTE_F4, NOTE_F4, NOTE_E4, NOTE_E4,
NOTE_D4, NOTE_D4, NOTE_C4
};
int noteDurations[] = {
4, 4, 4, 4, 4, 4, 2,
4, 4, 4, 4, 4, 4, 2,
4, 4, 4, 4, 4, 4, 2,
4, 4, 4, 4, 4, 4, 2,
4, 4, 4, 4, 4, 4, 2,
4, 4, 4, 4, 4, 4, 2
};
void setup() {
pinMode(BUZZER_PIN, OUTPUT);
Serial.begin(9600);
Serial.println("无源蜂鸣器测试开始");
}
void loop() {
for (int i = 0; i < sizeof(melody) / sizeof(melody[0]); i++) {
int noteDuration = 1000 / noteDurations[i];
if (melody[i] != NOTE_0) {
tone(BUZZER_PIN, melody[i], noteDuration);
}
delay(noteDuration * 1.3); // 音符间加间隔
noTone(BUZZER_PIN);
}
delay(2000); // 循环间隔
}
void buzzerBeep(uint16_t frequency, uint32_t duration_ms) {
if (frequency > 0) {
tone(BUZZER_PIN, frequency, duration_ms);
}
}
void buzzerStop(void) {
noTone(BUZZER_PIN);
}
void buzzerShortBeep(void) {
tone(BUZZER_PIN, 2300, 100);
}
void buzzerAlarm(uint8_t repeat) {
for (uint8_t i = 0; i < repeat; i++) {
tone(BUZZER_PIN, 2000, 200);
delay(250);
tone(BUZZER_PIN, 3000, 200);
delay(250);
}
noTone(BUZZER_PIN);
}
例程二:STM32 HAL 库(PWM 方式)
#include "main.h"
#include <math.h>
#define C4 262
#define D4 294
#define E4 330
#define F4 349
#define G4 392
#define A4 440
#define B4 494
#define C5 523
TIM_HandleTypeDef htim2;
static uint8_t buzzer_enabled = 0;
void Buzzer_PWM_Init(void) {
__HAL_RCC_TIM2_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF1_TIM2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
htim2.Instance = TIM2;
htim2.Init.Prescaler = 72 - 1; // 72MHz / 72 = 1MHz
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 1000 - 1; // 默认1kHz
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
HAL_TIM_PWM_Init(&htim2);
TIM_OC_InitTypeDef sConfigOC = {0};
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 500; // 50%占空比
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1);
}
void Buzzer_SetFrequency(uint16_t freq) {
if (freq == 0) {
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_1);
buzzer_enabled = 0;
return;
}
uint32_t arr = 1000000UL / freq - 1; // ARR = 1MHz/freq - 1
if (arr < 10) arr = 10;
if (arr > 65535) arr = 65535;
__HAL_TIM_SET_AUTORELOAD(&htim2, arr);
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, arr / 2); // 50%占空比
if (!buzzer_enabled) {
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
buzzer_enabled = 1;
}
}
void Buzzer_Beep(uint16_t freq, uint32_t duration_ms) {
Buzzer_SetFrequency(freq);
HAL_Delay(duration_ms);
Buzzer_SetFrequency(0);
}
void Buzzer_Stop(void) {
Buzzer_SetFrequency(0);
}
void Buzzer_PlayMelody(const uint16_t *notes, const uint8_t *durations,
uint8_t length, uint8_t tempo) {
for (uint8_t i = 0; i < length; i++) {
uint32_t note_ms = (60000UL / tempo) / durations[i];
if (notes[i] > 0) {
Buzzer_Beep(notes[i], note_ms * 0.9);
}
HAL_Delay(note_ms * 0.1); // 音符间隔
}
}
const uint16_t twinkle_notes[] = {
C4, C4, G4, G4, A4, A4, G4, 0,
F4, F4, E4, E4, D4, D4, C4, 0
};
const uint8_t twinkle_durs[] = {
4, 4, 4, 4, 4, 4, 2, 8,
4, 4, 4, 4, 4, 4, 2, 8
};
int main(void) {
HAL_Init();
SystemClock_Config();
Buzzer_PWM_Init();
while (1) {
Buzzer_Beep(2300, 200); // 2.3kHz 200ms
HAL_Delay(500);
Buzzer_PlayMelody(twinkle_notes, twinkle_durs, 16, 120);
HAL_Delay(2000);
}
}
例程三:ESP8266 (Arduino) 非阻塞驱动
#include <Ticker.h>
#define BUZZER_PIN 4 // D2 = GPIO4
Ticker buzzerTicker;
volatile bool isPlaying = false;
void buzzerToggle() {
static uint8_t state = 0;
state = !state;
digitalWrite(BUZZER_PIN, state);
}
void buzzerBeepNonBlocking(uint16_t freq, uint32_t duration_ms) {
if (freq == 0 || duration_ms == 0) return;
float period_us = 1000000.0f / freq;
float half_period_us = period_us / 2.0f;
isPlaying = true;
buzzerTicker.attach_us(half_period_us, buzzerToggle);
Ticker stopTicker;
stopTicker.once_ms(duration_ms, []() {
buzzerTicker.detach();
digitalWrite(BUZZER_PIN, LOW);
isPlaying = false;
});
}
void setup() {
pinMode(BUZZER_PIN, OUTPUT);
digitalWrite(BUZZER_PIN, LOW);
Serial.begin(115200);
}
void loop() {
buzzerBeepNonBlocking(2300, 200);
delay(1000);
}