news 2026/4/22 22:29:42

STM32F103C8T6驱动无源蜂鸣器播放《两只老虎》完整教程(附源码)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
STM32F103C8T6驱动无源蜂鸣器播放《两只老虎》完整教程(附源码)

STM32F103C8T6驱动无源蜂鸣器播放《两只老虎》完整教程(附源码)

蜂鸣器作为嵌入式开发中最基础的外设之一,常被用于系统报警、状态提示等场景。但你是否想过,通过精确控制PWM频率和节奏,可以让这个简单的元件演奏出熟悉的旋律?本文将带你用STM32的TIM定时器,实现无源蜂鸣器播放《两只老虎》的完整过程。

1. 硬件准备与原理分析

1.1 无源蜂鸣器工作特性

无源蜂鸣器与有源蜂鸣器的核心区别在于驱动方式:

  • 有源蜂鸣器:内置振荡电路,只需提供直流电压即可发声
  • 无源蜂鸣器:需要外部提供方波信号才能工作

音乐播放场景必须使用无源蜂鸣器,因为:

  1. 音高由驱动频率决定(C4=261Hz,D4=294Hz等)
  2. 音长由信号持续时间控制
  3. 可通过PWM精确调节波形特性

1.2 STM32的PWM生成机制

STM32F103C8T6通过TIM定时器产生PWM信号的关键配置参数:

参数作用计算公式
ARR (Auto-reload)决定PWM周期频率 = 定时器时钟/(PSC+1)/(ARR+1)
PSC (Prescaler)时钟预分频系数实际时钟 = 72MHz/(PSC+1)
CCR (Capture Compare)决定占空比占空比 = CCR/(ARR+1)

提示:音乐播放时通常固定50%占空比,重点调节ARR值改变频率

2. 音乐编程基础

2.1 音阶频率对照表

《两只老虎》主要使用中音区(C4-B4)的七个基本音阶:

音符频率(Hz)计算值(ARR) @PSC=71
C4261.633830
D4293.663412
E4329.633040
F4349.232870
G4392.002558
A4440.002279
B4493.882032

计算公式:

ARR = (72000000 / (PSC+1)) / frequency - 1 = (72000000 / 72) / frequency - 1 = 1000000 / frequency - 1

2.2 节拍时间控制

四四拍歌曲的典型节拍时长(BPM=120时):

节拍类型持续时间(ms)
全音符2000
二分音符1000
四分音符500
八分音符250

《两只老虎》简谱对应的节拍序列:

C4(1) D4(1) E4(1) C4(1) | C4(1) D4(1) E4(1) C4(1) | E4(1) F4(1) G4(2) | E4(1) F4(1) G4(2) | G4(0.5) A4(0.5) G4(0.5) F4(0.5) E4(1) C4(1) | G4(0.5) A4(0.5) G4(0.5) F4(0.5) E4(1) C4(1) | C4(1) G3(1) C4(2) | C4(1) G3(1) C4(2) |

3. 工程实现步骤

3.1 硬件连接

使用STM32F103C8T6最小系统板与无源蜂鸣器模块连接:

蜂鸣器+ → PA0 (TIM2_CH1) 蜂鸣器- → GND

注意:无源蜂鸣器没有极性,但需串联100Ω限流电阻

3.2 代码实现

3.2.1 PWM初始化配置
// pwm.h #define BUZZER_TIM TIM2 #define BUZZER_CHANNEL TIM_CHANNEL_1 void PWM_Init(void); void PWM_SetFreq(uint16_t freq); void PWM_PlayNote(uint16_t freq, uint32_t duration);
// pwm.c #include "stm32f10x.h" void PWM_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; TIM_TimeBaseInitTypeDef TIM_InitStruct; TIM_OCInitTypeDef TIM_OCInitStruct; // 1. 开启时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // 2. 配置GPIO GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStruct); // 3. 配置定时器基础 TIM_InitStruct.TIM_Period = 999; // 初始10kHz TIM_InitStruct.TIM_Prescaler = 71; // 72MHz/72=1MHz TIM_InitStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_InitStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(BUZZER_TIM, &TIM_InitStruct); // 4. 配置PWM输出 TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStruct.TIM_Pulse = 500; // 50%占空比 TIM_OC1Init(BUZZER_TIM, &TIM_OCInitStruct); TIM_Cmd(BUZZER_TIM, ENABLE); } void PWM_SetFreq(uint16_t freq) { uint16_t arr = (uint16_t)(1000000 / freq) - 1; TIM_SetAutoreload(BUZZER_TIM, arr); TIM_SetCompare1(BUZZER_TIM, arr / 2); // 保持50%占空比 }
3.2.2 音乐播放逻辑
// music.h typedef struct { uint16_t freq; uint16_t duration; } Note; #define TEMPO 120 // BPM #define QUARTER_NOTE (60000 / TEMPO) extern const Note song[]; extern const uint16_t song_length;
// music.c #include "music.h" const Note song[] = { {262, QUARTER_NOTE}, // C4 {294, QUARTER_NOTE}, // D4 {330, QUARTER_NOTE}, // E4 {262, QUARTER_NOTE}, // C4 // ... 完整乐谱 }; const uint16_t song_length = sizeof(song)/sizeof(Note);
3.2.3 主程序
// main.c #include "stm32f10x.h" #include "pwm.h" #include "music.h" #include "delay.h" int main(void) { Delay_Init(); PWM_Init(); while(1) { for(int i=0; i<song_length; i++) { PWM_SetFreq(song[i].freq); Delay_ms(song[i].duration); } PWM_SetFreq(0); // 停止发声 Delay_ms(2000); // 间隔2秒 } }

4. 进阶优化技巧

4.1 节拍精度提升

使用SysTick定时器替代Delay_ms实现更精确的节奏控制:

void SysTick_Handler(void) { static uint32_t counter = 0; if(counter++ >= note_duration) { counter = 0; play_next_note(); } }

4.2 多任务处理

在RTOS环境中创建独立播放任务:

void buzzer_task(void *params) { while(1) { play_song(&two_tigers); vTaskDelay(pdMS_TO_TICKS(5000)); } } xTaskCreate(buzzer_task, "Buzzer", 128, NULL, 2, NULL);

4.3 音效增强

通过调制PWM占空比实现音色变化:

void PWM_SetEnvelope(uint16_t freq, uint16_t duration) { // 淡入效果 for(int i=1; i<=10; i++) { TIM_SetCompare1(BUZZER_TIM, (ARR/i)); Delay_ms(duration/20); } // 淡出效果 for(int i=10; i>=1; i--) { TIM_SetCompare1(BUZZER_TIM, (ARR/i)); Delay_ms(duration/20); } }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/22 22:29:41

AI Agent Harness Engineering 创业时间规划:从idea到产品上线的关键节点

AI Agent Harness Engineering 创业时间规划:从idea到产品上线的关键节点 关键词 AI Agent, Harness Engineering, 创业时间规划, 产品开发周期, 人工智能应用, 系统架构, 敏捷开发 摘要 在人工智能快速发展的今天,AI Agent(智能代理)正成为创业领域的热点。本文将深入…

作者头像 李华
网站建设 2026/4/22 22:29:10

Inpaint 图片去水印软件下载和使用教程 支持去除豆包水印

Inpaint 图片去水印软件下载和使用教程 支持去除豆包水印 关键词&#xff1a;图片去水印软件、Inpaint下载、去水印工具推荐、图片修复软件、AI去水印教程 资源名称下载链接Inpaint v9.1.0https://dooo.fun/archives/1612 一、前言&#xff1a;一次真实需求让我找到它 平时做技…

作者头像 李华
网站建设 2026/4/22 22:26:47

告别闪退和key不显示!JDK 1.8 + BurpSuite v2.1 中文版完整配置避坑指南

JDK 1.8与BurpSuite v2.1中文版实战配置全解 第一次打开BurpSuite时&#xff0c;那个熟悉的闪退界面和消失的密钥输入框&#xff0c;让多少安全测试新手在深夜对着屏幕陷入沉思。这不是个例——据统计&#xff0c;超过60%的BurpSuite安装问题都源于Java环境配置不当。本文将彻底…

作者头像 李华
网站建设 2026/4/22 22:25:46

Adobe-GenP 3.0:Adobe全家桶通用补丁终极指南

Adobe-GenP 3.0&#xff1a;Adobe全家桶通用补丁终极指南 【免费下载链接】Adobe-GenP Adobe CC 2019/2020/2021/2022/2023 GenP Universal Patch 3.0 项目地址: https://gitcode.com/gh_mirrors/ad/Adobe-GenP Adobe-GenP 3.0是一款专为Adobe Creative Cloud系列软件设…

作者头像 李华
网站建设 2026/4/22 22:24:53

和美智健:远程诊疗联动专家,家门口开启“三甲级”健康服务新时代

医疗资源分布不均、基层诊疗能力不足&#xff0c;一直是困扰我国医疗体系的难题。如何让居民无需奔波&#xff0c;在家门口就能获得三甲医院专家的诊疗服务?河南智健医疗科技有限公司的创新突破给出了答案--通过多功能健康管理一体机&#xff0c;联动家庭签约医生与三甲医院专…

作者头像 李华