STM32 使用STM32F103控制无源蜂鸣器发声播放音乐

2023-11-09

使用STM32控制无源蜂鸣器发声播放音乐

【注:学习STM32总结做的笔记,大神勿喷。有不足之处还望不吝赐教。
-----本篇大部分转载而来,有侵权请联系作者,谢谢。】
原博客地址:
https://blog.csdn.net/fanxp66/article/details/80264700
https://blog.csdn.net/SNEZ_H/article/details/71172010

一、无源蜂鸣器和有源蜂鸣器
有源蜂鸣器内含振荡源,只要一通电就发声,但发生频率固定,音色单一;无源蜂鸣器内部不含振荡源,内部结构相当于电磁场扬声器,可以通过给他输出一定频率的信号才能发声。
人耳能听到的频率范围在20Hz–20kHz之间,通过STM32的GPIO引脚快速切换高低电平输出就能实现无源蜂鸣器的发声,切换的频率不同,发出的音调就不一样。

二、音乐播放的实现
一段音乐就是不同频率的声音按一定的时间节拍转换发出。所以音乐包含音调和节拍信息。

程序中首先准备音频数据表:

// 低Si Do Re Mi Fa So La Si ¸高Do¸高Re¸高Mi¸高Fa¸高So 无
uc16 tone[] ={247,262,294,330,349,392,440,294,523, 587, 659, 698, 784, 1000};
u8 music[]={ 5,5,6,8,7,6,5,6,13,13,……};//音调
u8 time[] = { 2,4,2,2,2,2,2,8,4, 4, ……}; //节拍时间
依次从音调数组中取music[i],然后根据music[i]的值在tone数组中得到该音的发声频率(tone[music[i]]),调用sound函数控制蜂鸣器发声,声音的发声时间有time数组控制。

如果我们能够控制好频率和节拍,那就有可能演奏出动听的音乐。因此,我们首先需要搞清楚各音调的频率,具体见下表(分别为低音、中音和高音):
在这里插入图片描述
我们知道了音调的频率后,下一步就是控制音符的演奏时间。每个音符都会播放一定的时间,这样才能构成一首优美的曲子,而不是生硬的一个调的把所有的音符一股脑的都播放出来。音符节奏分为一拍、半拍、1/4拍、1/8拍,我们规定一拍音符的时间为1;半拍为0.5;1/4拍为0.25;1/8拍为0.125……,所以我们可以为每个音符赋予这样的拍子播放出来,音乐就成了。
在这里插入图片描述
从简谱看,该音乐是C调的,这里的各音符对应的频率对应的是上表中C调的部分。另外,该音乐为四分之三拍,每个对应为1拍。(我们知道,音符节奏分为一拍、半拍、1/4拍、1/8拍,我们规定一拍音符的时间为1;半拍为0.5;1/4拍为0.25;1/8拍为0.125……,)几个特殊音符说明如下:
第一,普通音符。如第一个音符5,对应频率393,占1拍。
第二,带下划线音符,表示0.5拍;两个下划线是四分之一拍(0.25)。
第三,有的音符后带一个点,表示多加0.5拍,即1+0.5。
第四,有的音符后带一个“—”,表示多加1拍,即1+1。
第五,有的两个连续的音符上面带弧线,表示连音,可以稍微改下连音后面那个音的频率,比如减少或增加一些数值(需自己调试),这样表现会更流畅,其实不做处理,影响也不大。

** 注:因为我不会看乐谱,编的并不怎么样,所以。。。如果要改成别的歌曲,改时间和音调就可以了。**

源码地带:
beep.c

#include "beep.h"
#include "delay.h"

 int melody[] = {50, 50, 50, 50, 200, 200, 200, 400, 400, 500, 500, 500};
 
void BEEP_Init(void)
{ 
 GPIO_InitTypeDef  GPIO_InitStructure; 
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);   
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;  
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 GPIO_Init(GPIOA, &GPIO_InitStructure);
 GPIO_ResetBits(GPIOA,GPIO_Pin_11);
    
// GPIO_SetBits(GPIOA,GPIO_Pin_11);
}

void Sound(u16 frq)
{
    u32 time;
    if(frq != 1000)
    {
        time = 500000/((u32)frq);
        BEEP = 1;
        delay_us(time);
        BEEP = 0;
        delay_us(time);
    }else
        delay_us(1000);
}
void Sound2(u16 time)
{
    BEEP = 1;
    delay_ms(time);
    BEEP = 0;
    delay_ms(time);
}

void play_successful(void)
{
    int id=0;
    for(id = 0 ;id < 12 ;id++)
    {
        Sound2(melody[id]);
    }
}
void play_failed(void)
{
    int id=0;
    for(id = 11 ;id >=0 ;id--)
    {
        Sound2(melody[id]);
    }
}
void play_music(void)
{    
//红海情歌
//    uc16 tone[] = {247,262,294,330,349,392,440,294,523,587,659,698,784,1000};    
//    u8 music[]={5,5,6,8,7,6,5,6,13,13,5,5,6,8,7,6,5,3,13,13,2,2,3,5,3,5,6,3,2,1,6,6,5,6,5,3,6,5,13,13,
//                  5,5,6,8,7,6,5,6,13,13,5,5,6,8,7,6,5,3,13,13,2,2,3,5,3,5,6,3,2,1,6,6,5,6,5,3,6,1,    
//              13,8,9,10,10,9,8,10,9,8,6,13,6,8,9,9,8,6,9,8,6,5,13,2,3,5,5,3,5,5,6,8,7,6,6,10,9,9,8,6,5,6,8  };            
//    u8 time[] = {2,4,2,2,2,2,2,8,4, 4,2,4,2,2,2,2,2,8,4, 4, 2,4,2,4,2,2,4,2,2,8,2,4,2,2,2,2,2,8,4 ,4, 
//                2,4,2,2,2,2,2,8,4, 4,2,4,2,2,2,2,2,8,4,4,2,4,2,4,2,2,4,2,2,8,2,4,2,2,2,2,2,8,
//                4,2,2,2,4,2,2,2,2,2,8,4,2,2,2,4,2,2,2,2,2,8,4,2,2,2,4,2,2,5,2,6,2,4,2,2,2,4,2,4,2,2,12  };

/*************************************************************************************************************************/
    
//生日快乐    
                  // 0   1   2   3   4   5   6   7  低1  低2 低3 低4 低5 低6低7
    uc16 tone[] ={250,262,294,330,350,393,441,495,525,589,661,700,786,882,990}; //音调        
    u8 music[]={5,5,6,5,8,7,5,5,6,5,9,8,5,5,12,10,8,7,6,11,
                  11,10,8,9,8,5,5,8,5,5,12,10,8,7,6,11,11,10,8,9,8    //乐谱音调
    };     
        u8 time[] = {1,2,2,2,2,4,1,2,2,2,2,4,1,2,2,2,1,4,
                      4,1,2,2,2,2,4,1,2,4,1,2,2,2,1,4, 4,1,2,2,2,2,4,4        //节拍时间
        }; 
                    
    u32 yanshi;
    u16 i,e;
    yanshi = 10;
    for(i=0;i<sizeof(music)/sizeof(music[0]);i++){
        for(e=0;e<((u16)time[i])*tone[music[i]]/yanshi;e++){
            Sound((u32)tone[music[i]]);
        }    
    }
}

beep.h

#ifndef __BEEP_H
#define __BEEP_H     
#include "sys.h"

#define BEEP PAout(11)  

void BEEP_Init(void);         
void Sound(u16 frq);
void Sound2(u16 time);
void play_music(void);
void play_successful(void);
void play_failed(void);

#endif

main.c

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "key.h"
#include "led.h"
#include "beep.h" 

int main(void)
 {    
    delay_init(); 
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);     
    KEY_Init(); 
    LED_Init(); 
    BEEP_Init(); 

    while(1)
    {                
       play_music();        
    }    
}

文件源码下载链接:https://download.csdn.net/download/qq_28056277/10853285

https://download.csdn.net/download/qq_28056277/11429148
(考虑到积分越下载越贵的问题,就再上传了一次)
转载总结文章,若有侵权,请联系作者删除,谢谢。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32 使用STM32F103控制无源蜂鸣器发声播放音乐 的相关文章

随机推荐

  • 几种优化(求最优解)算法的比较

    遗传算法 优点是能很好的处理约束 能很好的跳出局部最优 最终得到全局最优解 全局搜索能力强 缺点是收敛较慢 局部搜索能力较弱 运行时间长 且容易受参数的影响 遗传算法适合求解离散问题 具备数学理论支持 但是存在着汉明悬崖等问题 模拟退火 优
  • ChatGPT与人类情感理解的挑战:解读复杂的情绪和态度

    导言 人类情感是复杂而多变的 涉及各种情绪 态度和情感表达方式 对于机器来说 理解和解读人类情感是一项具有挑战性的任务 然而 随着自然语言处理技术的进步 像ChatGPT这样的模型逐渐能够参与人类情感的解读和理解 本文将探讨ChatGPT在
  • 面试题-面经及知识重点

    1 葵花宝典 https blog csdn net jackfrued article details 44921941 1 面试整理 http www jfox info gao shou zheng zheng li java che
  • 计算机毕业设计之垃圾分类公益回收管理系统

    垃圾分类公益回收管理系统的开发过程中 采用B S架构 主要使用Java技术进行开发 结合最新流行的springboot框架 使用Mysql数据库和Eclipse开发环境 该垃圾分类公益回收管理系统包括用户 回收者和管理员 其主要功能包括垃圾
  • jstl引入maven项目常见问题

    在jsp页面中引入jstl标签库报错问题 1 引入标签时报错 排查历史 最后尝试通过降低jstl版本解决问题 2 jstl 在eclipse 中无法使用 解决方案 jstl jar 与 stand jar 单独下载而没有带c tld文件 下
  • idea 创建application.yml文件不变小叶子的解决方法

    首先你的确保你的pom xml中的包是全的 1 点击 2 选到你没有变小叶子的项目 3 将Spring加进去
  • SQL 快速插入数据 1000万条数据

    insert into 表名 select generate series 0 10000000 md5 random text clock timestamp
  • Unity内实现高级相机效果

    Cinemachine插件可以快速实现各种相机效果 例如跟随 分镜 推拉式镜头等 配合Timeline可以创建Cinemachine Track实现动画融合 从PackageManager上可以下载Cinemachine插件 它有以下几种类
  • Linux Bash单方括号与双方括号 [和[[的区别

    本文参考 Burak G kmen 的文章 Differences Between Single and Double Brackets in Bash 单括号 是 shell builtin 即 test 内置命令 type is a s
  • Spring boot Shiro anno不启作用问题分析

    1 分析 之前在Shiro中没有配置过静态资源过滤 这次在配置过程中给予静态资源anno发现还是会被拦截 查阅其它博客 基本上都是在说LinkedHashMap 过滤次序问题 但我最初就是这个 因此排除 后再翻阅相关博客的时候看到了 大佬博
  • 输出杨辉三角形(要求输出10行)

    include
  • Python 教程之 Pandas(14)—— 使用 Pandas 进行数据分析

    Pandas是最流行的用于数据分析的 Python 库 它提供高度优化的性能 后端源代码完全用C或Python编写 我们可以通过以下方式分析 pandas 中的数据 1 Series 2 数据帧 Series Series 是 pandas
  • TypeScript总结 一【数组,联合,交叉类型】

    最近刚把ts学完 简单总结一下 ts的话 更强调类型 更加严谨 非原始类型 1 object 不包括基础数据类型 小写的 let obj object a 1 let obj object 1 2 Object 包括基础数据类型 大写的O
  • 基于ARM的自来水厂全自动恒压供水监控系统

    文末下载完整资料 随着越来越多的场合正向自动化无人职守迈进 尤其在安全 监控等领域 为了进一步降低成本 减少人力的投资 以及更集中 更方便的掌握现场情况 许多场合都采用了电子监控设备 如办公室 发电站 机场 海关等等领域 而这些电子设备的设
  • KeyEvent事件

    Java按键事件KeyEvent 按键事件可以利用键盘来控制和执行一些动作 或者从键盘上获取输入 只要按下 释放一个键或者在一个组件上敲击 就会触发按键事件 KeyEvent对象描述事件的特性 按下 放开 或者敲击一个键 和对应的值 jav
  • 解决xgboost安装问题:xgboost.core.XGBoostError: XGBoost Library (xgboost.dll) could not be loaded.

    问题描述 下载xgboost 使用pip安装后 在python中导入import xgboost出错 如下 xgboost core XGBoostError XGBoost Library xgboost dll could not be
  • 常用计算机英文缩写,常用计算机英文缩写含义

    常用计算机英文缩写含义 AAL ATM适配层 ATM Adaptation Layer ABR 可用比特率 Available Bit Rate ACR 衰减串扰比 ADPCM 自适应差分PCM ADSL 非对称数字环路 Asymmetri
  • 使用idea导入Maven项目教程

    选择导入存在的项目 指定Maven模型 修改项目设置 在使用tomcat启动项目时 可能没有servlet api包需要手动导入 如果出现jar包问题 在settings中勾选 然后重新下载jar包 在Settings设置中设置jdk信息
  • 关于遗传算法

    关于遗传算法 有很多袋鼠 它们降落到喜玛拉雅山脉的任意地方 这些袋鼠并不知道它们的任务是寻找珠穆朗玛峰 但每过几年 就在一些海拔高度较低的地方射杀一些袋鼠 于是 不断有袋鼠死于海拔较低的地方 而越是在海拔高的袋鼠越是能活得更久 也越有机会生
  • STM32 使用STM32F103控制无源蜂鸣器发声播放音乐

    使用STM32控制无源蜂鸣器发声播放音乐 注 学习STM32总结做的笔记 大神勿喷 有不足之处还望不吝赐教 本篇大部分转载而来 有侵权请联系作者 谢谢 原博客地址 https blog csdn net fanxp66 article de