当前位置: 首页 > 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;网络等硬件环境的资源压力。下面介绍实现这些操作的…...

RPR方法:利用惯性主轴实现分子向量性质的快速准确预测

1. 项目概述&#xff1a;为什么分子向量预测是个“方向感”难题&#xff1f;在计算化学和材料模拟的日常工作中&#xff0c;我们常常需要预测分子的各种性质。其中&#xff0c;像能量这样的标量性质相对“好说话”——无论你把分子怎么转&#xff0c;它的总能量是不变的。所以&…...

双稳健机器学习在时间序列因果推断中的应用:以脉冲响应函数为例

1. 项目概述&#xff1a;当因果推断遇上时间序列在宏观经济和金融领域&#xff0c;我们常常需要回答这样的问题&#xff1a;当中央银行突然宣布加息0.25个百分点&#xff0c;失业率在未来两年内会如何变化&#xff1f;或者&#xff0c;一项新的财政刺激政策出台后&#xff0c;G…...

基于Hugging Face与Gradio的智能问答系统构建实战

1. 项目概述&#xff1a;从零构建一个可交互的智能问答系统 如果你对自然语言处理&#xff08;NLP&#xff09;感兴趣&#xff0c;并且一直想亲手搭建一个能“读懂”文章并回答问题的智能系统&#xff0c;那么这篇文章就是为你准备的。过去几年&#xff0c;基于Transformer架构…...

Leslie矩阵建模:从种群动力学到捕食竞争与机器学习拟合

1. 项目概述&#xff1a;从矩阵视角看种群兴衰在生态学和种群生物学里&#xff0c;我们总想预测未来&#xff1a;这片森林里的鹿群十年后会怎样&#xff1f;引入狼群后&#xff0c;整个系统会稳定还是崩溃&#xff1f;传统微分方程模型&#xff08;比如经典的Lotka-Volterra方程…...

FPGA加速机器学习在粒子物理触发系统中的应用与实战

1. 项目概述&#xff1a;当FPGA遇上机器学习&#xff0c;为粒子物理装上“火眼金睛” 在大型强子对撞机&#xff08;LHC&#xff09;的心脏地带&#xff0c;每秒发生着数亿次质子对撞。每一次对撞都可能产生希格斯玻色子、顶夸克&#xff0c;或是我们尚未知晓的新物理现象。然而…...

Burp Suite扫描深度配置指南:被动扫描、主动扫描与自定义插入点协同调优

1. 这不是“点一下就扫完”的配置&#xff0c;而是扫描质量的分水岭 很多人把 Burp Suite Scanner 当成一个“自动漏洞探测器”——填个 URL&#xff0c;点下“Active Scan”&#xff0c;等它跑完弹出一堆高危告警&#xff0c;就以为任务完成了。我见过太多这样的场景&#xff…...

基于RNN的数字-实体关系抽取:从非结构化文本中提取结构化信息

1. 项目概述与核心价值在信息爆炸的时代&#xff0c;我们每天都会接触到海量的非结构化文本&#xff0c;比如医学文献、金融报告、新闻资讯。这些文本中蕴含着大量有价值的结构化信息&#xff0c;例如“患者平均年龄67.6岁”、“手术成功率为38%”、“公司营收增长15%”。传统上…...

实测天下工厂:用它找工厂客户,数据准不准、覆盖全不全?

做 B2B 销售的人都知道&#xff0c;找到一份"高质量工厂名单"有多难。 不是因为工厂数量少&#xff0c;而是因为现有渠道普遍存在一个结构性问题&#xff1a;工厂和非工厂混在一起&#xff0c;分不清楚。用通用企业查询工具检索某个行业&#xff0c;跑出来的结果里&a…...

保姆级教程:用Python和Keras复现4D-CRNN脑电情绪识别模型(附DEAP/SEED数据集处理全流程)

从脑电信号到情绪识别&#xff1a;4D-CRNN模型实战全解析在脑机接口与情感计算领域&#xff0c;脑电信号&#xff08;EEG&#xff09;情绪识别一直是个充满挑战又极具应用价值的方向。传统方法往往难以同时捕捉EEG信号的时空频多维特征&#xff0c;而4D-CRNN模型通过创新的四维…...

量子计算中的SWAP门原理与应用解析

1. 量子计算中的SWAP门基础原理量子计算区别于经典计算的核心在于量子比特&#xff08;qubit&#xff09;的叠加态和纠缠态特性。在量子线路设计中&#xff0c;SWAP门作为基础量子逻辑门之一&#xff0c;扮演着量子信息交换的关键角色。与经典计算中的位交换不同&#xff0c;量…...