Stm32f103c8t6学习——2-2.无源蜂鸣器PWM

目录

一、无源蜂鸣器原理图

二、有源蜂鸣器代码

三、项目(代码+仿真)分享链接


一、无源蜂鸣器原理图

二、有源蜂鸣器代码

无源蜂鸣器需要使用PWM驱动,所以应先配置PWM
PWM.c文件

#include "PWM.h" 

/* TIM1四通道 PA8、PA9、PA10、PA11               TIM2四通道 PA0、PA1、PA2、PA3
   TIM3四通道 PA6、PA7、PB0、PB1                 TIM4四通道 PB6、PB7、PB8、PB9  */
	 
void PWM_TIM3_Init(void) //PWM初始化 TIM3
{
	//GPIO的结构体定义,定义一个GPIO类型的结构体,名字为GPIO_InitStructure
	GPIO_InitTypeDef GPIO_InitStructure;
	//TIM_TimeBase的结构体定义,定义一个TIM_TimeBase类型的结构体,名字为TIM_TimeBaseInitStructure
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	//TIM_OC的结构体定义,定义一个TIM_OC类型的结构体,名字为TIM_OCInitStructure
	TIM_OCInitTypeDef TIM_OCInitStructure;
	
	//开启定时器3的时钟,注意是APB1(GPIO的是APB2)
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
	//开启GPIO的时钟,注意是APB2
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	//GPIO引脚的重映射,TIM3_CH1重映射引脚到PB4
	//RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
	//GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM3, ENABLE);
	//GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;		
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure); 
	
	//选择定时器的内部时钟源  TIM3
	TIM_InternalClockConfig(TIM3);
	
	//配置定时器时基单元:TIM_TimeBase
	//选择时钟分频,可以选择1分频、2分频和4分频
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //TIM_CKD_DIV1:1分频
	//选择定时器计数方式,可选择向上计数、向下计数、中心对齐计数
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM_CounterMode_Up:向上计数
	//设置ARR,即定时器周期:TIM_Period,取值0-65535
	TIM_TimeBaseInitStructure.TIM_Period = 100 - 1;		//ARR
	//设置PSC,即定时器预分频器的值:TIM_Prescaler,取值0-65535
	TIM_TimeBaseInitStructure.TIM_Prescaler = 720 - 1;		//PSC
	//高级定时器才用的到,重复计算器,先用不上赋值为0
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	//TIM_TimeBase初始化
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
	
	//初始化配置定时器输出比较单元:TIM_OC
	//设置输出比较的模式:TIM_OCMode_PWM1,PWM1模式
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
	//设置输出比较的极性:TIM_OCPolarity_High;高极性:有效电平为高电平
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
	//设置输出使能
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	//设置捕获比较寄存器 CCR 的值
	TIM_OCInitStructure.TIM_Pulse = 0;		//CCR
	//初始化定时器3通道1
	TIM_OC1Init(TIM3, &TIM_OCInitStructure);
	
	//使能定时器3
	TIM_Cmd(TIM3, ENABLE);
}

void PWM_TIM3_SetCompare1(uint16_t Compare)
{
	 //占空比 Duty = CCR/(ARR+1)
	 TIM_SetCompare1(TIM3, Compare); //设置捕获比较寄存器 CCR 的值,由公式应该取值0-100
}

PWM.h头文件

#ifndef __PWM_H
#define __PWM_H

#include "stm32f10x.h"                  // Device header

void PWM_TIM3_Init(void);
void PWM_TIM3_SetCompare1(uint16_t Compare);

#endif

buzzer.c文件

#include "buzzer.h"  //无源蜂鸣器,PWM驱动

//音符频率定义(单位:Hz)
#define L1 262     //低音Do
#define L2 294     //Re
#define L3 330
#define L4 349
#define L5 392
#define L6 440
#define L7 494

#define M1 523     //中音Do
#define M2 587     //Re
#define M3 659
#define M4 698
#define M5 784
#define M6 880
#define M7 988

#define H1 1047     //高音Do
#define H2 1175     //Re
#define H3 1319
#define H4 1397
#define H5 1568
#define H6 1760
#define H7 1976

//定义节拍(单位:基本时间单位)
typedef enum {    //枚举
  T1 = 300 ,   //四分音符
	T2 = 600 ,     //二分音符
	T05 = 150 ,  //八分音符
	T15 = 450   //附点四分音符
}Beat;

//乐曲数据结构
typedef struct{
	uint16_t freq;  //频率
	uint16_t duration; //持续时间
}Note;

// 一闪一闪亮晶晶简谱
const Note music[] = {
    // 一闪一闪亮晶晶
    {M1,T05}, {M1,T05}, {M5,T05}, {M5,T05}, {M6,T05}, {M6,T05}, {M5,T1},
    // 满天都是小星星
    {M4,T05}, {M4,T05}, {M3,T05}, {M3,T05}, {M2,T05}, {M2,T05}, {M1,T1},
    // 挂在天空放光明
    {M5,T05}, {M5,T05}, {M4,T05}, {M4,T05}, {M3,T05}, {M3,T05}, {M2,T1},
    // 好像许多小眼睛
    {M5,T05}, {M5,T05}, {M4,T05}, {M4,T05}, {M3,T05}, {M3,T05}, {M2,T1},
    // 一闪一闪亮晶晶
    {M1,T05}, {M1,T05}, {M5,T05}, {M5,T05}, {M6,T05}, {M6,T05}, {M5,T1},
    // 满天都是小星星
    {M4,T05}, {M4,T05}, {M3,T05}, {M3,T05}, {M2,T05}, {M2,T05}, {M1,T1},
    
    // 可根据实际乐谱继续补充后续音符...

};

void Buzzer_Init(void){
	PWM_TIM3_Init(); //TIM3 OC1
}

void Buzzer_Freq(uint16_t freq){
	uint32_t arr = (SystemCoreClock / 72)/freq-1; //72分频
	if(freq == 0){
		TIM_SetCompare1(TIM3,0); //关闭输出
		return ;
	}
	TIM_PrescalerConfig(TIM3,72-1,TIM_PSCReloadMode_Immediate);
	TIM_SetAutoreload(TIM3,arr);
	TIM_SetCompare1(TIM3,arr/2);     //50%占空比
}

void Buzzer_PlayMusic(void){
	uint16_t a=0;
	uint16_t notes_count = sizeof(music)/sizeof(Note);
	for(a=0;a<notes_count;a++){
		Buzzer_Freq(music[a].freq);
		delay_ms(music[a].duration);
		delay_ms(100);
		Buzzer_Freq(0); //关闭声音
		delay_ms(50);   
	}
  
}
 

buzzer.h头文件

#ifndef __PWM_H
#define __PWM_H

#include "stm32f10x.h"                  // Device header

void PWM_TIM3_Init(void);
void PWM_TIM3_SetCompare1(uint16_t Compare);

#endif

main.c文件

#include "stm32f10x.h"
#include  "led.h"
#include  "PWM.h"
#include  "Buzzer.h"
#include "delay.h"
	
int main(void)
{ 
	delay_init();
  Buzzer_Init(); //TIM3 OC1
	
	while(1){ 
		Buzzer_PlayMusic();
		delay_ms(500);
	}
}

三、项目(代码+仿真)分享链接

     后续完善

<think>首先,用户的问题是:“我想了解如何使用PWM控制无蜂鸣器请问使用PWM驱动无蜂鸣器的方法”。系统指令要求:所有行内数学表达式使用$...$格式;独立公式使用$$...$$格式并单独成段;确保LaTeX语法正确;使用中文回答;生成相关问题;回答中引用的段落末尾自然地添加引用标识。回顾引用内容:-引用[1]:解释无蜂鸣器需要PWM方波驱动,频率影响音调,占空比影响音量。示例七个基本音调。-引用[2]:基于树莓派的WiringPi库,介绍如何使用PWM控制无蜂鸣器,包括初始化、设置分频、模式、范围。-引用[3]:类似[1],指定音调和频率、占空比值的表。-引用[4]:STM32PWM初始化代码片段。我的回答需要基于这些引用,但要结合用户的问题:如何使用PWM驱动无蜂鸣器。关键点:-蜂鸣器需要外部驱动信号才能发声。-PWM(脉冲宽度调制)方波可以用来驱动它。-频率决定了音调。-占空比影响了音量。-实际操作涉及初始化PWM、设置频率和占空比。回答结构:-逐步解释方法。-使用中文。-如果有数学表达式(如频率计算),使用$...$或$$...$$。-引用相关引用。-最后生成相关问题。大纲回答:1.**引言**:简述无蜂鸣器PWM的关系。2.**基本原理**:解释频率和占空比的作用。-频率:决定音调。公式:频率对应音调(如$f=262\text{Hz}$forDo)。-占空比:影响音量。通常设为50%或基于实验调整。3.**步骤**:如何设置PWM驱动。-初始化硬件。-设置PWM参数:-分频因子(如树莓派示例,divisor)。-PWM模式(如Mark-Space模式)。-范围(周期)。-写入值占空比。4.**代码参考**:引用STM32和树莓派例子,但不提供完整代码,以防超出范围。简要提及。5.**生成相关问题**:在末尾。确保LaTeX正确:-例如,频率公式用$...$:频率$f$对应音调。-独立公式:如占空比公式,但可能不需要复杂的数学。引用末尾添加标识:-当提到引用内容时,如[^1]、[^2]等。最终输出格式:-清晰结构。-相关问题用§§相关问题§§包裹。</think> ### PWM驱动无蜂鸣器的方法 无蜂鸣器需要外部音频驱动信号才能发声,不能像有蜂鸣器那样直接使用直流信号驱动。PWM(脉冲宽度调制)方波是一种常用的驱动方法,因为它能通过调整方波的频率和占空比来控制音调和音量[^1][^3]。以下我将一步步解释如何使用PWM驱动无蜂鸣器,操作基于树莓派和STM32等常见平台(引用内容提供细节),但核心逻辑适用于大多数硬件。 #### 1. **理解基本原理** - **频率控制音调**:方波的频率决定了蜂鸣器发出的音调高低。例如,在乐理中,七个基本音调“哆来咪发梭拉西”对应特定的频率值(单位:Hz): | 音调 | Do | Re | Mi | Fa | So | La | Si | |------|-----|-----|-----|-----|-----|-----|-----| | 频率 | 262 | 294 | 330 | 349 | 392 | 440 | 494 [^3]。 要发出特定音调,需要设置PWM输出该频率的方波。频率的计算基于硬件时钟,通常使用公式: $$ f_{\text{PWM}} = \frac{f_{\text{clock}}}{\text{divisor}} $$ 其中,$f_{\text{clock}}$ 是微控制器的主时钟频率(如树莓派默认19.2 MHz),divisor是分频因子(取值范围一般为2~4095)[^2]。 - **占空比控制音量**:占空比表示方波高电平在一个周期内的占比,影响蜂鸣器的响度。通常设为50%以实现对称波形,提高音量稳定性[^1][^3]。公式化表示为占空比值(range-based): $$ \text{占空比值} = \text{range} \times D $$ 其中,$D$ 是占空比比例(0~1),range是PWM周期参数。例如,如果range=1024,占空比50%时写入value=512。 #### 2. **驱动步骤** 以下是基于引用内容整理的核心操作步骤(以树莓派WiringPi库或STM32为例): - **步骤1:初始化硬件** - 设置微控制器的PWM引脚和初始化库。例如: - **树莓派**:使用`wiringPiSetup()` 或 `wiringPiSetupGpio()`初始化引脚(使用BCM GPIO编号)[^2]。 - **STM32**:通过类似`PWM_TIM3_Init()`函数初始化定时器和PWM通道[^4]。 - 确保权限:树莓派操作通常需要root权限[^2]。 - **步骤2:配置PWM参数** - **设置分频因子(divisor)**:调整divisor值来改变PWM频率,使其匹配目标音调频率。默认divisor=32(树莓派),可动态修改[^2]。计算目标频率divisor公式: $$ \text{divisor} = \frac{f_{\text{clock}}}{f_{\text{PWM}}} $$ 例如,要发出Do(262 Hz),树莓派$f_{\text{clock}} = 19.2 \times 10^6\text{ Hz}$: $$ \text{divisor} = \frac{19.2 \times 10^6}{262} \approx 73282,\text{但需验证在有效范围内(2~4095),实际应用可能使用预分频优化}[^2][^3]。 - **设置PWM模式和范围**: - **模式**:设为Mark-Space模式(占空比模式),而非默认的Balanced模式,以直接控制占空比[^2]。命令如`pwmSetMode(PWM_MODE_MS)`。 - **范围(range)**:定义PWM周期计数值。公式:range = \frac{f_{\text{clock}}}{\text{divisor} \times f_{\text{PWM}}},但通常简化如设置默认1024[^2]。 - **占空比写入**:使用函数如`pwmWrite(pin, value)`,其中value在0~range之间。例如,range=1024,50%占空比则value=512[^2]。 - **步骤3:输出方波驱动蜂鸣器** - 调用PWM输出函数控制引脚。例如: - **树莓派**:`pwmWrite(引脚编号, value)`,value基于占空比计算。 - **STM32**:`PWM_TIM3_SetCompare1(value)`[^4]。 - **时序控制**:每个音调持续输出固定时间(如0.5s),通过循环或定时器实现音阶切换[^1]。 - **示例注意事项**: - **音调循环实现**:编写循环代码,遍历音调频率表(如引用[^3]的表格),依次设置PWM频率和占空比,延时后切换音调。 - **硬件限制**:确保PWM引脚驱动能力匹配蜂鸣器(通常接电阻或驱动器)。 - **参考音调值**:可以直接使用引用提供的频率和占空比计数值表(如Do频率262 Hz,占空比计数值954)来简化开发[^3]。 #### 3. **调试和优化** - **音量调整**:测试不同占空比值(如30%~70%),避免高占空比导致失真。 - **频率精度**:计算divisor时,考虑整数截断问题,使用硬件定时器提高精度。 - **平台通用性**:树莓派和STM32的具体函数不同(如`pwmSetClock` vs `PWM_SetCompare`),但逻辑一致:初始化→设置参数→输出PWM[^2][^4]。 使用PWM驱动无蜂鸣器相对简单,只需正确设置频率和占空比,就能发出多样化的声音,适用于音乐播放、报警系统等场景。实验时可基于引用内容快速验证[^1][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值