单片机学习笔记---蜂鸣器播放提示音音乐(天空之城)

目录

蜂鸣器播放提示音

蜂鸣器播放音乐(天空之城)

准备工作

主程序

中断函数


上一节讲了蜂鸣器驱动原理和乐理基础知识,这一节开始代码演示!

蜂鸣器播放提示音

先创建工程:蜂鸣器播放提示音

把我们之前模块化的程序文件添加进来

但是这次我们 是要静态显示,所以要把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. 想要的频率在最左边,然后我们不能直接产生频率,我们只有周期,1除以频率就是周期。
  2. 我们需要半个周期给它翻转一次,翻转两次才是一个周期,所以翻转频率就是周期除以2,把这个频率取整就是我们的计数值(需要计这么多的数值然后就产生中断)。
  3. 那么它怎么计这么长呢?溢出才能产生中断对吧?我们就需要给它提前装好中间值(重装载值),在这个值开始计,计到65536溢出就产生中断了。
  4. 为了方便找到对应的音符,我们给这些音符弄个索引,相当于编号。

(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口}
}

效果请看视频:

蜂鸣器播放音乐

蜂鸣器播放音乐部分完成!

本节的源码放在评论区了,自取!

如有问题,可评论区留言!

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

python学习23

前言&#xff1a;相信看到这篇文章的小伙伴都或多或少有一些编程基础&#xff0c;懂得一些linux的基本命令了吧&#xff0c;本篇文章将带领大家服务器如何部署一个使用django框架开发的一个网站进行云服务器端的部署。 文章使用到的的工具 Python&#xff1a;一种编程语言&…

计算机网络基础 第二章——物理层 知识点

2.1物理层和物理层协议的基本概念 1.物理层的基本服务功能和设置物理层的目的。 ●物理层考虑的是怎样才能在连接各种计算机的传输媒体上 传输数据比特流&#xff0c;而不是指具体的传输媒体。 ●物理层的主要任务是:保证比特流通过传输介质的正确传 输&#xff0c;为数据链…

蓝桥杯2023年真题(1)

1.分糖果 #include <iostream> using namespace std; int a 9, b 16, c 7, d 2, e 5; int ans 0; //u是当前第几个分糖果的小朋友&#xff0c;x和y是还剩的糖果 void dfs(int u, int x, int y){if(u > c){//如果都为0&#xff0c;就是已经分完了if(!x &&…

一个小而实用的 Python 包 pangu,实现在中文和半宽字符(字母、数字和符号)之间自动插入空格

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 一个小巧的库&#xff0c;可以避免自己重新开发功能。利用 Python 包 pangu&#xff0c;可以轻松实现在 CJK&#xff08;中文、日文、韩文&#xff09;和半宽字符&#xff08;字母、数字和符号&#xf…

【开源】SpringBoot框架开发个人健康管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 健康档案模块2.2 体检档案模块2.3 健康咨询模块 三、系统展示四、核心代码4.1 查询健康档案4.2 新增健康档案4.3 查询体检档案4.4 新增体检档案4.5 新增健康咨询 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpri…

RestFul的认识

前言 RESTful 是 Representational State Transfer 的缩写&#xff0c;是一种软件架构风格&#xff0c;用于在网络上构建和整合应用程序。它基于 HTTP 协议&#xff0c;并定义了一组约束和规范&#xff0c;用于规范客户端和服务器之间的通信。 RESTful API 是遵循 REST 架构规…

Java实现河南软件客服系统 JAVA+Vue+SpringBoot+MySQL

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统管理人员2.2 业务操作人员 三、系统展示四、核心代码4.1 查询客户4.2 新增客户跟进情况4.3 查询客户历史4.4 新增服务派单4.5 新增客户服务费 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的河…

JavaScript 遍历文档生成目录结构

JavaScript 遍历文档生成目录结构 要遍历 HTML 文档并生成目录结构&#xff0c;你可以使用 JavaScript 来进行 DOM 操作和遍历。以下是一个简单的示例代码&#xff0c;演示了如何遍历文档中的标题元素&#xff08;例如 <h1>、<h2>、<h3> 等&#xff09;&…

ChatGPT高效提问—prompt常见用法(续篇十二)

ChatGPT高效提问—prompt常见用法&#xff08;续篇十二&#xff09; 1.1 prompt生成器 ​ 假如想让ChatGPT完成一个相对复杂的任务&#xff0c;但是没想好从哪个方面入手&#xff0c;需求不明确&#xff0c;或者对任务涉及的专业知识不够了解&#xff0c;不能写出专业、准确的…

C#使用重载方法实现不同类型数据的计算

目录 一、涉及到的相关知识 1.重载的方法 2.Convert.ToInt32(String)方法 3.判断字符串是否带有小数点 二、实例 1.示例 2.生成成果 一、涉及到的相关知识 1.重载的方法 重载方法就是方法名称相同&#xff0c;但是每个方法中参数的数据类型、个数或顺序不同的方法。如果…

2024年湖南省考报名时间及流程,选岗很重要!

注册时间&#xff1a;2024年2月18日9:00-25日17:00 报名时间&#xff1a;2024年2月19日9:00-25日17:00 网上确认时间&#xff1a;2024年2月28日9:00-3月2日24:00 缴费时间&#xff1a;2024年2月28日9:00-3月2日24:00 打印准考证时间&#xff1a;2024年3月11日9:00-15日17:00 考…

Python 中的互斥锁:保护共享资源的利器

Python 作为一门流行的编程语言&#xff0c;广泛应用于各种领域&#xff0c;特别是在多线程编程中。多线程编程可以让程序同时执行多个任务&#xff0c;但也会引发一些问题&#xff0c;比如多个线程同时访问共享资源可能导致数据错误或不一致。为了解决这个问题&#xff0c;Pyt…

2016-2022年哨兵影像的在线底图

有一个欧洲初创公司对哨兵影像进行了去云处理&#xff0c;制作了一个2016年-2022年的全球哨兵底图。目前底图通过wmts发布&#xff0c;可免费使用&#xff0c;无需搭梯子。 该数据的特点是&#xff1a; 很少的云覆盖&#xff0c;较少的条纹&#xff0c;色彩平衡 底图切片的网…

酷开科技荣获“消费者服务之星”称号后的未来展望

恭喜酷开科技荣获2023年第四季度黑猫平台“消费者服务之星”称号&#xff01;这是对酷开科技长期以来坚持用户至上、用心服务的肯定和认可。作为OTT行业的佼佼者&#xff0c;酷开科技一直秉承着“以用户为中心”的服务理念&#xff0c;不断追求卓越品质&#xff0c;为用户提供更…

Jumpserver教程01:部署jumpserver

Jumpserver教程 注&#xff1a; 本教程由羞涩梦整理同步发布&#xff0c;本人技术分享站点&#xff1a;blog.hukanfa.com 转发本文请备注原文链接&#xff0c;本文内容整理日期&#xff1a;2024-02-11 csdn 博客名称&#xff1a;五维空间-影子&#xff0c;欢迎关注 简要说明…

【EAI 019】Eureka: Human-Level Reward Design via Coding LLM

论文标题&#xff1a;Eureka: Human-Level Reward Design via Coding Large Language Models 论文作者&#xff1a;Yecheng Jason Ma, William Liang, Guanzhi Wang, De-An Huang, Osbert Bastani, Dinesh Jayaraman, Yuke Zhu, Linxi Fan, Anima Anandkumar 作者单位&#xff…

视频直播系统架构的设计与实现

视频直播系统作为一种实时性强、用户互动性高的应用&#xff0c;其架构设计至关重要。本文将介绍如何设计和实现一个稳定、高性能的直播系统架构&#xff0c;以提供良好的用户体验和可靠的服务。 1. 系统架构概述 - 介绍视频直播系统的整体架构&#xff0c;包括客户端、服务…

【java】12:封装

面向对象编程三大特征 1.基本介绍 面向对象编程有三大特征&#xff1a;封装、继承和多态。 2.封装介绍 封装(encapsulation)就是把抽象出的数据[属性]和对数据的操作[方法]封装在一起&#xff0c;数据被保护在内部&#xff0c;程序的其它部分只有通过被授权的操作[方法]&am…

MySQL-----DCL基础操作

▶ DCL简介 DCL英文全称是Data ControlLanguage(数据控制语言)&#xff0c;用来管理数据库用户、控制数据库的访问权限。 DCL--管理用户 ▶ 查询用户 use mysql; select * from user; ▶ 创建用户 ▶ 语法 create user 用户名主机名 identified by 密码 设置为在任意主机上访问…

数据库管理-第149期 Oracle Vector DB AI-01(20240210)

数据库管理149期 2024-02-10 数据库管理-第149期 Oracle Vector DB & AI-01&#xff08;20240210&#xff09;1 机器学习2 向量3 向量嵌入4 向量检索5 向量数据库5 专用向量数据库的问题总结 数据库管理-第149期 Oracle Vector DB & AI-01&#xff08;20240210&#xf…