STM32蜂鸣器播放音乐

STM32蜂鸣器播放音乐

STM32蜂鸣器播放音乐 Do, Re, Mi, Fa,

1. 功能概述

本系统基于STM32F7系列微控制器,实现了以下功能:

  1. 通过7个按键控制蜂鸣器发声,按键对应不同的音符。
  2. 每个按键对应一个音符(Do, Re, Mi, Fa, Sol, La, Si),按下按键时蜂鸣器播放对应音符的声音。
  3. 利用PWM技术控制蜂鸣器发声频率,实现不同音符的效果。
  4. 按键松开时蜂鸣器停止发声,防止连续触发。

在这里插入图片描述

2. 硬件接线

2.1 按键与GPIO连接

系统使用STM32F7的GPIOB端口,连接7个按键,其中:

  • 按键1: GPIO_PIN_0
  • 按键2: GPIO_PIN_1
  • 按键3: GPIO_PIN_3
  • 按键4: GPIO_PIN_4
  • 按键5: GPIO_PIN_5
  • 按键6: GPIO_PIN_6
  • 按键7: GPIO_PIN_7

每个按键的另一端连接到地(GND),GPIO引脚配置为上拉输入模式(GPIO_PULLUP)。

2.2 蜂鸣器与GPIO连接

蜂鸣器通过GPIOA的PA6引脚与STM32连接:

  • PA6配置为TIM3_CH1通道的PWM输出。
  • 蜂鸣器的一端连接到PA6,另一端连接到GND。

2.3 电源

  • STM32主控板通过USB供电。
  • 所有按键和蜂鸣器的电源均由STM32供电。

3. 软件实现原理

3.1 功能模块

软件设计主要包含以下功能模块:

3.1.1 PWM模块
  • 利用定时器TIM3的PWM功能产生控制蜂鸣器的信号。
  • 根据不同音符的频率设置PWM的周期(ARR)值,调整占空比控制音量。
3.1.2 按键扫描模块
  • 周期性读取GPIOB的引脚状态,判断按键是否按下。
  • 通过数组 KeyStatus[] 保存每个按键的状态(按下为1,松开为0)。
3.1.3 音符播放模块
  • 根据按键状态决定是否播放音符。
  • 使用Play_Tone()函数设置PWM频率并播放音符。
  • 使用Stop_Tone()函数停止蜂鸣器播放。

3.2 软件流程

3.2.1 主程序流程

主程序主要流程如下:

  1. 初始化系统时钟和HAL库。
  2. 配置GPIO用于按键输入和蜂鸣器输出。
  3. 初始化TIM3定时器的PWM功能。
  4. 主循环中:
    • 调用按键扫描函数Keypad_Read()更新按键状态。
    • 检查每个按键状态,对应播放音符。
    • 播放音符后延时一定时间避免重复触发。
    • 调用Stop_Tone()停止蜂鸣器播放。
3.2.2 按键扫描流程

按键扫描采用循环遍历方式:

  1. 定义GPIOB引脚的数组 pins[],保存每个按键对应的GPIO引脚。
  2. 遍历引脚数组,调用HAL_GPIO_ReadPin()读取每个按键状态。
  3. 如果引脚电平为低(GPIO_PIN_RESET),表示按键被按下。
  4. 更新 KeyStatus[] 数组。
3.2.3 音符播放流程

音符播放利用PWM实现:

  1. 根据音符频率计算PWM的自动重装载值(ARR)。
  2. 调用__HAL_TIM_SET_AUTORELOAD()更新TIM3的ARR值。
  3. 调用__HAL_TIM_SET_COMPARE()设置占空比。
  4. 开始PWM输出,蜂鸣器发声。
  5. 延时指定时间后停止PWM输出。

主函数代码:

#include "stm32f7xx.h"
#include "main.h"
#include "./tim/bsp_basic_tim.h"
#include "./led/bsp_led.h"
#include "./usart/bsp_usart.h"
#include "./beep_music/beep_music.h"
TIM_HandleTypeDef htimx; // 定义一个全局定时器句柄void SystemClock_Config(void);
void PWM_Init(void);
void Set_PWM_Frequency(uint32_t frequency);
void Play_Music(int *tune, float *duration, int length);
/*** @brief  主函数* @param  无* @retval 无*/
int main(void) 
{/* 初始化系统时钟为216MHz */SystemClock_Config();/* 初始化LED */LED_GPIO_Config();/* 初始化基本定时器定时,1s产生一次中断 *///TIMx_Configuration();PWM_Init();               // 初始化 PWM//	int length = sizeof(tune) / sizeof(tune[0]); // 获取音符数量
//    Play_Music(tune, duration, length);play_music();	while(1){   }
}/*** @brief  System Clock 配置*         System Clock 配置如下 : *         System Clock source            = PLL (HSE)*         SYSCLK(Hz)                     = 216000000*         HCLK(Hz)                       = 216000000*         AHB Prescaler                  = 1*         APB1 Prescaler                 = 4*         APB2 Prescaler                 = 2*         HSE Frequency(Hz)              = 25000000*         PLL_M                          = 25*         PLL_N                          = 432*         PLL_P                          = 2*         PLL_Q                          = 9*         VDD(V)                         = 3.3*         Main regulator output voltage  = Scale1 mode*         Flash Latency(WS)              = 7* @param  无* @retval 无*/
void SystemClock_Config(void)
{RCC_ClkInitTypeDef RCC_ClkInitStruct;RCC_OscInitTypeDef RCC_OscInitStruct;HAL_StatusTypeDef ret = HAL_OK;/* 使能HSE,配置HSE为PLL的时钟源,配置PLL的各种分频因子M N P Q * PLLCLK = HSE/M*N/P = 25M / 25 *432 / 2 = 216M*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLM = 25;RCC_OscInitStruct.PLL.PLLN = 432;RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;RCC_OscInitStruct.PLL.PLLQ = 9;ret = HAL_RCC_OscConfig(&RCC_OscInitStruct);if(ret != HAL_OK){while(1) { ; }}/* 激活 OverDrive 模式以达到216M频率  */  ret = HAL_PWREx_EnableOverDrive();if(ret != HAL_OK){while(1) { ; }}/* 选择PLLCLK作为SYSCLK,并配置 HCLK, PCLK1 and PCLK2 的时钟分频因子 * SYSCLK = PLLCLK     = 216M* HCLK   = SYSCLK / 1 = 216M* PCLK2  = SYSCLK / 2 = 108M* PCLK1  = SYSCLK / 4 = 54M*/RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; /* 在HAL_RCC_ClockConfig函数里面同时初始化好了系统定时器systick,配置为1ms中断一次 */ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7);if(ret != HAL_OK){while(1) { ; }}  
}/*** @brief 配置系统时钟* @retval 无*//*** @brief 初始化 PWM* @retval 无*/
void PWM_Init(void)
{// 开启定时器和 GPIO 时钟__HAL_RCC_TIM3_CLK_ENABLE();  // 使用 TIM3 作为示例__HAL_RCC_GPIOA_CLK_ENABLE(); // 使用 GPIOA 作为示例// 配置 PWM 输出引脚GPIO_InitTypeDef GPIO_InitStruct = {0};GPIO_InitStruct.Pin = GPIO_PIN_6;       // 使用 PA6(TIM3_CH1)作为 PWM 输出GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; // 复用推挽模式GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);// 配置定时器htimx.Instance = TIM3;                        // 定时器实例为 TIM3htimx.Init.Prescaler = (SystemCoreClock / 1000000) - 1; // 定时器频率分频到 1MHz (1μs 精度)htimx.Init.CounterMode = TIM_COUNTERMODE_UP;  // 向上计数模式htimx.Init.Period = 1000 - 1;                 // 默认周期,产生 1kHz 方波htimx.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;htimx.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;HAL_TIM_PWM_Init(&htimx);                     // 初始化定时器 PWM// 配置 PWM 通道TIM_OC_InitTypeDef sConfigOC = {0};sConfigOC.OCMode = TIM_OCMODE_PWM1;           // PWM 模式 1sConfigOC.Pulse = 500;                        // 默认占空比 50%sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;   // 高电平有效sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;HAL_TIM_PWM_ConfigChannel(&htimx, &sConfigOC, TIM_CHANNEL_1); // 配置通道 1// 启动 PWM 输出HAL_TIM_PWM_Start(&htimx, TIM_CHANNEL_1);
}/*** @brief 设置 PWM 输出频率* @param frequency 频率 (Hz)* @retval 无*/
void Set_PWM_Frequency(uint32_t frequency)
{if (frequency == 0) // 如果频率为 0,停止 PWM 输出{__HAL_TIM_SET_COMPARE(&htimx, TIM_CHANNEL_1, 0);return;}uint32_t period = 1000000 / frequency; // 周期 = 1秒(1000000us) / 频率__HAL_TIM_SET_AUTORELOAD(&htimx, period - 1); // 设置自动重装载值__HAL_TIM_SET_COMPARE(&htimx, TIM_CHANNEL_1, period / 2); // 设置占空比为 50%
}/*** @brief 播放音乐* @param tune 音符数组* @param duration 音符持续时间数组* @param length 音符数量* @retval 无*/
void Play_Music(int *tune, float *duration, int length)
{for (int i = 0; i < length; i++){if (tune[i] == 0) // 如果音符为 0,停止播放,表示间隔{Set_PWM_Frequency(0); // 停止 PWM}else{Set_PWM_Frequency(tune[i]); // 设置音符对应的频率}HAL_Delay(duration[i] * 1000); // 持续时间(将秒转换为毫秒)}Set_PWM_Frequency(0); // 播放完成后停止 PWM
}/*********************************************END OF FILE**********************/

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于docker-compose 部署可道云资源管理器

容器编排Explorer 容器化部署MariaDB容器化部署Redis容器化部署PHP容器化部署Nginx编排部署compose服务 var code “9861ce02-1202-405b-b419-4dddd337aaa7” GitHub官网 KodExplorer 是一款网页文件管理器。它也是一个网页代码编辑器&#xff0c;可让你直接在网页浏览器中开…

【Git】--- Git远程操作 标签管理

Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏&#xff1a; Git 前面我们学习的操作都是在本地仓库进行了&#xff0c;如果团队内多人协作都在本地仓库操作是不行的&#xff0c;此时需要新的解决方案 --- 远程仓库。…

Deepseek API+Python 测试用例一键生成与导出 V1.0.3

** 功能详解** 随着软件测试复杂度的不断提升,测试工程师需要更高效的方法来设计高覆盖率的测试用例。Deepseek API+Python 测试用例生成工具在 V1.0.3 版本中,新增了多个功能点,优化了提示词模板,并增强了对文档和接口测试用例的支持,极大提升了测试用例设计的智能化和易…

Axure RP9.0 教程:左侧菜单列表导航 ( 点击父级菜单,子菜单自动收缩或展开)【响应式的菜单导航】

文章目录 引言I 实现步骤添加商品管理菜单组推拉效果引言 应用场景:PC端管理后台页面,左侧菜单列表导航。 思路: 用到了动态面板的两个交互效果来实现:隐藏/显示切换、展开/收起元件向下I 实现步骤 添加商品管理菜单组 在左侧画布区域添加一个菜单栏矩形框;再添加一个商…

详细比较StringRedisTemplate和RedisTemplate的区别及使用方法,及解决融合使用方法

前言 感觉StringRedisTemplate和RedisTemplate非常的相识&#xff0c;到底有什么区别和联系呢&#xff1f;点开idea&#xff0c;打开其依赖关系&#xff0c;可以看出只需使用maven依赖包spring-boot-starter-data-redis&#xff0c;然后在service中注入StringRedisTemplate或者…

SpringSecurity——前后端分离登录认证

SpringSecurity——前后端分离登录认证的整个过程 前端&#xff1a; 使用Axios向后端发送请求 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>登录</title><script src"https://cdn…

如何用腾讯云建站做好一个多语言的建筑工程网站?海外用户访问量提升3倍!分享我的经验

作为新疆地区领先的工程建筑企业&#xff0c;我们深知在数字化浪潮中&#xff0c;一个专业、高效且具备国际视野的官方网站是企业形象与业务拓展的“门面担当”。然而&#xff0c;传统的建站流程复杂、技术门槛高、多语言适配难等问题&#xff0c;曾让我们在数字化转型中举步维…

遥控器钥匙学习---通过uds指令

1、实际报文 2、硬件配置信息 使用原gateway硬件&#xff0c;软件基于sbcm-main工程新建的一个分支。主要用于钥匙学习的指令发送。 3、后续更改 这里需要细化一下&#xff0c;为了后续方便测试 4、钥匙学习策略 可以学习2把钥匙 一次可以学习把钥匙&#xff0c;uds命令&…

QinQ项展 VLAN 空间

随着以太网技术在网络中的大量部署&#xff0c;利用 VLAN 对用户进行隔离和标识受到很大限制。因为 IEEE802.1Q 中定义的 VLAN Tag 域只有 12 个比特&#xff0c;仅能表示 4096 个 VLAN&#xff0c;无法满足城域以太网中标识大量用户的需求&#xff0c;于是 QinQ 技术应运而生。…

给Web开发者的HarmonyOS指南02-布局样式

给Web开发者的HarmonyOS指南02-布局样式 本系列教程适合鸿蒙 HarmonyOS 初学者&#xff0c;为那些熟悉用 HTML 与 CSS 语法的 Web 前端开发者准备的。 本系列教程会将 HTML/CSS 代码片段替换为等价的 HarmonyOS/ArkUI 代码。 布局基础对比 在Web开发中&#xff0c;我们使用CS…

mapbox进阶,添加鹰眼图控件

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️mapboxgl.Map style属性1.3 ☘️mapboxgl-minimap 鹰眼控件二、🍀添加…

Linux 配置时间服务器

一、同步阿里云服务器时间 服务端设置 1.检查chrony服务是否安装&#xff0c;设置chrony开机自启&#xff0c;查看chrony服务状态 [rootnode1-server ~]# rpm -q chrony # rpm -q 用于查看包是否安装 chrony-4.3-1.el9.x86_64 [rootnode1-server ~]# systemctl enable --n…

Android实践开发制作小猴子摘桃小游戏

Android实践制作小猴子摘桃小游戏 实践素材项目源文件获取&#xff1a;Android可以存在版本差异项目如果不能正确运行&#xff0c;可以使用里面的素材自己构建项目Android实践制作小猴子摘桃小游戏Android实践制作小猴子摘桃小游戏https://mp.weixin.qq.com/s/jNU_hVfj9xklsil…

数据库查询练习

1.单表查询 CREATE TABLE worker (部门号 int(11) NOT NULL,职工号 int(11) NOT NULL,工作时间 date NOT NULL,工资 float(8,2) NOT NULL,政治面貌 varchar(10) NOT NULL DEFAULT 群众,姓名 varchar(20) NOT NULL,出生日期 date NOT NULL,PRIMARY KEY (职工号) ) ENGINEInnoDB…

VGG 改进:添加ScConv空间与通道特征重构卷积

目录 1. ScConv空间与通道特征重构卷积 2. VGG+ScConv模块 3. 完整代码 Tips:融入模块后的网络经过测试,可以直接使用,设置好输入和输出的图片维度即可 1. ScConv空间与通道特征重构卷积 ScConv (Spatial and Channel reconstruction Convolution) 是一种旨在减少卷积神…

如何优化SQL查询以提高数据库性能?

你正在自助餐厅&#xff0c;所有的食物看起来都很美味。但你不是拿一个盘子&#xff0c;只取你需要的&#xff0c;而是开始从各个角落堆满食物&#xff0c;弄得一团糟&#xff0c;速度也慢了下来。结果是什么&#xff1f;你拿的东西很多并且效率低下。 这就像没有优化的SQL查询…

VS2022的第一个Qt程序——实战《加载并显示图像》

目录 一、UI设计 S1&#xff1a;双击Form Files下.ui文件&#xff0c;进入ui设计界面Qt Designer S2&#xff1a;然后拖动一个Push Button和Label控件到界面 S3&#xff1a;点击信号与槽&#xff0c;然后点击PushButton往外拉一下 S4&#xff1a;松开鼠标进入配置连接界面…

决策树算法详解:从西瓜分类到实战应用

目录 0. 引言 1. 决策树是什么&#xff1f; 1.1 生活中的决策树 1.2 专业版决策树 2. 如何构建决策树&#xff1f; 2.1 关键问题&#xff1a;选哪个特征先判断&#xff1f; 2.1.1 信息熵&#xff08;数据混乱度&#xff09; 2.1.2 信息增益&#xff08;划分后的整洁度提…

Python 标准库与数据结构

Python的标准库提供了丰富的内置数据结构和函数&#xff0c;使用这些工具能为我们提供一套强有力的工具。 需要注意的是&#xff0c;相比C与Java&#xff0c;Python的一些特点&#xff1a; Python不需要显式声明变量类型Python没有模板(Template)的概念&#xff0c;因为Pytho…

VUE3 路由配置

1.下载 VueRouter 模块 在命令行中输入 yarn add vue-router 2.导⼊相关函数 在自己创建的router/index.js 文件中 import { createRouter, createWebHashHistory } from vue-router 3.创建路由实例 在自己创建的router/index.js 文件中 const theFirstRouter ()>{return…