当前位置: 首页 > news >正文

STM32无源蜂鸣器播放音乐

开发板:野火霸天虎V2
单片机:STM32F407ZGT6
开发软件:MDK+STM32CubeMX

文章目录

  • 前言
  • 一、找一篇音乐的简谱
  • 二、确定音调
  • 三、确定节拍
  • 四、使用STM32CubeMX生成初始化代码
  • 五、代码分析


前言

本实验使用的是低电平触发的无源蜂鸣器

无源蜂鸣器是指没有振荡源的蜂鸣器,因此必须使用一定频率的方波才能驱动它发声,所以无源蜂鸣器播放音乐的本质就是使用定时器的PWM,随着节奏拍调节延时、根据音符调节驱动信号的频率,这样就能播放音乐了。

STM32无源蜂鸣器播放孤勇者


一、找一篇音乐的简谱

找一篇稍微简单点的音乐的简谱,我这里找的是孤勇者。
孤勇者简谱

二、确定音调

① 确定音调,区分高中低音很简单,就看数字上方下方有没有点。
高中低音
② 确定音调对应的频率,如下图所示。
简谱音名和频率关系
③ 定义一个常量浮点型数组,把各音名对应的频率放入。

const float pitch_name_frequency[21] = {//低音//1		2		3		4		5		6		7261.63,	293.67,	329.63,	349.23,	391.99,	440,	493.88,//0-6//中音//1		2		3		4		5		6		7532.25,	587.33,	659.25,	698.46,	783.99,	880,	987.76,//7-13//高音//1		2		3		4		5		6		71046.50,1174.66,1318.51,1396.92,1567.98,1760,	1975.52//14-20
};

④ 开始抄吧,定义一个常量无符号8位类型数组,把乐谱音名对应频率数组序号放入,抄的过程一定仔细,一不小心就可能抄错。怎么抄
0代表休止符,不发声,这里用21表示,方便后续判断处理,抄完结果如下,每一行都与简谱对应。

const uint8_t gu_yong_zhe[] = {9,21,21,7,8,7,9,21,7,8,7,8,9,5,7,5,7,5,7,8,7,6,21,21,9,21,21,7,8,7,9,21,7,8,7,8,9,5,7,5,7,5,7,9,8,6,21,21,5,7,12,12,12,12,11,12,12,11,12,11,12,11,9,9,9,21,21,5,7,12,12,12,11,12,11,13,13,13,12,13,    13,12,9,9,21,9,11,9,8,9,8,9,8,9,11,9,11,9,8,9,8,9,8,21,7,8,9,5,7,9,8,9,8,7,7,5,21,21,12,13,14,15,13,14,14,14,13,14,15,13,14,14,14,15,16,15,16,15,16,16,15,16,18,16,12,13,14,15,13,14,14,14,13,14,15,13,14,14,14,15,16,15,16,15,16,16,15,16,18,16,18,16,18,16,18,16,18,19,16,18,18,16,18,16,18,16,18,19,16,18,18,18,16,15,15,15,14,16,16,15,15,15,14,14,12,21,21,18,18,16,15,15,15,14,16,16,15,15,15,14,14,12,21,21,21,21,21,21,21,21,21,21,21,21,21,21,12,11,12,11,12,11,12,11,12,12,11,12,11,12,11,9,9,9,21,21,12,11,12,11,12,11,12,11,13,13,13,12,13,12,9,9,9,21,21,9,11,9,8,9,8,9,8,9,11,9,11,9,8,9,8,9,8,21,7,8,9,12,14,16,15,16,15,14,14,12,21,12,13,12,5,7,9,13,13,13,13,12,12,12,21,5,7,9,13,13,13,13,12,12,12,21,12,13,12,21,21
};

三、确定节拍

确定音乐的节拍,也就是PWM持续的时间,即延时时间。
节拍
我们看表格的第一列,音符右方、下方的短横线和右方的圆点共同表示音符的时长。
以音符5为例,设音符 5 (即1拍)延时时间tdelay=4x
右方增加1条横线表示延时时间增加1倍,5 - 的延时时间tdelay=8x,加2条横线表示增加2倍,5 - -的延时时间tdelay=12x。
右方增加1个圆点表示延时时间增加一个半拍,5 · 的延时时间tdelay=6x。
下方增加1条横线表示延时时间减少一半,tdelay=2x,下方增加2条横线表示延时时间减少为1/4,tdelay=x。

因为孤勇者中最小的是1/4拍,因此取1/4拍为单位时间,定义一个常量无符号8位类型数组,将简谱上音名对应节拍抄入,又是一个漫长的过程。
抄入节拍
结果如下。

const uint8_t beat[] = {8,4,1,1,1,1,8,3,1,1,1,1,1,3,1,3,1,3,1,2,2,8,4,4,8,4,1,1,1,1,8,3,1,1,1,1,1,3,1,3,1,3,1,2,2,8,4,4,1,1,2,1,1,1,1,2,1,1,1,1,1,1,1,3,4,4,2,1,1,3,1,1,1,1,1,3,1,1,1,2,1,2,1,8,1,1,1,1,3,1,3,1,3,1,1,1,1,1,3,1,3,1,4,2,1,1,2,2,2,2,3,1,1,1,2,8,4,2,1,1,1,1,1,1,2,1,1,1,1,1,1,2,1,1,1,1,1,1,2,1,1,2,2,2,1,1,1,1,1,1,2,1,1,1,1,1,1,2,1,1,1,1,1,1,2,1,1,2,2,2,2,3,1,3,1,1,1,1,1,2,2,3,1,3,1,1,1,1,1,2,1,1,1,1,2,2,1,1,1,1,2,2,1,1,8,4,2,1,1,1,1,2,2,1,1,1,1,2,2,1,1,8,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2,1,1,3,1,1,1,1,1,2,1,1,1,1,1,1,1,3,4,4,2,1,1,3,1,1,1,1,1,3,1,1,1,1,1,1,3,4,4,1,1,1,1,3,1,3,1,3,1,1,1,1,1,3,1,3,1,4,2,1,1,2,2,2,2,3,1,1,1,2,12,2,1,1,2,2,2,2,4,2,1,1,1,3,12,2,2,2,2,4,2,1,1,1,3,8,2,1,1,8,4,4
};

四、使用STM32CubeMX生成初始化代码

点击Clock Configuration配置时钟树,F407ZGT6最大时钟为168MHz。
时钟树
点击Pinout & Configuration配置RCC。
RCC
配置SYS。
SYS
配置TIM时钟源为内部时钟,通道1为PWM生成。
在这里插入图片描述
配置参数,PSC设置为0不分频,ARR、Pulse都可以设置为0,因为后面程序中会修改的,注意Mode设置为PWM Mode 1,CH Polarity(通道有效极性)设置为0,因为我使用的是低电平触发的无源蜂鸣器。
参数
将TIM2通道1的GPIO引脚速度改为高。
GPIO
点击Project,配置工程名、位置、IDE及IDE版本。
1
勾选这两项,将所有库文件复制到工程文件夹、每个初始化外设生成一个.c和.h文件,下面这项必勾。
2
生成代码,打开工程。

五、代码分析

ARR寄存器的值控制着PWM的周期、频率,因为F407 TIM2时钟已经配置为不分频,所以fcnt=84M,Tcnt=1/84 * 10-6s,Tpwm = ARR * Tcnt ,所以fcnt = ARR * fpwm,ARR = fcnt / fpwm, fcnt=84M,fpwm音调对应频率pitch_name_frequency[gu_yong_zhe[i]]。开始生成PWM,根据节拍延时一段时间,关闭PWM。注意关闭PWM后清零CNT计数器,不然会发生错误。代码:__HAL_TIM_SetCounter(&htim2, 0);

void play_music(void)
{uint32_t i, delay_time, tune;for(i=0;i<(sizeof(gu_yong_zhe)/sizeof(gu_yong_zhe[0]));i++){delay_time = beat[i] * 250; //250ms 1/4拍, 1s 1拍if(gu_yong_zhe[i] != 21) // 不是休止符{tune = (uint32_t)84*1000*1000/pitch_name_frequency[gu_yong_zhe[i]];
//			__HAL_TIM_SetAutoreload(&htim2, tune); // 和下一句作用一样TIM2->ARR = tune; // 改变频率
//			__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1, tune/2); // 和下一句作用一样TIM2->CCR1 = tune/2; // 占空比为50%HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);HAL_Delay(delay_time); // 根据节拍延时HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_1);__HAL_TIM_SetCounter(&htim2, 0); // CNT寄存器值清0,不然会发生错误}else // 是休止符{HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_1);HAL_Delay(delay_time);}}
}

相关文章:

STM32无源蜂鸣器播放音乐

开发板&#xff1a;野火霸天虎V2 单片机&#xff1a;STM32F407ZGT6 开发软件&#xff1a;MDKSTM32CubeMX 文章目录 前言一、找一篇音乐的简谱二、确定音调三、确定节拍四、使用STM32CubeMX生成初始化代码五、代码分析 前言 本实验使用的是低电平触发的无源蜂鸣器 无源蜂鸣器是…...

【云原生】kubernetes中的认证、权限设置---RBAC授权原理分析与应用实战

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…...

【Python设计模式04】策略模式

策略模式&#xff08;Strategy Pattern&#xff09;是一种行为型设计模式&#xff0c;它定义了一系列算法&#xff0c;并将每个算法封装起来&#xff0c;使它们可以互相替换。策略模式让算法的变化不会影响使用算法的客户端&#xff0c;使得算法可以独立于客户端的变化而变化。…...

私域用户画像分析:你必须知道的3个关键点!

在互联网时代的变革中&#xff0c;私域流量成为越来越多企业的关注焦点。而了解私域用户画像是建立精准营销策略的关键一步。 今天&#xff0c;就给大家分享私域用户画像分析的三个关键点&#xff0c;让大家都能更好地进行用户画像分析。 1、市场需求 理解市场需求是把握用户…...

【MATLAB源码-第74期】基于matlab的OFDM-IM索引调制系统不同频偏误码率对比,对比OFDM系统。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 OFDM-IM索引调制技术是一种新型的无线通信技术&#xff0c;它将正交频分复用&#xff08;OFDM&#xff09;和索引调制&#xff08;IM&#xff09;相结合&#xff0c;以提高频谱效率和系统容量。OFDM-IM索引调制技术的基本思想…...

优于其他超导量子比特数千倍!猫态量子比特实现超过十秒的受控比特翻转时间

内容来源&#xff1a;量子前哨&#xff08;ID&#xff1a;Qforepost&#xff09; 文丨娴睿/慕一 排版丨沛贤 深度好文&#xff1a;2000字丨8分钟阅读 摘要&#xff1a;量子计算公司Alice & Bob和QUANTIC团队&#xff08;国立巴黎高等矿业学院PSL分校、巴黎高等师范学院和…...

QtXlsx库编译使用

文章目录 一、前言二、Windows编译使用2.1 用法①&#xff1a;QtXlsx作为Qt的附加模块2.1.1 检验是否安装Perl2.1.2 下载并解压QtXlsx源码2.1.3 MinGW 64-bit安装模块2.1.4 测试 2.2 用法②&#xff1a;直接使用源码 三、Linus编译使用3.1、安装Qt5开发软件包&#xff1a;qtbas…...

LeetCode题练习与总结:二叉树的层序遍历Ⅱ--107

一、题目描述 给你二叉树的根节点 root &#xff0c;返回其节点值 自底向上的层序遍历 。 &#xff08;即按从叶子节点所在层到根节点所在的层&#xff0c;逐层从左向右遍历&#xff09; 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;[…...

WIFI国家码设置的影响

记录下工作中关于国家码设置对WIFI的影响&#xff0c;以SKYLAB的SKW99和SDZ202模组为例进行说明。对应到日常&#xff0c;就是我们经常提及手机是“美版”“港版”等&#xff0c;它们的wifi国家码是不同的&#xff0c;各版本在wifi使用中遇到的各种情况与下面所述是吻合的。 现…...

2024年软考高项-信息系统管理师介绍-备考-考试内容-通过攻略

介绍 以下是计算机软件考试的资格设置&#xff0c;本文说的是高级资格中的信息系统项目管理师(简称"高项")&#xff0c;是比较热门和好考的选择&#xff0c;与中级的"系统集成项目管理工程师"有大部分的知识重叠交叉&#xff0c;中级考了"系统集成项…...

Python知识点复习

文章目录 Input & OutputVariables & Data typesPython字符串重复&#xff08;字符串乘法&#xff09;字符串和数字连接在一起print时&#xff0c;要强制类型转换int为str用input()得到的用户输入&#xff0c;是str类型&#xff0c;如果要以int形式计算的话&#xff0c…...

GeoScene产品学习视频收集

1、易智瑞运营的极思课堂https://www.geosceneonline.cn/learn/library 2、历年易智瑞技术公开课视频资料 链接&#xff1a;技术公开课-易智瑞信息技术有限公司&#xff0c;GIS/地理信息系统&#xff0c;空间分析-制图-位置智能-地图 3、一些关于GeoScene系列产品和技术操作的视…...

51单片机的最小系统详解

51单片机的最小系统详解 1. 引言 在嵌入式系统中,51单片机被广泛应用于各种小型控制器和嵌入式开发板中。相信很多人都接触过51单片机,但是对于51单片机的最小系统却了解得不够深入。本文将从振荡电路、电源模块、复位电路、LED指示灯和调试接口五个方面详细介绍51单片机的…...

路径规划搜路算法有哪些?

路径规划搜索算法是帮助移动机器人或自动化系统在环境中从起点导航至终点的计算方法。以下是一些常见的路径规划搜索算法&#xff1a; Dijkstra算法&#xff1a;一种经典的最短路径搜索算法&#xff0c;适用于没有负权边的图。 A*算法&#xff1a;一种启发式搜索算法&#xff…...

Hadoop学习之hdfs的操作

Hadoop学习之hdfs的操作 1.将HDFS中的文件复制到本地 package com.shujia.hdfs;import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.junit.After; import org.junit.Before; import org.j…...

DBAPI怎么进行数据格式转换

DBAPI如何进行数据格式的转换 假设现在有个API&#xff0c;根据学生id查询学生信息&#xff0c;访问API查看数据格式如下 {"data":[{"name":"Michale","phone_number":null,"id":77,"age":55}],"msg"…...

Oracle JSON 函数详解与实战

Oracle 数据库提供了丰富的 JSON 函数集&#xff0c;使得开发者可以高效地处理 JSON 数据。本文将详细介绍这些函数&#xff0c;包括它们的语法、使用场景、具体示例&#xff0c;以及在实际项目中的应用。 文章目录 JSON_VALUE语法参数说明示例 JSON_QUERY语法示例 JSON_TABLE语…...

C#面:请解释转发与跳转的区别

在C#中&#xff0c;转发&#xff08;forwarding&#xff09;和跳转&#xff08;jumping&#xff09;是两种不同的控制流程操作。 转发 是指将控制权从一个方法或函数转移到另一个方法或函数。在转发中&#xff0c;程序会将当前的执行状态传递给另一个方法&#xff0c;并在该方…...

Java+IDEA+SpringBoot药物不良反应ADR智能监测系统源码 ADR智能化监测系统源码

JavaIDEASpringBoot药物不良反应ADR智能监测系统源码 ADR智能化监测系统源码 药物不良反应&#xff08;Adverse Drug Reaction&#xff0c;ADR&#xff09;是指在使用合格药品时&#xff0c;在正常的用法和用量下出现的与用药目的无关的有害反应。这些反应往往因药物种类、使用…...

linux系统模拟资源消耗的简单手段

当我们在做系统性能&#xff0c;稳定性&#xff0c;高可用等特殊场景的测试时&#xff0c;往往要对计算机的硬件资源做出比较苛刻的限制&#xff0c;因此需要最简便的办法增加CPU&#xff0c;内存&#xff0c;磁盘&#xff0c;网络等硬件环境的资源压力。下面介绍实现这些操作的…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)

CSI-2 协议详细解析 (一&#xff09; 1. CSI-2层定义&#xff08;CSI-2 Layer Definitions&#xff09; 分层结构 &#xff1a;CSI-2协议分为6层&#xff1a; 物理层&#xff08;PHY Layer&#xff09; &#xff1a; 定义电气特性、时钟机制和传输介质&#xff08;导线&#…...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块&#xff0c;它提供了一个轻量级的 HTTP 服务器实现&#xff0c;主要用于构建基于 HTTP 的应用程序和服务。 功能介绍&#xff1a; 主要功能 HTTP服务器功能&#xff1a; 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

基于Docker Compose部署Java微服务项目

一. 创建根项目 根项目&#xff08;父项目&#xff09;主要用于依赖管理 一些需要注意的点&#xff1a; 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件&#xff0c;否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

微服务商城-商品微服务

数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

【JavaWeb】Docker项目部署

引言 之前学习了Linux操作系统的常见命令&#xff0c;在Linux上安装软件&#xff0c;以及如何在Linux上部署一个单体项目&#xff0c;大多数同学都会有相同的感受&#xff0c;那就是麻烦。 核心体现在三点&#xff1a; 命令太多了&#xff0c;记不住 软件安装包名字复杂&…...

Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理

引言 Bitmap&#xff08;位图&#xff09;是Android应用内存占用的“头号杀手”。一张1080P&#xff08;1920x1080&#xff09;的图片以ARGB_8888格式加载时&#xff0c;内存占用高达8MB&#xff08;192010804字节&#xff09;。据统计&#xff0c;超过60%的应用OOM崩溃与Bitm…...