问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

嵌入式学习:蜂鸣器的分类、原理与驱动代码详解

创作时间:
作者:
@小白创作中心

嵌入式学习:蜂鸣器的分类、原理与驱动代码详解

引用
CSDN
1.
https://blog.csdn.net/qq_55344209/article/details/141110787

蜂鸣器是嵌入式系统中常见的发声器件,广泛应用于各种电子产品中。本文将详细介绍蜂鸣器的分类、工作原理、驱动方式以及具体的代码实现,帮助读者系统地了解蜂鸣器的相关知识。

1. 蜂鸣器分类

蜂鸣器是一种电子发声器件,采用直流电压供电,能够发出声音。广泛应用于计算机、打印机、报警器、电子玩具等电子产品中作为发声部件。一般仅从外形不易分辨蜂鸣器的种类。但是有些蜂鸣器使用广泛,见得多了就很容易分辨。例如常见的有源蜂鸣器会带一个白色贴纸,而无源蜂鸣器不带(当然这并不是绝对的)。

一般在单片机系统中,会按照驱动方式,将蜂鸣器分为以下两类:

  • 有源蜂鸣器:内部自带振荡源,接通电压即可发声,振荡频率固定,常用作报警器。
  • 无源蜂鸣器:内部不带振荡源,需要外加振荡信号,频率可改变,更加灵活实用。


无源蜂鸣器


有源蜂鸣器

有源蜂鸣器只需一个高低电平即可发声,和之前讲的LED的驱动方式完全相同。无源蜂鸣器需要外部频率变化的震荡信号才可以发声,相对稍复杂一点。

其他分类:

(1)按工作原理分类


压电式蜂鸣器

电磁式蜂鸣器

1. 压电式蜂鸣器

原理:利用压电效应,当施加电压时,压电材料(如钛酸钡或锆钛酸铅)会发生形变,从而产生振动并发出声音。

特点:

  • 高效节能,功耗低。
  • 结构简单,体积小,适合空间有限的应用场景。
  • 适用于高频范围(通常在2kHz到4kHz之间),音质较为清脆。
  • 耐用性强,没有移动部件,不易损坏。

2. 电磁式蜂鸣器

原理:通过电磁铁吸引膜片振动发声。当电流通过线圈时,产生磁场,该磁场与永久磁铁相互作用,使膜片振动。

特点:

  • 可以发出较低频率的声音,音质较为浑厚。
  • 相对压电式蜂鸣器,功耗较高。
  • 结构相对复杂一些,但价格通常较低。

(2)按结构特点分类


敞开式蜂鸣器

封闭式蜂鸣器

1. 封闭式蜂鸣器

特点:

  • 内部结构被完全封装在一个外壳中,具有较好的防护性能。
  • 适合在恶劣环境中使用,能够防止灰尘、湿气等进入影响工作。
  • 外观美观,便于安装。

2. 敞开式蜂鸣器

特点:

  • 没有外壳保护,直接暴露在外。
  • 更适合用于需要散热或不需要严格防护的应用场景。
  • 成本较低,但在某些环境下可能需要额外的防护措施。

(3)按供电类型分类


交流蜂鸣器


直流蜂鸣器

1. 直流蜂鸣器

特点:

  • 使用直流电源供电,通常为5V、12V等常见电压等级。
  • 广泛应用于电子设备中,特别是那些依赖电池供电的便携式设备。

2. 交流蜂鸣器

特点:

  • 使用交流电源供电,通常为市电电压(如110V或220V)。
  • 主要应用于工业控制、家用电器等领域,由于其功率较大,常用于报警系统。

2. 两种蜂鸣器的区别

特性
无源蜂鸣器
有源蜂鸣器
内置振荡电路
驱动方式
需要外部方波信号
直流电源
音调可调性
可调
固定
控制复杂度
较高(需生成信号)
简单(直接供电)
功耗
根据信号可变
较高
应用场景
多音调、复杂音频
单一音调、简单提示

3. 驱动代码

有源蜂鸣器驱动方式和LED是一样的,因此它的驱动代码也是和LED通用的。这里就不再赘述。

无源蜂鸣器不像有源蜂鸣器那样内置振荡电路,因此需要外部提供一个振荡信号来驱动。具体来说,你需要通过微控制器或其他信号源生成一定频率的方波信号,并将其施加到无源蜂鸣器上,才能产生声音。

包括STM32在内的大多数微控制器,都会使用PWM方波信号来驱动无源蜂鸣器。

先初始化PWM,在PA1 IO口输出PWM波。

// pwm.c
void PWM_Init(void)
{
    GPIO_InitTypeDef  		    GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef     TIM2_InitStructure;
    TIM_OCInitTypeDef   		TIM_OCInitStructure;
    NVIC_InitTypeDef    		NVIC_InitStructure;
    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    //5ms
    TIM2_InitStructure.TIM_Period = 4999;
    TIM2_InitStructure.TIM_Prescaler = 71;
    TIM2_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM2_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;  
    TIM_TimeBaseInit(TIM2, &TIM2_InitStructure);
    
    //PWM输出引脚配置  TIM2_CH2 PA1  
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //不是常规引脚功能,因此配置为复用推挽
    GPIO_InitStructure.GPIO_Pin = PWM_PIN; 
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(PWM_PORT, &GPIO_InitStructure);
    //PWM配置  TIM2_CH2 PA1  占空比:2500/(4999+1) = 50%
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;  //PWM模式1 
    TIM_OCInitStructure.TIM_Pulse = 2500;              //初始值2500个高电平
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;  //主通道使能
    TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable; //TIM2无此功能  随便写或不写
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;  //开始时输出高
    TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;  //TIM2无此功能  随便写或不写
    TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;//TIM2无此功能  随便写或不写
    TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set;//TIM2无此功能  随便写或不写
    TIM_OC2Init(TIM2, &TIM_OCInitStructure);  
    //中断分组配置
    NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    
    TIM_ITConfig(TIM2,TIM_IT_CC2,ENABLE);
    TIM_Cmd(TIM2, ENABLE);
}
//TIM2中断服务程序  
void TIM2_IRQHandler(void)                		
{
    u8 i=0;
    if(TIM_GetITStatus(TIM2, TIM_IT_CC2) != RESET)  //TIM2捕获比较中断
    {
        i++;
        if(i==255)  //产生一次PWM后做的事情 根据自己需求修改
        {
          i=0;
        }
        
        TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);  //清除中断标志位
    }
}
// main.c
main()
{
    SystemTinerInit(7200-1, 1000-1);
    Delay_Init();
    USART1_Init(115200);
    LED_Init();
    PWM_Init();
    while(1)
    {
      TIM_SetCompare2(TIM2, 300);  //输出占空为300/5000=6%的方波。
    }
}

虽然有些无源蜂鸣器没有明确的正负极标识,但最好确认一下。如果蜂鸣器有标记(如“+”号),则该端应接至PWM信号输出端;如果没有明确标识,则一般情况下不会因为接反而损坏,但仍建议按照制造商提供的指南进行连接。

在这里我们把无源蜂鸣器的随便一个引脚(或“+”)接到PA1,另一引脚接地。代码是上一章节的PWM的代码,具体配置细节可到上一章节查看。

另外,通过改变PWM占空比,可以调节无源蜂鸣器的音调,利用这一特点,再结合适当的延迟,可以演奏简单的音乐。但是要注意蜂鸣器并不能像扬声器那样直接播放音乐,只能播放简单的节拍(就像纯音乐一样,还只能是简单的)。假如你想播放一首MP3音乐,应该选择扬声器作为输出,而不是蜂鸣器。这是很多小白的一个误区,在此提醒一下。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号