【PWM】无源蜂鸣器
下载例程代码: 下载代码 如何使用例程【点击查看教程】
PWM 简介
PWM 波形
PWM波形是一种方波信号,是高/低电平不断切换的结果,其波形如图所示,这是3种占空比不同的波形:
PWM的几个关键参数为:
- 频率(Frequency):即高低电平切换的速度,切换的速度越快则频率越高,1000Hz的PWM波意味着1秒钟有1000个脉冲
- 占空比(Duty Cycle):即每个周期内,高电平所占的宽度
- 例如图中
50% duty cycle
,即高/低电平的时间各占50%; - 图中的
75% duty cycle
,高电平占75%,低电平占25%; - 图中的
25% duty cycle
,高电平占25%,低电平占75%;
- 例如图中
PWM 播放音调
通过改变PWM频率,可以输出不同频率的方波信号。用这个信号驱动无源蜂鸣器,便能播放不同频率的声音。
无源蜂鸣器原理
- 学习板上的蜂鸣器型号为:QMB-09B-03电磁式无源蜂鸣器。
- 蜂鸣器内部有一个电磁线圈,能够驱动振动膜片发出声音。通过PWM给蜂鸣器提供不同频率的信号,即可发出不同频率的声音
- 实际操作中,除了控制PWM频率,还需要控制PWM占空比,以使膜片振动趋近于正弦波,从而发出清脆明亮的声音。在学习板上,使用20%占空比可以有较好的响度和音质
如何使用例程
下载程序,即可看到效果
程序效果
- 烧录例程后,按下 KEY1、KEY2 会听到 2kHz、3kHz 的音调
- 可以尝试修改例程代码,产生其他频率的声音
例程讲解
下面介绍了如何自己实现该例程的功能
1、工程配置
- 开启外部晶振:在Pinout&Configuration -> System Core -> RCC 页面,将 High Speed Clock (HSE) 配置为 Crystal/Ceramic Resonator
- 配置时钟频率:在Clock Configuration 页面,将PLL Source 选择为 HSE,将System Clock Mux 选择为 PLLCLK,然后在HCLK (MHz) 输入72并回车,将HCLK频率配置为 72 MHz
分配引脚:在Pinout&Configuration页面,配置如下引脚
将PB9配置为TIM4_CH4,
将PB12、PB13设置为GPIO_Input,并分别设置User Label为KEY1、KEY2
配置GPIO:在Pinout&Configuration -> GPIO,将PB13的GPIO Pull-up/Pull-down配置为Pull-up
配置TIM4:在Pinout&Configuration -> Timers -> TIM4
勾选 Internal Clock,开启 TIM4 的内部时钟源
Configuration -> Mode,将 Channel4 配置为 PWM Generation CH4
Configuration -> Parameter Settings -> Counter Settings,将 Prescaler 配置为 72-1
2、代码
启动PWM输出
HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_4);
在while循环中检测按键并输出相应的频率
htim4.Instance->ARR = 500
可以将 TIM4 的 Counter Period 设置为 500此时,PWM频率 = 72 MHz ÷ 72 ÷ 500 = 2 kHz
__HAL_TIM_SET_COMPARE
可以设置PWM的占空比,将占空比设为 20%,可以确保声音清脆明亮注意:占空比必须小于前面配置的Counter Period,例程中配置为100-1,即占空比可调范围是 0 - 99
while (1)
{
// KEY1按下: 输出2kHz声波
if (!HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin))
{
htim4.Instance->ARR = 500; // 2kHz = 72MHz / 72 / 500
__HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_4, htim4.Instance->ARR / 5); // 20%占空比
}
// KEY2按下: 输出3kHz声波
else if (!HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin))
{
htim4.Instance->ARR = 334; // 3kHz = 72MHz / 72 / 334
__HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_4, htim4.Instance->ARR / 5); // 20%占空比
}
// 否则: 关闭声波输出
else
{
__HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_4, 0);
}
HAL_Delay(100);
}