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

news2025/4/21 17:06:01

目录

一、蜂鸣器的基本知识

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。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1346418.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【十一】【C++\动态规划】1218. 最长定差子序列、873. 最长的斐波那契子序列的长度、1027. 最长等差数列,三道题目深度解析

动态规划 动态规划就像是解决问题的一种策略&#xff0c;它可以帮助我们更高效地找到问题的解决方案。这个策略的核心思想就是将问题分解为一系列的小问题&#xff0c;并将每个小问题的解保存起来。这样&#xff0c;当我们需要解决原始问题的时候&#xff0c;我们就可以直接利…

.NET进阶篇06-async异步、thread多线程2

知识须要不断积累、总结和沉淀&#xff0c;思考和写做是成长的催化剂web 内容目录 1、线程Thread 一、生命周期 二、后台线程 三、静态方法 1.线程本地存储 2.内存栅栏 四、返回值 2、线程池ThreadPool 一、工做队列 二、工做线程和IO线程 三、和Thread区别 四、定时器 1、线…

3D视觉-激光三角测量法的分类

按照入射激光光束和被测物体表面法线的角度关系&#xff0c;一般分为直射式和斜射式两种方式。 1&#xff09;直射式测量 如图所示&#xff0c;激光器发出的光线&#xff0c;经会聚透镜聚焦后垂直入射到被测物体表面上&#xff0c;物体移动或者其表面变化&#xff0c;导致入射…

纯CSS的华为充电动画,它来了

&#x1f4e2; 鸿蒙专栏&#xff1a;想学鸿蒙的&#xff0c;冲 &#x1f4e2; C语言专栏&#xff1a;想学C语言的&#xff0c;冲 &#x1f4e2; VUE专栏&#xff1a;想学VUE的&#xff0c;冲这里 &#x1f4e2; Krpano专栏&#xff1a;想学Krpano的&#xff0c;冲 &#x1f514…

ubuntu磁盘管理常用命令

写的不全&#xff0c;后面随时修改。 Linux 磁盘管理常用三个命令为 df、du 和 fdisk。 df&#xff08;英文全称&#xff1a;disk free&#xff09;&#xff1a;列出文件系统的整体磁盘未使用量du&#xff08;英文全称&#xff1a;disk used&#xff09;&#xff1a;检查磁盘空…

GcExcel:DsExcel 7.0 for Java Crack

GcExcel:DsExcel 7.0-高速 Java Excel 电子表格 API 库 Document Solutions for Excel&#xff08;DsExcel&#xff0c;以前称为 GcExcel&#xff09;Java 版允许您在 Java 应用程序中以编程方式创建、编辑、导入和导出 Excel 电子表格。几乎可以部署在任何地方。 创建、加载、…

[python]python利用pyaudio录制系统声音没有立体声混音怎么录制系统音频

当电脑没有立体声混音导致Python写代码无法使用pyaudio进行录制系统声音怎么办&#xff1f;查阅资料和安装驱动等方法都不行&#xff0c;难道没办法了吗&#xff1f;那为什么电脑其他软件可以做到呢&#xff1f;因此研究了一下pyaudio在没有立体声混音情况下确实无法录制声音&a…

数据模型设计

数据模型设计&#xff0c;可以理解为数据库中的表结构设计。 我们在设计器中创建的数据模型&#xff0c;也称为实体。我们将前端页面中传过来的数据保存到对应的实体中&#xff0c;即为将前端数据保存到了数据库中。 1 、实体与枚举的创建 1 .1 创建供应商 supplier实体 在左…

MySQL基础学习: 由delete和insert操作导致的死锁问题

一、问题复现&#xff1a;表结构 CREATE TABLE user_props (user_id bigint NOT NULL ,prop_key varchar(100) NOT NULL ,prop_value varchar(100) NOT NULL,PRIMARY KEY (user_id,prop_key) )二、死锁测试 &#xff08;1&#xff09;开启两个事务 &#xff08;2&#xff09;…

基于微信小程序的停车预约系统设计与实现

基于微信小程序的停车预约系统设计与实现 项目概述 本项目旨在结合微信小程序、后台Spring Boot和MySQL数据库&#xff0c;打造一套高效便捷的停车预约系统。用户通过微信小程序进行注册、登录、预约停车位等操作&#xff0c;而管理员和超级管理员则可通过后台管理系统对停车…

【python】爬取百度热搜排行榜Top50+可视化【附源码】【送数据分析书籍】

一、导入必要的模块&#xff1a; 这篇博客将介绍如何使用Python编写一个爬虫程序&#xff0c;从斗鱼直播网站上获取图片信息并保存到本地。我们将使用requests模块发送HTTP请求和接收响应&#xff0c;以及os模块处理文件和目录操作。 如果出现模块报错 进入控制台输入&#xff…

【软件工程】走进敏捷开发:灵活、协作、迭代的软件工艺之旅

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a; 软件工程 ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言&#xff1a; 正文 敏捷开发&#xff08;Agile Development&#xff09; 详细介绍&#xff1a; 优缺点&#xff1a; 优点&#xf…

(2023)PanGu-Draw:通过时间解耦训练和可重用的 Coop-Diffusion 推进资源高效的文本到图像合成

PanGu-Draw: Advancing Resource-Efficient Text-to-Image Synthesis with Time-Decoupled Training and Reusable Coop-Diffusion 公众&#xff1a;EDPJ&#xff08;添加 VX&#xff1a;CV_EDPJ 或直接进 Q 交流群&#xff1a;922230617 获取资料&#xff09; 目录 0. 摘要…

php的laravel权限问题

1.这是我新建的一个路由&#xff0c;然后就是说每新建一个路由都要给他开个权限&#xff01;&#xff01;&#xff01;&#xff01; 2.这个是组内大佬写的&#xff1a; 我们也可以在里面加&#xff0c;也可以在浏览器的页面手动加&#xff08;对我们新手来说还是浏览器的页面…

使用uni-app editor富文本组件设置富文本内容及解决@Ready先于onload执行,无法获取后端接口数据的问题

开始使用富文本组件editor时&#xff0c;不知如何调用相关API设置富文本内容和获取内容&#xff0c;本文将举例详解 目录 一.了解editor组件的常用属性及相关API 1.属性常用说明 2.富文本相关API说明 1&#xff09;editorContext 2&#xff09; editorContext.setContents…

JVM 常用知识和面试题

1. 什么是JVM内存结构&#xff1f; jvm将虚拟机分为5大区域&#xff0c;程序计数器、虚拟机栈、本地方法栈、java堆、方法区&#xff1b; 程序计数器&#xff1a;线程私有的&#xff0c;是一块很小的内存空间&#xff0c;作为当前线程的行号指示器&#xff0c;用于记录当前虚拟…

Avalonia学习(十五)-OxyPlot

今天开始继续Avalonia练习。展示一些样例&#xff0c;尤其是第三方库的使用。 本节&#xff1a;OxyPlot 1.引入OxyPlot.Avalonia 2.项目引入 在Main方法里增加OxyPlotModule.EnsureLoaded()方法调用。 public static void Main(string[] args) {OxyPlotModule.EnsureLoade…

Java线程池ThreadPoolExecutor源码解析

Java线程池ThreadPoolExecutor源码解析 1.ThreadPoolExecutor的构造实现 以jdk8为准&#xff0c;常说线程池有七大参数&#xff0c;通常而言&#xff0c;有四个参数是比较重要的 public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit …

python3处理xls并flask显示

前言&#xff1a; 工作中有需求对xls文件进行生成和显示&#xff0c;这里就将对应的xls文件的处理&#xff0c;读取和flask展示代码罗列出来&#xff0c;方便大家使用&#xff1a; 需要的模块&#xff0c;这里需要注意版本号&#xff0c;如果直接安装使用报错&#xff0c;就指…

Tensorflow2.X的GPU版框架最快最稳搭建方法

一、环境基础 Windows10以上 已装Anaconda 支持GPU 二、搭建步骤 1. 在Anaconda中创建并进入虚拟环境 conda create -n envname python3.8 conda activate envname 注意&#xff1a;envname 替换为你自己想命名的&#xff0c;下文将以“Ljdenv”出现 2.安…