news 2026/5/14 10:34:15

别再只让蜂鸣器滴滴响了!手把手教你用STM32的PWM和定时器演奏《两只老虎》

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
别再只让蜂鸣器滴滴响了!手把手教你用STM32的PWM和定时器演奏《两只老虎》

用STM32演奏《两只老虎》:PWM与定时器的创意实践

记得第一次用STM32的GPIO让蜂鸣器发出"滴"声时的兴奋吗?那种控制硬件的成就感让人上瘾。但单调的蜂鸣声很快会失去新鲜感——为什么不试试让开发板唱首歌呢?本文将带你用STM32的PWM和定时器实现《两只老虎》的演奏,从乐理到代码,完整呈现嵌入式开发的趣味实践。

1. 硬件准备与基础原理

手边的STM32开发板(正点原子或野火等常见型号)和无源蜂鸣器就是我们的"乐器"。无源蜂鸣器与有源型号的关键区别在于它没有内置振荡电路,需要外部提供方波信号才能发声。这正是PWM大显身手的地方。

PWM(脉冲宽度调制)通过快速切换高低电平来控制平均电压。对于蜂鸣器来说,PWM的频率决定了音高,而占空比则影响音量。STM32的定时器模块可以精确生成PWM信号:

  • 定时器时钟:STM32F103系列通常以72MHz运行
  • 预分频器:降低基准时钟频率(如分频系数为9时得到8MHz)
  • 自动重装载值:与PWM频率直接相关,计算公式为频率 = 时钟频率/(ARR+1)
// 示例:设置PWM频率为440Hz(标准A4音高) uint16_t clock_freq = 8000000; // 8MHz (72MHz/9) uint16_t arr_value = (clock_freq / 440) - 1; __HAL_TIM_SET_AUTORELOAD(&htim4, arr_value);

2. 从乐谱到代码的转换艺术

《两只老虎》的简谱是我们编程的蓝图。每个音符需要转换为:

  1. 频率值:对应PWM的ARR设置
  2. 节拍时长:由定时器中断控制

建立音符频率对照表是第一步。国际标准音高A4=440Hz,其他音符按十二平均律计算:

音符频率(Hz)代码常量
C4262NOTE_C4
D4294NOTE_D4
E4330NOTE_E4
F4349NOTE_F4
G4392NOTE_G4
A4440NOTE_A4
B4494NOTE_B4

《两只老虎》前两小节的编码示例:

uint8_t melody[] = {NOTE_C4, NOTE_D4, NOTE_E4, NOTE_C4}; // 音符序列 uint8_t rhythm[] = {4, 4, 4, 4}; // 四分音符时长

3. 定时器编排音乐节奏

单独的PWM只能产生持续音,需要定时器来管理节拍切换。配置一个定时器(如TIM2)产生1ms中断,用于音符时长计数:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim->Instance == TIM2) { static uint16_t counter = 0; if (++counter >= current_note_duration) { counter = 0; play_next_note(); // 切换到下一个音符 } } }

节拍时长计算要考虑曲速。假设《两只老虎》速度为120BPM(每分钟120拍),则:

  • 四分音符时长 = 60000ms / 120 = 500ms
  • 在代码中用定时器中断次数实现(如500次1ms中断)

4. 完整实现与优化技巧

将各个模块整合,音乐播放流程如下:

  1. 初始化PWM定时器(TIM4)和节拍定时器(TIM2)
  2. 加载《两只老虎》的音符和节拍数据
  3. 启动定时器中断
  4. 在中断服务程序中管理音符切换

高级优化技巧

  • 动态音量控制:通过调整PWM占空比实现强弱变化
void set_volume(uint8_t vol) { uint16_t pulse = (ARR_value * vol) / 100; __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_2, pulse); }
  • 多曲目管理:使用结构体数组存储不同歌曲
typedef struct { uint8_t *notes; uint8_t *durations; uint16_t length; uint16_t tempo; } Song; Song songs[] = { {two_tiger_notes, two_tiger_durations, sizeof(two_tiger_notes), 120}, // 添加更多歌曲... };
  • 按键控制:通过外部中断实现播放/暂停/切歌

实际项目中,我遇到过因中断优先级设置不当导致音乐卡顿的情况。调试发现TIM2的中断优先级低于其他外设中断,调整NVIC设置后问题解决:

HAL_NVIC_SetPriority(TIM2_IRQn, 0, 0); // 设置为最高优先级

5. 创意扩展与实践建议

掌握了基础播放功能后,可以尝试:

  1. LED视觉同步:让LED随音乐节奏闪烁
  2. 录音功能:通过ADC采集音频并记录音符序列
  3. 无线控制:通过蓝牙或WiFi远程选曲
  4. 和弦效果:使用多个定时器同时产生不同频率

建议先用示波器观察PWM输出波形,确认频率准确后再连接蜂鸣器。不同型号蜂鸣器的最佳工作频率可能略有差异,可通过微调ARR值获得最佳音质。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/14 10:33:25

ADRecon在企业安全评估中的10个最佳实践

ADRecon在企业安全评估中的10个最佳实践 【免费下载链接】ADRecon ADRecon is a tool which gathers information about the Active Directory and generates a report which can provide a holistic picture of the current state of the target AD environment. 项目地址:…

作者头像 李华
网站建设 2026/5/14 10:33:20

如何让PPT演示时间掌控如呼吸般自然:PPTTimer智能计时器使用指南

如何让PPT演示时间掌控如呼吸般自然:PPTTimer智能计时器使用指南 【免费下载链接】ppttimer 一个简易的 PPT 计时器 项目地址: https://gitcode.com/gh_mirrors/pp/ppttimer 你是否曾在重要汇报时因为超时而被打断思路?或者在技术分享中因为时间不…

作者头像 李华
网站建设 2026/5/14 10:26:19

深度解析:如何高效使用Poppins字体实现多语言排版系统

深度解析:如何高效使用Poppins字体实现多语言排版系统 【免费下载链接】Poppins Poppins, a Devanagari Latin family for Google Fonts. 项目地址: https://gitcode.com/gh_mirrors/po/Poppins Poppins是一款专为现代设计打造的开源几何无衬线字体&#xf…

作者头像 李华
网站建设 2026/5/14 10:25:22

渐渐被 AI 淘汰的 5 类程序员,这里面有你吗?

01 危机,已经来了以前,写一个后台管理系统,你得花3天时间:画设计图、搭框架、写增删改查、调接口、修Bug。现在不一样了,用AI,30分钟就能生成骨架,2小时调通逻辑,剩下的时间都能用来…

作者头像 李华