【let's do|2026年第3期】音乐盒
本文介绍了 Let's Do|2026年第3期 活动,使用 NUCLEO-C562RE 开发板驱动无源蜂鸣器实现音乐播放的项目设计。
项目介绍
NUCLEO-C562RE 开发板结合定时器产生 PWM 信号驱动无源蜂鸣器,实现音乐播放的项目设计。
准备工作:模块介绍、硬件连接、环境搭建;
工程测试:工程配置、关键代码、编译上传、效果演示。


模块介绍
Grove - 蜂鸣器模块的主要组件是一个压电蜂鸣器。压电蜂鸣器可以连接到数字输出,当输出为高电平时会发出音调。或者,它可以连接到模拟脉宽调制输出以生成各种音调和效果。


原理图


详见:Grove - 蜂鸣器 | Seeed Studio Wiki .
硬件连接
根据开发板原理图,定时器 1 和频道 1 对应 PA8 引脚,可将该其作为 PWM 信号产生引脚。


接线方式
| NUCLEO-C562RE | Buzzer | Note |
| PA8 (D7) | SIG | Signal |
| GND | GND | Ground |
| 3V3 | VCC | Power supply |
实物图


工程配置
打开 STM32CubeMX2 软件,从开发板新建工程;
点击左侧工具栏 Open Peripherals 按钮,展开 Timers ,将预分频器配置为1毫秒的时间基准。


使用标准公式:频率 = f_clk / [(PSC + 1) × (ARR + 1)],即
计算步骤:
1.(Prescaler 预分频器):143 + 1 = 144
2.(Period 周期):999 + 1 = 1,000
3.(Total Divisor 总除数):144 × 1,000 = 144,000
4.(Final Result 最终结果):144,000,000 / 144,000 = 1,000 Hz(1 kHz)
固定 PSC=0、占空比 50%,则:
使能 PWM 后,ARR 和 CCR 可通过程序更改,进而改变 音调 和 音量 。
设置通道,启用 CH1,输出模式,比较模式设置为 PWM mode 1,脉冲为 0,使能通道1,使能 GPIO 引脚;


将 TIM1 的 CH1 引脚配置为 PA8 ;


开启定时器中断


保存配置,生成 CMake工程;
详见:【let's_do|2026年第3期】介绍、环境搭建、工程测试 .
导入 IDE
打开 STM32CubeIDE 软件,依次选择 File - Import ,选择 STM32 CMake Project ,选择目标工程文件所在路径;
配置工具链,选择主控芯片型号 STM32C562RETx ;
待导入完成,点击工具栏 小锤子 按钮,编译工程,无报错。
或使用 VS Code 软件打开目标文件夹,编译工程。


流程图

工程代码
打开 main.c 文件,添加如下代码
#include "main.h"
/* 音符频率表(C 调) */
static const uint16_t mytone[8] = {262, 294, 330, 349, 392, 440, 494, 523};
#define BEAT_MS 300 // 节拍 300ms
#define CNT_CLK 1000000UL
/* -------------------------
* 设置 PWM 频率
* ---------------- */
static void pwm_set_freq(uint32_t freq)
{
hal_tim_handle_t *htim = mx_tim1_gethandle();
if (freq == 0U)
{
HAL_TIM_OC_SetCompareUnitPulse(htim, HAL_TIM_OC_COMPARE_UNIT_1, 0U); // 静音
return;
}
/* ARR = CNT_CLK / freq - 1 */
uint32_t arr = CNT_CLK / freq;
if (arr < 2U) arr = 2U;
if (arr > 0x10000UL) arr = 0x10000UL;
HAL_TIM_SetPeriod(htim, arr - 1U); // ARR → 频率
HAL_TIM_OC_SetCompareUnitPulse(htim, HAL_TIM_OC_COMPARE_UNIT_1, arr / 2U); // 50% 占空比
}
/* 设置音符:x = 1~8 为音符,其它 → 休止 */
static void set_note(uint8_t x)
{
pwm_set_freq((x >= 1U && x <= 8U) ? mytone[x - 1] : 0U);
}
/* 播放一个音符:x 音符,beats 节拍数 */
static void play_note(uint8_t x, uint8_t beats)
{
set_note(x); // 发音
HAL_Delay(BEAT_MS * beats);
set_note(0); // 停顿 1 拍
HAL_Delay(BEAT_MS);
}
int main(void)
{
if (mx_system_init() != SYSTEM_OK){
return (-1);
}
else{
/* 启动 TIM1_CH1 PWM 输出 */
HAL_TIM_OC_StartChannel(mx_tim1_gethandle(), HAL_TIM_CHANNEL_1); // 启用CH1
HAL_TIM_Start(mx_tim1_gethandle());
set_note(0); // 上电静音
/* 小星星乐谱:(音调, 节拍) */
const uint8_t mymusic[][2] = {
{1,1},{1,1},{5,1},{5,1},{6,1},{6,1},{5,2},{4,1},{4,1},
{3,1},{3,1},{2,1},{2,1},{1,2},{5,1},{5,1},{4,1},{4,1},
{3,1},{3,1},{2,2},{5,1},{5,1},{4,1},{4,1},{3,1},
{3,1},{2,2},{1,1},{1,1},{5,1},{5,1},{6,1},{6,1},
{5,2},{4,1},{4,1},{3,1},{3,1},{2,1},{2,1},{1,2}
};
uint32_t n = sizeof(mymusic) / sizeof(mymusic[0]);
for (uint32_t i = 0; i < n; i++)
{
play_note(mymusic[i][0], mymusic[i][1]);
}
set_note(0); // 结束静音
while (1) {}
}
} /* end main */保存代码。
编译上传
点击 VS Code 左侧菜单栏的 调试运行 按钮,创建 launch.json 调试文件,选择 STLINK,默认配置保存;


点击运行按钮,自动编译工程并进入调试状态,点击条状悬浮窗的运行按钮,开始运行程序;


效果演示


音频播放效果见 https://pan.baidu.com/s/1045h4lmPyKIPXwn891MQkA?pwd=1234
总结
本文介绍了 Let's Do|2026年第3期 活动,使用 NUCLEO-C562RE 开发板驱动无源蜂鸣器实现音乐播放的项目设计,为相关项目的快速开发和应用设计提供了参考。

我要赚赏金
