【补档_C51单片机】基于C51的蜂鸣器音乐盒工程源码解析(可播放《打上花火》)
项目地址:https://gitee.com/daycen/c51-music-box
通过Keil uVision3打开即可使用
以前做的一些小硬件,现补档至博客
1 功能及总体方案
1.1 功能描述
一个可通过无源蜂鸣器播放任意预先编码好的歌曲的基于51单片机设计的音乐盒。
最小系统部分:由STC89S52单片机X接口连接晶振电路,RESET连接复位电路所构成的满足最简单应用的单片机系统。
无源蜂鸣器驱动电路:由一个1K的分压电阻与无源蜂鸣器串联组成,作为系统的发声源。
软件模块:由计算得出的每个声调的频率数据数组、歌曲编码数组、延时函数、定时器中断函数以及主循环函数构成,用于改变无源蜂鸣器的发声声调。
1.2 系统组成及工作过程
系统组成框图如下:

2 硬件设计
2.1 硬件电路总体设计

单片机最小系统包括单片机、时钟电路、复位电路与5V电源构成,时钟电路提供的时钟信号给单片机提供了一个时间基准。复位电路则是让单片机回到原始状态重新执行程序。
实物图如下:




2.2 模块电路设计
播放一段音乐需要的是两个元素,一个是音调,另一个是音符。首先要了解对应的音调,音调主要由声音的频率决定,同时也与声音强度有关。对一定强度的纯音,音调随频率的升降而升降;对一定频率的纯音、低频纯音的音调随声强增加而下降,高频纯音的音调却随强度增加而上升。另外,音符的频率有所不同。音符的发音主要靠不同的音频脉冲。利用单片机的内部定时器/计数器0,使其工作在模式1,定时中断,然后控制P2.0引脚的输出音乐。只要算出某一音频的周期(1/频率),然后将此周期除以2,即为半周期的时间,利用定时器计时这个半周期时间,每当计时到后就将输出脉冲的I/O反相,然后重复计时此半周期时间再对I/O反相,就可在I/O脚上得到此频率的脉冲。
音乐盒的设计采用STC89C52作为主控芯片,利用单片机内部定时器产生特定的音符频率,控制节拍。
音频模块选用无源蜂鸣器作为发声源,因为它制作成本低,声音频率范围宽,可高分贝的发出某些频率的超声波以及可以做出音符的效果。
PCB图:


3 软件设计
3.1 软件总体设计
软件的总流程图如下

3.2 主程序设计
主程序的设计思路就是将一首乐曲分成三个变量来控制,分别是曲调、所在音区、时长。而控制曲调的因素即频率又分成高八位和第八位两个表,每演奏一个曲调,就根据该曲调的三个变量来取值。此外,x变量用于定义休止符,控制歌曲的不演奏(间断)延时
3.3 各模块程序设计
①音调频率换算
要想产生音频脉冲信号,需要算出某音频的周期(1/频率),然后将此周期除以2,即为半周期的时间。利用单片机定时器计时这个半周期的时间,每当计时到后就输出脉冲的I/O口反相,这样就在此I/O口上得到此脉冲的频率。
例如,若要产生C大调中的Re(频率为587Hzs)的音频脉冲,其音频信号的脉冲周期T=1/587=1703.5775us,半周期时间为852us,因此总要令计时器计数=852us/1us=852,在每计数852时将I/O口反相,就可以得到Re这个音。按照这种方式可得到一张音符频率对应的半周期数值表,如下图

②歌曲编码
为了能够让程序按照乐谱调用相应的音调数据发声,于是这里我定义了一种编码方式对乐谱进行转换,每个音符的对应的编码包含四个数字:第一个数代表第几个音符(对应简谱中的1234567);第二个数代表第几个八度(音高);第三个数代表时长(以半拍为单位,在钢琴简谱中,音符的右边有一个点代表1.5倍时长);第四个数仅定义为1或0,1表示休止符,间断延时一个节拍而0则不进行任何操作(统一以1121编码代表休止符);
在本程序中,我一共写入了两首歌,分别是《打上花火》和《aLIEz》,在第一首歌播放完毕后会间隔3个节拍的时间播放下一首。特别说明的是,由于编码参考的是钢琴简谱,故编码表中部分时长为3的音符调整为了2目的是让歌曲节奏快一些,且对我对双手谱的复弹做了一定删减以保证听感。
③休止符间断延时函数
该函数由一组双重循环构成,当数组遍历到编码为1121的休止符时,程序会延时a个半拍,模拟出乐谱上休止符的功能。

④主延时函数
与休止符函数类似,主延时函数也由一组双重循环构成,共延时t/2个节拍以控制蜂鸣器发声的时长。此处仅延时t/2个节拍是为了加快歌曲节奏。

⑤定时器中断函数
该函数为T0中断函数。根据图3数值表找到的定时器的初始值被送入这里,无源蜂鸣器被驱动而发声

⑥音乐播放函数
该函数启动T0, 由T0输出方波去发音,并传递参数给图5中的主延时函数,对节拍时长进行控制。

⑦主函数
主程序流程图如下

【补档_C51单片机】基于C51的蜂鸣器音乐盒工程源码解析(可播放《打上花火》)的更多相关文章
- 基于Linux ALSA音频驱动的wav文件解析及播放程序 2012
本设计思路:先打开一个普通wav音频文件,从定义的文件头前面的44个字节中,取出文件头的定义消息,置于一个文件头的结构体中.然后打开alsa音频驱动,从文件头结构体取出采样精度,声道数,采样频率三个重 ...
- 【补档_STM32单片机】脉搏波采集显示硬件设计
一.脉搏波简介 脉搏一般情况下指的都是动脉脉搏.每分钟的脉搏次数称为脉率,正常情况下与心率是一致的.心脏的一次收缩和舒张成为一个心动周期.在每个心动周期内,心室的收缩和舒张会引起脉内压力的周期性波 ...
- 基于Spring注解的上下文初始化过程源码解析(一)
最近工作之余有时间和精力,加上平时对源码比较感兴趣,就开始啃起了Spring源码.为加深印象写了这篇博客,如有错误,望各位大佬不吝指正. 我看的是Spring5的源码,从同性社区download下来后 ...
- 基于Spring注解的上下文初始化过程源码解析(二)
上一篇看完了register方法的代码,继续跟后面代码 后面执行refresh方法,代码清单如下: public void refresh() throws BeansException, Illeg ...
- 服务器文档下载zip格式 SQL Server SQL分页查询 C#过滤html标签 EF 延时加载与死锁 在JS方法中返回多个值的三种方法(转载) IEnumerable,ICollection,IList接口问题 不吹不擂,你想要的Python面试都在这里了【315+道题】 基于mvc三层架构和ajax技术实现最简单的文件上传 事件管理
服务器文档下载zip格式 刚好这次项目中遇到了这个东西,就来弄一下,挺简单的,但是前台调用的时候弄错了,浪费了大半天的时间,本人也是菜鸟一枚.开始吧.(MVC的) @using Rattan.Co ...
- ARM开发(2)基于STM32的蜂鸣器
基于STM32的蜂鸣器 一 蜂鸣器原理: 1.1 本实验实现1个蜂鸣器间隔1S鸣叫. 1.2 实验思路:根据电路图原理,给蜂鸣器相关引脚赋予高低电平,实现电路的导通,使蜂鸣器实现鸣叫或不鸣. 1 ...
- STL 补档
STL 补档 1.vector 作用:它能够像容器一样存放各种类型的对象,简单地说,vector是一个能够存放任意类型的动态数组,能够增加和压缩数据. vector在C++标准模板库中的部分内容,它是 ...
- 图论补档——KM算法+稳定婚姻问题
突然发现考前复习图论的时候直接把 KM 和 稳定婚姻 给跳了--emmm 结果现在刷训练指南就疯狂补档.QAQ. KM算法--二分图最大带权匹配 提出问题 (不严谨定义,理解即可) 二分图 定义:将点 ...
- String,StringBuffer和StringBuilder源码解析[基于JDK6]
最近指导几位新人,学习了一下String,StringBuffer和StringBuilder类,从反馈的结果来看,总体感觉学习的深度不够,没有读出东西.其实,JDK的源码是越读越有味的.下面总结一下 ...
- .Net Core 认证系统之基于Identity Server4 Token的JwtToken认证源码解析
介绍JwtToken认证之前,必须要掌握.Net Core认证系统的核心原理,如果你还不了解,请参考.Net Core 认证组件源码解析,且必须对jwt有基本的了解,如果不知道,请百度.最重要的是你还 ...
随机推荐
- 【转帖】Linux性能优化(一)——stress压力测试工具
https://blog.csdn.net/a642960662/category_11641226.html 一.stress简介 1.stress简介 stress是Linux的一个压力测试工具, ...
- [转帖]windows使用net user add用户并加入管理员,从而支持rdp远程登陆访问
C:\phpstudy_pro\WWW> net user test2 /add 命令成功完成. C:\phpstudy_pro\WWW> net user test2 Huawei ...
- 境内下载nodejs二进制文件
下载 nodejs 安装包的方法 找到一个境内的淘宝源 可以直接使用 下载速度还比较快 但是没有 龙芯的.. http://npm.taobao.org/mirrors/node/v10.20.0/
- 深度学习应用篇-计算机视觉-图像分类[3]:ResNeXt、Res2Net、Swin Transformer、Vision Transformer等模型结构、实现、模型特点详细介绍
深度学习应用篇-计算机视觉-图像分类[3]:ResNeXt.Res2Net.Swin Transformer.Vision Transformer等模型结构.实现.模型特点详细介绍 1.ResNet ...
- 3.2 IDAPro脚本IDC常用函数
IDA Pro内置的IDC脚本语言是一种灵活的.C语言风格的脚本语言,旨在帮助逆向工程师更轻松地进行反汇编和静态分析.IDC脚本语言支持变量.表达式.循环.分支.函数等C语言中的常见语法结构,并且还提 ...
- CSS背景设置与Emmet语法
CSS背景设置 通过CSS背景属性,可以给页面元素添加背景样式,页面元素指任意标签. 背景属性可以设置背景颜色,背景图片,背景平铺,背景图片位置,背景图像固定等. 背景颜色 一般默认值是:tran ...
- Dart常用核心知识
Dart简述 Dart 是一个为全平台构建快速应用的客户端优化的编程语言,免费且开源. Dart是面向对象的.类定义的.单继承的语言.它的语法涵盖了多种语言的语法特性,如C,JavaScirpt, J ...
- 【C语言进阶】【小项目】实现一个通讯录【C语言知识点汇总项目】通过这个项目,掌握C语言重要知识点
[C语言进阶][小项目]实现一个通讯录[C语言知识点汇总项目]通过这个项目,掌握C语言重要知识点 欢迎来到#西城s的博客,今天,博主带着大家用C实现一个通讯录!干货满满不要错过噢! 作者: #西城s ...
- 2022 多益网络hr面
不知道为啥 我的一面是hr面试,面试官是一个小姐姐,整个面试过程还是比较轻松的 废话不多说,直接上题目 自我介绍(巴拉巴拉巴拉...) 有参与过什么团队协作项目吗,担任了一个什么样的角色,怎么分配任务 ...
- Adoquery 简单的事务 编程 超级棒
1.记得 有一次 看 c#视频教程,发现了一个简单事务 处理的绝佳方法,就是 adoquery 其实是可以 同时执行多条 SQL 语句的, 当其中一条 SQL 语句失败了,那么其余 SQL 语句也会失 ...