单片机学习笔记---蜂鸣器播放提示音音乐(天空之城)
目录
蜂鸣器播放提示音
蜂鸣器播放音乐(天空之城)
准备工作
主程序
中断函数
上一节讲了蜂鸣器驱动原理和乐理基础知识,这一节开始代码演示!
蜂鸣器播放提示音
先创建工程:蜂鸣器播放提示音
把我们之前模块化的程序文件添加进来
但是这次我们 是要静态显示,所以要把Nixie.c文件中这里删掉
我们要实现的效果是我们按下按键之后,会出现按键提示音。
创建一个Buzzer.c和Buzzer.h文件
具体代码解释请看注释:
Buzzer.c
#include <REGX52.H>
#include <INTRINS.H>//_nop_函数的头文件//蜂鸣器端口:普中A2的板子是P2^5,其他板子的可以试试P1^5
sbit Buzzer=P2^5;//在博主以后的博客中,这个函数就作为蜂鸣器的私有延时函数
void Buzzer_Delay500us() //@12.000MHz
{unsigned char i;_nop_();//延时一微秒的函数i = 247;while (--i);
}//蜂鸣器的发声时长函数
void Buzzer_Time(unsigned int ms)
{unsigned int i;//蜂鸣器翻转的次数for(i=0;i<ms*2;i++)//一个for循环500us=0.5ms,x*0.5ms*2延时xms{Buzzer=!Buzzer;//翻转蜂鸣器//蜂鸣器的标准提示音是1000HzBuzzer_Delay500us();//每500us=0.5ms翻转一次,那蜂鸣响的周期就是1000Hz}
}
Buzzer.h
#ifndef __BUZZER_H__
#define __BUZZER_H__void Buzzer_Time(unsigned int ms);#endif
main.c
#include <REGX52.H>
#include "Delay.h"
#include "Key.h"
#include "Nixie.h"
#include "Buzzer.h"unsigned char KeyNum;void main()
{Nixie(1,0);//第一位数码管显示0while(1){KeyNum=Key();//按键按下后将键码赋值给keyNumif(KeyNum)//如果按键按下{Buzzer_Time(100);//蜂鸣器响100msNixie(1,KeyNum);//第1位数码管,显示键码}}
}
效果请看视频:
蜂鸣器播放提示音
以上就是蜂鸣器播放提示音的代码演示!
蜂鸣器播放音乐(天空之城)
接下来开始演示蜂鸣器播放音乐(天空之城)
开始之前,我们先接着上一篇解释一下这张表格(我们之后都叫它表1)
- 想要的频率在最左边,然后我们不能直接产生频率,我们只有周期,1除以频率就是周期。
- 我们需要半个周期给它翻转一次,翻转两次才是一个周期,所以翻转频率就是周期除以2,把这个频率取整就是我们的计数值(需要计这么多的数值然后就产生中断)。
- 那么它怎么计这么长呢?溢出才能产生中断对吧?我们就需要给它提前装好中间值(重装载值),在这个值开始计,计到65536溢出就产生中断了。
- 为了方便找到对应的音符,我们给这些音符弄个索引,相当于编号。
(PS:手机页面请把表格往左滑动就可看到重装载值)
表1:
音符 | 频率(Hz) | 周期(us) | 周期/2(us) | 取整 | 重装载值 | 索引 |
1 | 262 | 3816.793893 | 1908.396947 | 1908 | 63628 | 1 |
1# | 277 | 3610.108303 | 1805.054152 | 1805 | 63731 | 2 |
2 | 294 | 3401.360544 | 1700.680272 | 1701 | 63835 | 3 |
2# | 311 | 3215.434084 | 1607.717042 | 1608 | 63928 | 4 |
3 | 330 | 3030.30303 | 1515.151515 | 1515 | 64021 | 5 |
4 | 349 | 2865.329513 | 1432.664756 | 1433 | 64103 | 6 |
4# | 370 | 2702.702703 | 1351.351351 | 1351 | 64185 | 7 |
5 | 392 | 2551.020408 | 1275.510204 | 1276 | 64260 | 8 |
5# | 415 | 2409.638554 | 1204.819277 | 1205 | 64331 | 9 |
6 | 440 | 2272.727273 | 1136.363636 | 1136 | 64400 | 10 |
6# | 466 | 2145.922747 | 1072.961373 | 1073 | 64463 | 11 |
7 | 496 | 2016.129032 | 1008.064516 | 1008 | 64528 | 12 |
1 | 523 | 1912.045889 | 956.0229446 | 956 | 64580 | 13 |
1# | 554 | 1805.054152 | 902.5270758 | 903 | 64633 | 14 |
2 | 587 | 1703.577513 | 851.7887564 | 852 | 64684 | 15 |
2# | 622 | 1607.717042 | 803.8585209 | 804 | 64732 | 16 |
3 | 659 | 1517.450683 | 758.7253414 | 759 | 64777 | 17 |
4 | 698 | 1432.664756 | 716.3323782 | 716 | 64820 | 18 |
4# | 740 | 1351.351351 | 675.6756757 | 676 | 64860 | 19 |
5 | 784 | 1275.510204 | 637.755102 | 638 | 64898 | 20 |
5# | 831 | 1203.369434 | 601.6847172 | 602 | 64934 | 21 |
6 | 880 | 1136.363636 | 568.1818182 | 568 | 64968 | 22 |
6# | 932 | 1072.961373 | 536.4806867 | 536 | 65000 | 23 |
7 | 988 | 1012.145749 | 506.0728745 | 506 | 65030 | 24 |
1 | 1046 | 956.0229446 | 478.0114723 | 478 | 65058 | 25 |
1# | 1109 | 901.7132552 | 450.8566276 | 451 | 65085 | 26 |
2 | 1175 | 851.0638298 | 425.5319149 | 426 | 65110 | 27 |
2# | 1245 | 803.2128514 | 401.6064257 | 402 | 65134 | 28 |
3 | 1318 | 758.7253414 | 379.3626707 | 379 | 65157 | 29 |
4 | 1397 | 715.8196135 | 357.9098067 | 358 | 65178 | 30 |
4# | 1480 | 675.6756757 | 337.8378378 | 338 | 65198 | 31 |
5 | 1568 | 637.755102 | 318.877551 | 319 | 65217 | 32 |
5# | 1661 | 602.0469597 | 301.0234798 | 301 | 65235 | 33 |
6 | 1760 | 568.1818182 | 284.0909091 | 284 | 65252 | 34 |
6# | 1865 | 536.1930295 | 268.0965147 | 268 | 65268 | 35 |
7 | 1976 | 506.0728745 | 253.0364372 | 253 | 65283 | 36 |
接下来开始新创建一个工程:蜂鸣器播放音乐(天空之城)
把之前写好的定时器模块和Delay函数模块添加进来
接下来就对本节代码的每一个模块进行讲解,PS:讲解重点在代码的注释里。
准备工作
为了方便可以重定义端口号(如果最后整个程序写完之后蜂鸣器没有响,那么请看看自己的板子是不是普中的A2开发板,如是,则要把P1^5改成P2^5):
//蜂鸣器端口定义
sbit Buzzer=P1^5;
乐理zhonggu,一个四分音符所用时间是500ms,重定义四分音符的时间,把500ms重命名为Speed:
//播放速度,值为四分音符的时长(ms)
#define SPEED 500
然后我们把表1上的音符与索引重定义:
//音符与索引对应表,P:休止符,L:低音,M:中音,H:高音,下划线:升半音符号#
#define P 0
#define L1 1
#define L1_ 2
#define L2 3
#define L2_ 4
#define L3 5
#define L4 6
#define L4_ 7
#define L5 8
#define L5_ 9
#define L6 10
#define L6_ 11
#define L7 12
#define M1 13
#define M1_ 14
#define M2 15
#define M2_ 16
#define M3 17
#define M4 18
#define M4_ 19
#define M5 20
#define M5_ 21
#define M6 22
#define M6_ 23
#define M7 24
#define H1 25
#define H1_ 26
#define H2 27
#define H2_ 28
#define H3 29
#define H4 30
#define H4_ 31
#define H5 32
#define H5_ 33
#define H6 34
#define H6_ 35
#define H7 36
其中0在乐谱上表示休止符,表示不弹,这里是没有声音的
然后根据表1上的频率和索引弄成一个数组:
//索引与频率对照表
unsigned int FreqTable[]={0,//休止符,表示不弹63628,63731,63835,63928,64021,64103,64185,64260,64331,64400,64463,64528,64580,64633,64684,64732,64777,64820,64860,64898,64934,64968,65000,65030,65058,65085,65110,65134,65157,65178,65198,65217,65235,65252,65268,65283,
};
接下来我们就把天空之城的乐谱中的每一个音符放进一个数组中
这是《天空之城》的乐谱:
这里我们定义十六分音符为1个时长(125ms),则八分音符就是2个时长,四分音符就是4个时长(500ms),二音符就是8个时长,全音符就是16个时长。时长即下面写的时值。
//乐谱
unsigned char code Music[]={//音符,时值,//1P, 4,P, 4,P, 4,M6, 2,M7, 2,H1, 4+2,M7, 2,H1, 4,H3, 4,M7, 4+4+4,M3, 2,M3, 2,//2M6, 4+2,M5, 2,M6, 4,H1, 4,M5, 4+4+4,M3, 4,M4, 4+2,M3, 2,M4, 4,H1, 4,//3M3, 4+4,P, 2,H1, 2,H1, 2,H1, 2,M7, 4+2,M4_,2,M4_,4,M7, 4,M7, 8,P, 4,M6, 2,M7, 2,//4H1, 4+2,M7, 2,H1, 4,H3, 4,M7, 4+4+4,M3, 2,M3, 2,M6, 4+2,M5, 2,M6, 4,H1, 4,//5M5, 4+4+4,M2, 2,M3, 2,M4, 4,H1, 2,M7, 2+2,H1, 2+4,H2, 2,H2, 2,H3, 2,H1, 2+4+4,//6H1, 2,M7, 2,M6, 2,M6, 2,M7, 4,M5_,4,M6, 4+4+4,H1, 2,H2, 2,H3, 4+2,H2, 2,H3, 4,H5, 4,//7H2, 4+4+4,M5, 2,M5, 2,H1, 4+2,M7, 2,H1, 4,H3, 4,H3, 4+4+4+4,//8M6, 2,M7, 2,H1, 4,M7, 4,H2, 2,H2, 2,H1, 4+2,M5, 2+4+4,H4, 4,H3, 4,H3, 4,H1, 4,//9H3, 4+4+4,H3, 4,H6, 4+4,H5, 4,H5, 4,H3, 2,H2, 2,H1, 4+4,P, 2,H1, 2,//10H2, 4,H1, 2,H2, 2,H2, 4,H5, 4,H3, 4+4+4,H3, 4,H6, 4+4,H5, 4+4,//11H3, 2,H2, 2,H1, 4+4,P, 2,H1, 2,H2, 4,H1, 2,H2, 2+4,M7, 4,M6, 4+4+4,P, 4,0xFF //终止标志,防止数组越界之后乱音,用一个最大值来做一个终止标志,也可以设别的值
};
定义两个变量
//FreSelect就是FreqTable[]中的元素的下标,
//MusicSelect就是Music[]中的元素下标unsigned char FreqSelect,MusicSelect;
主程序
void main()
{Timer0Init();//定时器初始化,1ms后溢出调到中断函数中执行中断//之后每次中断函数执行完之后返回主程序中进入while循环while(1){if(Music[MusicSelect]!=0xFF) //如果不是停止标志位{FreqSelect=Music[MusicSelect]; //选择音符对应的频率//选择好Music[]里的音符(索引/编号的重定义)之后赋值给FreqTable[]的下标FreqSelect,//然后在中断函数里就把FreqSelect这个下标对应的重装载值赋值给TL0和TH0,//也就是让它产生对应的频率即可发出对应的音符MusicSelect++;//Music[]的下标+1就是该音符的时长的下标Delay(SPEED/4*Music[MusicSelect]); //选择音符对应的时值//SPEED是500ms//SPEED/4=一个十六分音符的时间125ms//125ms*Music[MusicSelect]=125ms*时值=某个音符的时长MusicSelect++;//Music[]的下标+1就是下一个音符的下标//为了停顿后进入下一次while循环的MusicSelect的初值TR0=0;//关闭定时器Delay(5); //音符间短暂停顿TR0=1;//开启定时器}else //如果是停止标志位0xFF{TR0=0;//关闭定时器while(1);//程序就一直停在这里了}}
}
中断函数
//如果不是休止符,定时器初始化后第一次进来时是FreqTable[0]=0,没有出声,
//第二次进来中断函数才真正开始选(重装载值)
void Timer0_Routine() interrupt 1 //中断函数每1ms进来一次
{if(FreqTable[FreqSelect]) {/*取对应频率值的重装载值到定时器*/TL0 = FreqTable[FreqSelect]%256; //设置定时初值TH0 = FreqTable[FreqSelect]/256; //设置定时初值Buzzer=!Buzzer; //翻转蜂鸣器IO口}
}
效果请看视频:
蜂鸣器播放音乐
蜂鸣器播放音乐部分完成!
本节的源码放在评论区了,自取!
如有问题,可评论区留言!
相关文章:

单片机学习笔记---蜂鸣器播放提示音音乐(天空之城)
目录 蜂鸣器播放提示音 蜂鸣器播放音乐(天空之城) 准备工作 主程序 中断函数 上一节讲了蜂鸣器驱动原理和乐理基础知识,这一节开始代码演示! 蜂鸣器播放提示音 先创建工程:蜂鸣器播放提示音 把我们之前模块化的…...

软件实例分享,茶楼收银软件管理系统,支持计时计费商品销售会员管理定时语音提醒功能
软件实例分享,茶楼收银软件管理系统,支持计时计费商品销售会员管理定时语音提醒功能 一、前言 以下软件教程以 佳易王茶社计时计费管理系统软件V18.0为例说明 软件文件下载可以点击最下方官网卡片——软件下载——试用版软件下载 问:这个软…...

clang前端
Clang可以处理C、C和Objective-C源代码 Clang简介 Clang可能指三种不同的实体: 前端(在Clang库中实现)编译驱动程序(在clang命令和Clang驱动程序库中实现)实际的编译器(在clang-ccl命令中实现࿰…...

ARM:AI 的翅膀,还能飞多久?
ARM(ARM.O)于北京时间 2024 年 2 月 8 日上午的美股盘后发布了 2024 年第三财年报告(截止 2023 年 12 月),要点如下: 1、整体业绩:收入再创新高。ARM 在 2024 财年第三季度(即 23Q4…...

【C语言】常见字符串函数的功能与模拟实现
目录 1.strlen() 模拟实现strlen() 2.strcpy() 模拟实现strcpy() 3.strcat() 模拟实现strcat() 4.strcmp() 模拟实现strcmp() 5.strncpy() 模拟实现strncpy() 6.strncat() 模拟实现strncat() 7.strncmp() 模拟实现strncmp() 8.strstr() 模拟实现strstr() 9.str…...

pyGMT初步使用
文章目录 安装显示地图保存地图 安装 GMT,即Generic Mapping Tools,通用制图工具,是GIS领域应用最广泛的制图软件之一,用于绘制地图、图形以及进行地球科学数据分析和可视化。而pyGMT即其为python提供的函数接口,故而…...
神经网络 | CNN 与 RNN——深度学习主力军
Hi,大家好,我是半亩花海。本文主要将卷积神经网络(CNN)和循环神经网络(RNN)这两个深度学习主力军进行对比。我们知道,从应用方面上来看,CNN 用于图像识别较多,而 RNN 用于…...

thinkphp6入门(20)-- 如何上传图片、文件
1. 配置文件 设置上传的路径 对应文件夹 2. 前端 <div class"card-body"><h1 class"card-title">用户头像</h1><img src"../../../uploads/{$user.avatar_photo_path}" alt"avatar" height"100"/&g…...

【Linux技术宝典】深入理解Linux基本指令:命令行新手指南
📷 江池俊: 个人主页 🔥个人专栏: ✅数据结构冒险记 ✅Linux技术宝典 🌅 有航道的人,再渺小也不会迷途。 文章目录 一、Linux下基本指令1. ls 指令2. pwd指令3. clear指令4. cd指令什么是家目录…...

C++:Level1阶段测试
总结。 只要你看过我的文章,哪怕只是一半,一定能够过关! 准备好开始测试氻吗? 选择题,每题4分,共40分 1、 DevC的项目创建按钮是_____ A、文件[F]” → “新建[N]” → “项目[P]... B、工具[T]” → …...
autojs自动化刷视频脚本
视频展示 视频 //悬浮窗 // var window floaty.rawWindow( // <frame gravity"center" bg"#ff00ff"> // <button id"action" w"300dp" h"300dp"> // 按钮 // </button> // </fram…...

鲁南制药“健康幸福中国年”主题航班,开启探寻健康与幸福的旅程
“小年,小年,过了今天就是年。”提到过年,北方人的“过年”是从腊月二十三的“小年”开始的,而南方地区是在明天。虽然时间不同,但是浓浓的年味是一样的,红彤彤是主色调,喜洋洋是主乐曲…...

CISA知识点
审计流程21%;运营和业务恢复23%;保护资产27%;IT治理17%;开发12%。 领域1-信息系统审计流程 规划-现场工作-报告 (1)审计规划 了解业务使命、目标、目的和流程 找到相关规定 实施风险分析(…...

C语言求解猴子分桃子
问题:海滩上有一堆桃子,五只猴子来分。第一只猴子把这堆桃子平均分为五份,多了一个,这只 猴子把多的一个扔入海中,拿走了一份。第二只猴子把剩下的桃子又平均分成五份,又多了 一个,它同样把多的…...

本地部署 Stable Cascade
本地部署 Stable Cascade 0. 引言1. 事前准备2. 本地部署 Stable Cascade3. 使用 Stable Cascade 生成图片4. Stable Cascade Github 地址 0. 引言 Stable Cascade 模型建立在 Wrstchen 架构之上,它与 Stable Diffusion 等其他模型的主要区别在于它的工作潜在空间要…...
LeetCode 二叉树/n叉树的解题思路
二叉树 二叉树特点是每个节点最多只能有两棵子树,且有左右之分二叉树的数据结构如下: public class TreeNode {//节点的值int val;//左子树TreeNode left;//右子树TreeNode right;TreeNode(int x) { val x; } }树节点的初始化: int val1;T…...

opencv mat用法赋值克隆的操作和一些基本属性
//Mat基本结构 (头部 数据部分) //赋值的话 就是修改了指针位置 但还是指向了原来数据 并没创建数据 本质上并没有变 //只有克隆或者拷贝时 它才会真正复制一份数据 //代码实现 //创建方法 - 克隆 //Mat m1 src.clone(); //复制 //Mat m2; //src.copyTo(m2); //赋值法 …...

【使用IDEA总结】01——新增作者信息、方法参数返回值
[TOC](目录) 1.类新增作者信息 打开IDEA的Settings,Editor->Code Style->File and Code Templates->Includes->File Header,输入以下作者信息,作者名更换为自己的即可,操作如下图所示 /*** Author Linhaipeng* Date…...

ElasticSearch分词器和相关性详解
目录 ES分词器详解 基本概念 分词发生时期 分词器的组成 切词器:Tokenizer 词项过滤器:Token Filter 停用词 同义词 字符过滤器:Character Filter HTML 标签过滤器:HTML Strip Character Filter 字符映射过滤器&#x…...

DolphinScheduler安装与配置
DolphinScheduler概述 Apache DolphinScheduler是一个分布式、易扩展的可视化DAG工作流任务调度平台。致力于解决数据处理流程中错综复杂的依赖关系,使调度系统在数据处理流程中开箱即用。 DolphinScheduler的主要角色如下: MasterServer采用分布式无…...

循环冗余码校验CRC码 算法步骤+详细实例计算
通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)࿰…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...

高危文件识别的常用算法:原理、应用与企业场景
高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...

ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...

技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...