本帖最后由 yinwuqing110 于 2022-12-12 00:17 编辑
在前面帖子中介绍到MM32L0136C7P开发板上集成了一个无源蜂鸣器,而且开箱贴也演示了出厂默认程序中有集成驱动蜂鸣器,输出美妙音符的功能。那么无源蜂鸣器是如何工作的呢?
蜂鸣器分类
蜂鸣器是一种一体化结构的电子讯响器,采用直流电压供电,广泛应用于计算机、打印机、复印机、报警器、电子玩具、汽车电子设备、电话机、定时器等电子产品中作发声器件。蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器两种类型。产品分类:有源蜂鸣器和无源蜂鸣器。实现的结构原理是电磁线圈和磁铁周期性地振动发声,使用三极管放大电流电路驱动。
结构原理:
1.压电式蜂鸣器 压电式蜂鸣器主要由多谐振荡器、压电蜂鸣片、抗阻匹配器及共鸣箱、外壳等组成。有的压电式蜂鸣器外壳上还装有发光二极管。多谐振荡器由晶体管或集成电路构成。当接通电源后(1.5~15V直流工作电压),多谐振荡器起振,输出1.5~2.5kHZ的音频信号,阻抗匹配器推动压电蜂鸣片发声。
2.电磁式蜂鸣器 电磁式蜂鸣器由振荡器、电磁线圈、磁铁、振动膜片及外壳等组成。接通电源后,振荡器产生的音频信号电流通过电磁线圈,使电磁线圈产生磁场。振动膜片在电磁线圈和磁铁的相互作用下,周期性地振动发声。
有源与无源:
有源蜂鸣器直接接上额定电源(新的蜂鸣器在标签上都有注明)就可连续发声;而无源蜂鸣器则和电磁扬声器一样,需要接在音频输出电路中才能发声。这里的"源"不是指电源,而是指震荡源。也就是说,有源蜂鸣器内部带震荡源,所以只要一通电就会叫;而无源内部不带震荡源,所以如果用直流信号无法令其鸣叫。必须用2K-5K的方波去驱动它。
驱动方式:
单片机驱动他激蜂鸣器的方式有两种:一种是PWM 输出口直接驱动,另一种是利用I/O 定时翻转电平产生驱动波形对蜂鸣器进行驱动。
1.PWM 输出口直接驱动是利用PWM 输出口本身可以输出一定的方波来直接驱动蜂鸣器。在单片机的软件设置中有几个系统寄存器是用来设置PWM 口的输出的,可以设置占空比、周期等等,通过设置这些寄存器产生符合蜂鸣器要求的频率的波形之后,只要打开PWM 输出,PWM 输出口就能输出该频率的方波,这个时候利用这个波形就可以驱动蜂鸣器了。比如频率为2000Hz 的蜂鸣器的驱动,可以知道周期为500μs,这样只需要把PWM 的周期设置为500μs,占空比电平设置为250μs,就能产生一个频率为2000Hz 的方波,通过这个方波再利用三极管就可以去驱动这个蜂鸣器了。
2.利用I/O 定时翻转电平来产生驱动波形的方式会比较麻烦一点,必须利用定时器来做定时,通过定时翻转电平产生符合蜂鸣器要求的频率的波形,这个波形就可以用来驱动蜂鸣器了。比如为2500Hz 的蜂鸣器的驱动,可以知道周期为400μs,这样只需要驱动蜂鸣器的I/O 口每200μs 翻转一次电平就可以产生一个频率为2500Hz,占空比为1/2duty 的方波,再通过三极管放大就可以驱动这个蜂鸣器了。
根据原理图可知,MCU通过PA6管脚与无源蜂鸣器相连接,接下来我们在官方给出的gpio工程示例中,添加针对无源蜂鸣器管脚PA6的驱动代码。
代码实现如下:
#ifndef __BOARD_INIT_H__
#define __BOARD_INIT_H__
#include <stdio.h>
#include "hal_common.h"
#include "hal_gpio.h"
#include "hal_uart.h"
#include "clock_init.h"
#include "pin_init.h"
/* DEBUG UART. */
#define BOARD_DEBUG_UART_PORT UART2
#define BOARD_DEBUG_UART_BAUDRATE 9600u
#define BOARD_DEBUG_UART_FREQ CLOCK_APB1_FREQ
/* KEY0 - K2. */
#define BOARD_KEY0_GPIO_PORT GPIOD
#define BOARD_KEY0_GPIO_PIN GPIO_PIN_5
/* LED0. */
#define BOARD_LED0_GPIO_PORT GPIOB
#define BOARD_LED0_GPIO_PIN GPIO_PIN_9
/* LED1. */
#define BOARD_LED1_GPIO_PORT GPIOB
#define BOARD_LED1_GPIO_PIN GPIO_PIN_10
/* Beep. */
#define BOARD_BEEP_GPIO_PORT GPIOA
#define BOARD_BEEP_GPIO_PIN GPIO_PIN_6
#include "pin_init.h"
#include "hal_rcc.h"
#include "hal_gpio.h"
void BOARD_InitPins(void)
{
GPIO_Init_Type gpio_init;
/* PA3 - UART2_RX. */
gpio_init.Pins = GPIO_PIN_3;
gpio_init.PinMode = GPIO_PinMode_In_Floating;
gpio_init.Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &gpio_init);
GPIO_PinAFConf(GPIOA, gpio_init.Pins, GPIO_AF_1);
/* PA2 - UART2_TX. */
gpio_init.Pins = GPIO_PIN_2;
gpio_init.PinMode = GPIO_PinMode_AF_PushPull;
gpio_init.Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &gpio_init);
GPIO_PinAFConf(GPIOA, gpio_init.Pins, GPIO_AF_1);
/* LED0. */
gpio_init.Pins = GPIO_PIN_9;
gpio_init.PinMode = GPIO_PinMode_Out_PushPull;
gpio_init.Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &gpio_init);
GPIO_PinAFConf(GPIOB, gpio_init.Pins, GPIO_AF_15);
/* LED1. */
gpio_init.Pins = GPIO_PIN_10;
gpio_init.PinMode = GPIO_PinMode_Out_PushPull;
gpio_init.Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &gpio_init);
GPIO_PinAFConf(GPIOB, gpio_init.Pins, GPIO_AF_15);
/* KEY0 - K2. */
gpio_init.Pins = GPIO_PIN_5;
gpio_init.PinMode = GPIO_PinMode_In_PullUp;
gpio_init.Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &gpio_init);
GPIO_PinAFConf(GPIOD, gpio_init.Pins, GPIO_AF_15);
/* BEEP. */
gpio_init.Pins = GPIO_PIN_6;
gpio_init.PinMode = GPIO_PinMode_Out_PushPull;
gpio_init.Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &gpio_init);
GPIO_PinAFConf(GPIOA, gpio_init.Pins, GPIO_AF_15);
}
#include <stdint.h>
#include <stdio.h>
#include "board_init.h"
#include "clock_init.h"
/*
* Definitions.
*/
unsigned char SONG_TONE[]={212,212,190,212,159,169,212,212,190,212,142,159,212,212,106,126,159,169,190,119,119,126,159,142,159,0};
unsigned char SONG_LONG[]={9,3,12,12,12,24,9,3,12,12,12,24,9,3,12,12,12,12,12,9,3,12,12,12,24,0};
void delay(uint32_t Tms)
{
unsigned int i,j;
for(i=150;i>0;i--)
{
for( j=Tms;j>0;j--)
{}
}
}
void PlayMusic()
{
unsigned int i=0,j,k;
while(SONG_LONG[i]!=0||SONG_TONE[i]!=0)
{
以上为实现无源蜂鸣器输出生日之歌的源代码,感兴趣的坛友可做相应的修改,编译下载实验。其实现方式是利用I/O定时翻转电平来产生驱动波形,这类无源蜂鸣器在低功耗产品应用比较广泛,比如电子表的滴滴声,生日贺卡等。实验的效果见下面视频,此次分享告一段落,咱们后会有期。
|
此文章已获得独家原创/原创奖标签,著作权归21ic所有,未经允许禁止转载。
共1人点赞
|