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

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

React 第五十五节 Router 中 useAsyncError的使用详解

前言 useAsyncError 是 React Router v6.4 引入的一个钩子&#xff0c;用于处理异步操作&#xff08;如数据加载&#xff09;中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误&#xff1a;捕获在 loader 或 action 中发生的异步错误替…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别

一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

五年级数学知识边界总结思考-下册

目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解&#xff1a;由来、作用与意义**一、知识点核心内容****二、知识点的由来&#xff1a;从生活实践到数学抽象****三、知识的作用&#xff1a;解决实际问题的工具****四、学习的意义&#xff1a;培养核心素养…...

工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配

AI3D视觉的工业赋能者 迁移科技成立于2017年&#xff0c;作为行业领先的3D工业相机及视觉系统供应商&#xff0c;累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成&#xff0c;通过稳定、易用、高回报的AI3D视觉系统&#xff0c;为汽车、新能源、金属制造等行…...

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包&#xff1a; for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台

🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...