关于有源蜂鸣器及无源蜂鸣器的区别及驱动各类单片机案例
有源蜂鸣器与无源蜂鸣器区别
有源蜂鸣器与无源蜂鸣器区别在于是否有振荡源。
有源蜂鸣器即有震荡源的蜂鸣器,通常只需要在正负极上加对应的供电电压就可以驱动发声。
无源蜂鸣器即无震荡源的蜂鸣器,这个时候就需要搭建驱动电路(后面章节会提到相关驱动电路)进行驱动蜂鸣器进行发声了。
有源蜂鸣器
有源蜂鸣器的话相当于在这个模块内部已经为我们搭建好了驱动电路了,这个时候我们只需要在蜂鸣器两端加上对应的电压驱动即可(注意有源蜂鸣器引脚区分正负)。
例如下面的这张图可以看到一般有源蜂鸣器会清楚的写出驱动的电压参数以及输出的频率是多少的,因为内部加了震荡源了,所以一般输出频率都是固定的(通常引脚是长脚正,短脚负 )。
图中的这个有源蜂鸣器的驱动电压是5V,输出频率是2.3KHz左右的。
无源蜂鸣器
无源蜂鸣器需要自己外搭驱动电路,此时对于蜂鸣器本身来说引脚是不分正负的。
同样可以查看自己手中的无源蜂鸣器提供的参数,重要的就是两个,一个驱动电压,一个是驱动的频率(常见:2-5KHz)。这里给出一个简单的驱动电路可以用来驱动无源蜂鸣器发声的。
这里我用来试验的是输入2KHz驱动的蜂鸣器,看下实际接线图:
这里使用的是PWM发生器来给蜂鸣器提供一个方波信号驱动其发声,最快速方法就是搭建洞洞板来驱动就能快速知道这个无源蜂鸣器是否可以正常驱动及好坏。
模块化有源蜂鸣器及无源蜂鸣器驱动方式的说明
单片机驱动比较常用的是这种模块化的蜂鸣器,可以看到两者之间的外观是一模一样的(这里有些厂商会用贴纸区分,有些是一样的),如果是贴纸是一样的,只能通过输入信号听蜂鸣器是否发声分辨是有源还是无源。
VCC,GND按参数供电5V,这里供电建议还是使用稳压电源会好些(有些人用USB转TTL或者STlink进行供电发现无法驱动的情况,市面上还是有部分USB转串口和stlink是劣质的,很容易出现供电不足的情况,所以模块的供电都是建议使用稳压电压进行供电),然后在I/O口输入一个低电平(看自己手中的模块写的是高/低电平驱动然后输入对应的电平,这里是低电平驱动)看蜂鸣器是否发声:
- 蜂鸣器发声-->模块为有源蜂鸣器
- 蜂鸣器无声-->坏了或者为无源蜂鸣器
然后把 I/O口输入从低电平换成一个方波信号来驱动,输入方波信号后可以听到蜂鸣器发声就是无源蜂鸣器,依旧无声的话,排查自己的方波信号是否驱动能力不够大/信号地和电源地没有共地的问题,如果驱动能力足够且都有共地的话那可能就是模块坏了。
有源、无源蜂鸣器代码驱动
有源蜂鸣器:单片机IO口输出一个高/低电平信号
无源蜂鸣器:单片机IO口输出一个方波(占空比不为0%或者100%的)
这里只举例STM32F103C8T6的驱动主函数代码,需要整个工程的可以评论区留言!(其他单片机arduino,51等都是同理,配置好IO口输出即可)
有源蜂鸣器驱动代码(main.c):
javascript
##现象:蜂鸣器响一下停一下,按这样一直循环
int main(void)
{
/*开启时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //开启GPIOB的时钟
/*GPIO初始化*/
GPIO_InitTypeDef GPIO_InitStructure; //定义结构体变量
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //GPIO模式,赋值为推挽输出模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //GPIO引脚
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //GPIO速度,赋值为50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); //实现GPIOB的初始化
while (1)
{
GPIO_ResetBits(GPIOB, GPIO_Pin_9); //将PB9引脚设置为低电平,蜂鸣器鸣叫
Delay_ms(200); //延时100ms
GPIO_SetBits(GPIOB, GPIO_Pin_9); //将PB9引脚设置为高电平,蜂鸣器停止
Delay_ms(200); //延时100ms
}
}
无源蜂鸣器驱动代码(pwm.c)
javascript
#这个的现象主要和设置的频率和占空比有关,自行在主函数确定好即可输出对应的现象
void PWM_Init(void)
{
/*开启时钟*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //开启TIM2的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟
/*GPIO初始化*/
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure); //将PA0引脚初始化为复用推挽输出
/*配置时钟源*/
TIM_InternalClockConfig(TIM2); //选择TIM2为内部时钟,若不调用此函数,TIM默认也为内部时钟
/*时基单元初始化*/
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; //定义结构体变量
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //时钟分频,选择不分频,此参数用于配置滤波器时钟,不影响时基单元功能
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //计数器模式,选择向上计数
TIM_TimeBaseInitStructure.TIM_Period = 100 - 1; //计数周期,即ARR的值
TIM_TimeBaseInitStructure.TIM_Prescaler = 720 - 1; //预分频器,即PSC的值
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; //重复计数器,高级定时器才会用到
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
/*输出比较初始化*/
TIM_OCInitTypeDef TIM_OCInitStructure; //定义结构体变量
TIM_OCStructInit(&TIM_OCInitStructure); //结构体初始化,若结构体没有完整赋值
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //输出比较模式,选择PWM模式1
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性,选择为高,若选择极性为低,则输出高低电平取反
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //输出使能
TIM_OCInitStructure.TIM_Pulse = 0; //初始的CCR值
TIM_OC1Init(TIM2, &TIM_OCInitStructure); //将结构体变量交给TIM_OC1Init,配置TIM2的输出比较通道1
/*TIM使能*/
TIM_Cmd(TIM2, ENABLE); //使能TIM2,定时器开始运行
}
/**
* 函 数:PWM设置CCR
* 参 数:Compare 要写入的CCR的值,范围:0~100
* 注意事项:CCR和ARR共同决定占空比,此函数仅设置CCR的值,并不直接是占空比
* 占空比Duty = CCR / (ARR + 1)
*/
void PWM_SetCompare1(uint16_t Compare)
{
TIM_SetCompare1(TIM2, Compare); //设置CCR1的值
//这里的ARR+1正好是100 所以CCR设置为多少占空比就是多少
}
无源蜂鸣器驱动代码主要是PWM的输出,这个时候改变频率改变的是输出声音的音调。
总结
1.区分好有源、无源蜂鸣器后再进行驱动,不要不发声就认为模块是坏的。
2.有些贴片式的无源蜂鸣器有多个引脚,有些是固定引脚要看手册区分好引脚的功能。
3.有源区分正负,一般长脚正,短脚负;无源不分正负。