05 HAL库驱动蜂鸣器唱出一首小歌

2023-12-31 18:25:40

目录

一、蜂鸣器的基本知识

1、有源蜂鸣器

2、无源蜂鸣器

二、PWM的相关知识

1. PWM概念

2. PWM常见参数

3.PWM基本结构

三、蜂鸣器发出音调的原理

四、频率计算

五、实验开始


一、蜂鸣器的基本知识


? ? ?

??蜂鸣器是一种能够发出持续而连续的声音的电子设备,它被广泛应用于警报、提醒、提示等场合。

以下是关于蜂鸣器的基本知识和分类:

基本知识:

1. 构成:蜂鸣器由一个或多个压电陶瓷或电磁线圈构成,当输入电流或电压时,产生机械振动,从而产生声音。

2. 工作原理:蜂鸣器通过交变或直流电流或电压的作用,使压电陶瓷片或线圈振动,产生声音。

分类:

1. 压电式蜂鸣器(Piezoelectric Buzzer):这种蜂鸣器使用压电陶瓷片作为振动元件,通过外加的交变电压引起陶瓷片的振动,从而产生声音。它的优点是结构简单、功耗低、体积小,常见的有被动型和主动型压电蜂鸣器。

2. 电磁式蜂鸣器(Magnetic Buzzer):这种蜂鸣器使用电磁线圈和振动片组成,通过外加的交变电流引起线圈的振动,从而产生声音。它的优点是音量大、声音频率范围宽,常用于声音要求较高的应用场合。

此外,根据蜂鸣器输出的声音特性,还可以将蜂鸣器分为不同的类型,如持续音蜂鸣器和脉冲音蜂鸣器。持续音蜂鸣器发出持续不断的声音,适用于需要连续声音的场合;而脉冲音蜂鸣器则是以间断的脉冲声音来提醒或警告。 总的来说,蜂鸣器是一种实用的电子设备,通过不同的结构和工作原理,可以满足各种不同场景下的声音要求。

以上内容知识作为一个了解和知识拓展, 其实我们只需要知道这些。

1、有源蜂鸣器

有源蜂鸣器只要接上额定电源就可以发出声音, 内部内置得有震荡源, 但是频率固定

2、无源蜂鸣器

无源蜂鸣器利用电磁感应原理,为音圈接入交变电流后形成的电磁铁与永磁铁相吸或相斥而推动振膜发声, 这种蜂鸣器就比较适合我们由来播放对应频率的音乐。所以本实验想驱动蜂鸣器哼出一首歌的曲调也得使用无源蜂鸣器。

二、PWM的相关知识


1. PWM概念

PWM(Pulse Width Modulation)即脉冲宽度调制,通过对脉冲的宽度进行调制,来获得所需要波形, 大家不需要管PWM的是咱们实现的,正所谓术业有专攻嘛, 嵌入式开发技术这块记住这四个字:“够用就行”。因为学海无涯, 知识太多了。

2. PWM常见参数

3.PWM基本结构

三、蜂鸣器发出音调的原理


大家看以上这张图, 这就是各个音调的频率, 也就是说我们给蜂鸣器对应频率的PWM波,蜂鸣器就能发出对应的声音出来, 我们再结合我们需要播放的音乐的音调和每一个音调的间隔时间是不是就能驱动蜂鸣器播放音乐了。

四、频率计算


这里也是一样的, 我就带着大家配置了, 我以文字的形式给大家说一下, 大家配置一下工程, 咱们的重点放在频率的计算和代码实现上面。查看原理图, 看看蜂鸣器的连接情况, 查看蜂鸣器连接再哪一个定时器的哪一个通道上面, 接着配置该定时器, 根据定时器所在总线上的频率来计算, 这里不太清楚的可以看我单片机主题里面的定时器中断那篇文章。

重点在这:

该实验的重点在这, 或者说定时器的重点在这里, 根据预分频的值和计数值计算pwm波的频率

CK_PSC:为定时器所在总线上的频率

PSC:预分频的值

ARR:计数器周期里的值

大家看这张图

我的定时器所在总线上的频率是64MHz, 预分频的值为6400-1, 计数器的值(ARR/count period)10000-1, 那么我的pwm波形的频率是不是64000000 / 6400 / 10000 = 1Hz, 这样我们去晚上随便弄个音乐的频率图来, 我们按照该音乐的各个音调分布和时间间隔是不是就能使蜂鸣器播放对应的音乐了。

五、实验开始


对了对了, 咱们驱动蜂鸣器播放音乐是不是得改变pwm波的怕频率, 又根据上面的频率计算公式,可以发现有两个参数可以修改频率, 一个是预分频的值, 一个是计数值(周期),在该代码种采用固定周期值, 修改预分频的值, 大家不用担心, 也是有函数可以修改预分频器的值的。

Beeper.h

#define  proport          72000 	//Tclk/(arr+1)=72000000/(1000)


#define COUNT_PERIOD 10000
 
//根据Tout= ((arr+1)*(psc+1))/Tclk推出psc值就是本句define定义的值,Tout为音调频率131Hz的倒数,Tclk=72MHz                                                
#define  L1       ((proport/262)-1)//低调 do 的频率
#define  L2       ((proport/296)-1)//低调 re 的频率
#define  L3       ((proport/330)-1)//低调 mi 的频率
#define  L4       ((proport/349)-1)//低调 fa 的频率
#define  L5       ((proport/392)-1)//低调 sol 的频率
#define  L6       ((proport/440)-1)//低调 la 的频率
#define  L7       ((proport/494)-1)//低调 si 的频率
                                               
#define  M1       ((proport/523)-1)//中调 do 的频率
#define  M2       ((proport/587)-1)//中调 re 的频率
#define  M3       ((proport/659)-1)//中调 mi 的频率
#define  M4       ((proport/699)-1)//中调 fa 的频率
#define  M5       ((proport/784)-1)//中调 sol的频率
#define  M6       ((proport/880)-1)//中调 la 的频率
#define  M7       ((proport/988)-1)//中调 si 的频率
 
#define  H1       ((proport/1048)-1)//高调 do 的频率
#define  H2       ((proport/1176)-1)//高调 re 的频率
#define  H3       ((proport/1320)-1)//高调 mi 的频率
#define  H4       ((proport/1480)-1)//高调 fa 的频率
#define  H5       ((proport/1640)-1)//高调 sol的频率
#define  H6       ((proport/1760)-1)//高调 la 的频率
#define  H7       ((proport/1976)-1)//高调 si 的频率
 
#define  Z0       0//

Beeper.c


void Solitary_brave(void)
{
	int16_t solitary_brave[]=
	{
		M6,50,M7,50,H1,50,H2,50,M7,50,H1,50,H1,100,Z0,10,	//爱你孤身走暗巷
		H1,50,M7,50,H1,50,H2,50,M7,50,H1,50,H1,100,Z0,10, 	//爱你不跪的模样
		H1,50,H2,50,H3,50,H2,50,H3,50,H2,50,H3,100,H3,50,H3,50,H2,50,H3,100,H5,100,H3,100,Z0,10 //爱你对峙过绝望不肯哭一场
		
	};

	int length = sizeof(solitary_brave)/sizeof(solitary_brave[0]);
	for(uint8_t i=0;i<(length/2);i++)
	{
		__HAL_TIM_SET_COMPARE(&tim1, TIM_CHANNEL_1, COUNT_PERIOD / 2);
        __HAL_TIM_SET_PRESCALER(&tim1, solitary_brave[2 * i]);      //取出偶数,预分频的值
		HAL_Delay(5*solitary_brave[i*2+1]);
	}
}

以上代码的头文件是从别处弄来的,懒得写了,给大家再重复一下原理, 头文件种的#define ?proport ? ? ? ? ?72000 ?? ?//Tclk/(arr+1)=72000000/(1000)这一句, 就是计算出经过72MHz/计数器的周期值之后的值, 咱们想得到262Hz的频率, 预分频的值是不是将经过72MHz/计数器的周期值之后的值除以262, 这样结果就是预分频的值了, 也就是头文件中的L, M, H。

文章来源:https://blog.csdn.net/m0_74976404/article/details/135317696
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。