一、使用硬件介绍
无源蜂鸣器外形及原理图如下所示;

单片机型号为STM32F103C8T6;
二、PWM驱动程序
使用STM32CubeMX配置、频率及占空比的计算公式,可参考STM32单片机输出频率及占空比可调的PWM波;
使用定时器TIM1的Channel 1作为PWM通道,时钟为72MHz,配置PSC为72-1,这样当ARR从0~65535变化时,可以得到约15Hz-1MHz的频率,如果想要其他频率,则可以修改PSC的值;
一般无源蜂鸣器的共振频率为2000Hz或4000Hz,笔者设置默认频率为4000Hz,占空比为50%;
将需要用到的变量封装在一个结构体,放在头文件中:
c
typedef struct
{
uint16_t u16OnMs;//一个鸣叫周期内声音开启时间
uint16_t u16OffMs;//一个鸣叫周期内声音关闭时间
uint8_t u8Cycles;//重复次数
uint8_t u8CycleCnt;//次数计数
uint16_t u16CycleMs;//每个周期计时,单位ms
bool bStart:1;//鸣叫开始标志
bool bBeeping:1;//正在鸣叫标志
uint8_t Reserved:6;//保留
}BuzPara_ts;
蜂鸣器驱动c文件中的程序:
c
#include "PWM.h"
#include "Buzzer.h"
#include <string.h>
#define BUZZER_PWM_FREQUENCY 4000//共振频率
#define BUZZER_PWM_DUTY_CYCLE 50//占空比
static BuzPara_ts sBuzzer_Para;
/*******************************************************************************
* 函数名:Buzzer_Start
* 功 能:初始化
* 参 数:无
* 返回值:无
* 说 明:无
*******************************************************************************/
void Buzzer_Start(void)
{
PWM_Config(BUZZER_PWM_FREQUENCY, BUZZER_PWM_DUTY_CYCLE);
PWM_Start();
}
/*******************************************************************************
* 函数名:Buzzer_Stop
* 功 能:初始化
* 参 数:无
* 返回值:无
* 说 明:无
*******************************************************************************/
void Buzzer_Stop(void)
{
PWM_Stop();
}
/*******************************************************************************
* 函数名:Buzzer_Init
* 功 能:初始化
* 参 数:无
* 返回值:无
* 说 明:无
*******************************************************************************/
void Buzzer_Init(void)
{
Buzzer_Stop();
memset(&sBuzzer_Para, 0, sizeof(sBuzzer_Para));
Buzzer_SoundSet(50,100,5);
}
/*******************************************************************************
* 函数名:Buzzer_SoundSet
* 功 能:蜂鸣器声音设置
* 参 数:OnTime:开启时间
OffTime:关闭时间
Cycles:重复次数
* 返回值:无
* 说 明:无
*******************************************************************************/
void Buzzer_SoundSet(uint16_t OnTime, uint16_t OffTime, uint8_t Cycles)
{
sBuzzer_Para.u16OnMs = OnTime;
sBuzzer_Para.u16OffMs = OffTime;
sBuzzer_Para.u8Cycles = Cycles;
sBuzzer_Para.u8CycleCnt = 0;
sBuzzer_Para.u16CycleMs = 0;
sBuzzer_Para.bStart = 1;
sBuzzer_Para.bBeeping = 0;
}
/*******************************************************************************
* 函数名:Buzzer_SoundProcess
* 功 能:蜂鸣器声音鸣叫处理
* 参 数:无
* 返回值:无
* 说 明:无
*******************************************************************************/
void Buzzer_SoundProcess(void)
{
if (sBuzzer_Para.bStart)
{
if (sBuzzer_Para.u8CycleCnt < sBuzzer_Para.u8Cycles)
{
if (sBuzzer_Para.u16CycleMs < sBuzzer_Para.u16OnMs)//鸣叫时间未结束
{
if (!sBuzzer_Para.bBeeping)
{
Buzzer_Start();
sBuzzer_Para.bBeeping = 1;
}
}else//一个周期内鸣叫的时间结束
{
if (sBuzzer_Para.bBeeping)
{
Buzzer_Stop();//关闭蜂鸣器
sBuzzer_Para.bBeeping = 0;
}else
{
if (sBuzzer_Para.u16CycleMs >= (sBuzzer_Para.u16OnMs + sBuzzer_Para.u16OffMs))//一个周期结束
{
sBuzzer_Para.u16CycleMs = 0;
sBuzzer_Para.u8CycleCnt++;
}
}
}
}else//重复次数完成
{
Buzzer_Stop();
memset(&sBuzzer_Para, 0, sizeof(sBuzzer_Para));
}
}
}
/*******************************************************************************
* 函数名:Buzzer_CycleTimeProcess
* 功 能:时间处理
* 参 数:无
* 返回值:无
* 说 明:无
*******************************************************************************/
void Buzzer_CycleTimeProcess(void)
{
if (sBuzzer_Para.bStart)
{
sBuzzer_Para.u16CycleMs++;
}else
{
sBuzzer_Para.u16CycleMs = 0;
}
}
/*******************************************************************************
* 函数名:Buzzer_TaskMs
* 功 能:每ms执行的任务
* 参 数:无
* 返回值:无
* 说 明:无
*******************************************************************************/
void Buzzer_TaskMs(void)
{
Buzzer_SoundProcess();
Buzzer_CycleTimeProcess();
}
在程序初始化时运行以下函数:
c
Buzzer_Init();
每隔1ms运行以下函数:
c
Buzzer_TaskMs();
当需要蜂鸣器响时,调用以下:
c
void Buzzer_SoundSet(uint16_t OnTime, uint16_t OffTime, uint8_t Cycles)
例如,让蜂鸣器响100ms,关500ms,如此重复3次,即响三声,"嘀嘀嘀",按如下方式调用:
c
Buzzer_SoundSet(100, 500, 3);
完整Keil MDK工程文件下载链接:
STM32F103C8T6单片机PWM驱动无源蜂鸣器
如有错漏之处,请评论指出。