无源蜂鸣器与播放音乐(总结)
原作者链接:http://blog.sina.com.cn/s/blog_bf63e2650102wibs.html
如若侵犯原作者,请及时联系本人,本人立刻删除
单片机产生音乐的原理:
音乐的产生主要是通过单片机的I/O口输出高低不同的脉冲信号来控制蜂鸣器发音,要想产生音频脉冲信号,需要算出某音频的周期(1/频率),然后将此周期除以2,即为半周期的时间。利用单片机定时器计时这个半周期的时间,每当计时到后就输出脉冲的I/O口反相,这样就在此I/O口上得到此脉冲的频率。
通常,利用单片机的内部定时器0,工作在方式一下,改变计数初始值TH0和TL0来产生不同的率。
例如,若单片机采用12MHzs晶振,要产生频率为587Hzs的音频脉冲时,其音频信号的脉冲周期T=1/587=1703.5775us,半周期时间为852us,因此总要令计时器计数=852us/1us=852,在每计数852时将I/O口反相,就得到C大调的中调Re。
由于定时器0的在方式一计数方式为16位计数器,最多只能装载的数为2的16次方即65536个,也就是说定时器计数到65536就会进入中断函数,而在中断函数中将输出脉冲的I/O口反相即可,故只需设置好定时器0的初值就可以了发出特定的音频了。初值与音频的对应关系见下表所示:
音频 |
定时器初值 |
低1do |
63628 |
低2re |
63835 |
低3mi |
64021 |
低4fa |
64103 |
低5so |
64260 |
低6la |
64400 |
低7si |
64524 |
中1do |
64580 |
中2re |
64684 |
中3mi |
64777 |
中4fa |
64820 |
中5so |
64898 |
中6la |
64968 |
中7si |
65030 |
高1do |
65058 |
高2re |
65110 |
高3mi |
65157 |
高4fa |
65160 |
高5so |
65217 |
高6la |
65252 |
高7si |
65282 |
#include"STC12C5A.h"
int tab[]={64580,64684,64777,64820,64898,64968,65030,65058,65110,65157,65178,65217,65252,65282}; //网上找到的音符与定时器初值对照表中的数据,用来设定时器0初值
sbit bell=P1^3;//位定义蜂鸣器
int i; //用于赋定时器0初值
void delay_ms(unsigned int time)
{
unsigned int t;
for(;time>0;time--)
{
t=1500;
while(t--);
}
}
void Timer0_init()
{
TMOD=0x01;//选择定时器0方式1
ET0=1; //开启定时器0中断
EA=1;
TR0=1;
TL0=tab;
TH0=tab>>8;
}
void Timer0_Isp() interrupt 1
{
TL0=tab;
TH0=tab>>8;
bell=!bell;
}
//放音符的数组前面记得加个code,延迟时间凭乐感吧!要关掉蜂鸣器貌似蜂鸣器跟定时器都要关哦,歌曲暂停与播放,强烈推荐用外部中断!
void main()
{
int s;
code int song[]={6,5,6,8,9,10,7,6,5,3,5,9,8};
code int song1[]={2,3,5,6,5,3,2,1} ;
code song2[]={10,9,8,5,9,3,5,9,5};
code int song3[]={8,9,10,12,13,10,9};
code int song4[]={9,8,9,10,12,10};
for(s=0;s<13;s++)
{
i=song-1;
Timer0_init();
Timer0_init();
delay_ms(450);
}
delay_ms(500);
for(s=0;s<8;s++)
{
i=song1-1;
Timer0_init();
Timer0_init();
delay_ms(450);
}
delay_ms(700);
for(s=1;s<3;s++)
{
i=4;
Timer0_init();
Timer0_init();
delay_ms(450);
i=5;
Timer0_init();
Timer0_init();
delay_ms(450);
i=9;
Timer0_init();
Timer0_init();
delay_ms(700);
}
i=7;
Timer0_init();
Timer0_init();
delay_ms(450);
i=8;
Timer0_init();
Timer0_init();
delay_ms(1000);
for(s=0;s<9;s++)
{
i=song2-1;
Timer0_init();
Timer0_init();
delay_ms(450);
}
delay_ms(100);
i=7;
Timer0_init();
Timer0_init();
delay_ms(1000);
for(s=0;s<7;s++)
{
i=song3-1;
Timer0_init();
Timer0_init();
delay_ms(450);
}
delay_ms(1000);
for(s=0;s<6;s++)
{
i=song4-1;
Timer0_init();
Timer0_init();
delay_ms(450);
}
delay_ms(1000);
}
如果我们能够控制好频率和节拍,那就有可能演奏出动听的音乐。因此,我们首先需要搞清楚各音调的频率,具体见下表(分别为低音、中音和高音):
这里我们具体以《欢乐颂》为例:
第一,普通音符。如第一个音符3,对应频率350,占1拍。
第二,带下划线音符,表示0.5拍;两个下划线是四分之一拍(0.25)。
第三,有的音符后带一个点,表示多加0.5拍,即1+0.5。
第四,有的音符后带一个“—”,表示多加1拍,即1+1。
第五,有的两个连续的音符上面带弧线,表示连音,可以稍微改下连音后面那个音的频率,比如减少或增加一些数值(需自己调试),这样表现会更流畅,其实不做处理,影响也不大。
1. #define NTD0 -1
2. #define NTD1 294
3. #define NTD2 330
4. #define NTD3 350
5. #define NTD4 393
6. #define NTD5 441
7. #define NTD6 495
8. #define NTD7 556
9.
10. #define NTDL1 147
11. #define NTDL2 165
12. #define NTDL3 175
13. #define NTDL4 196
14. #define NTDL5 221
15. #define NTDL6 248
16. #define NTDL7 278
17.
18. #define NTDH1 589
19. #define NTDH2 661
20. #define NTDH3 700
21. #define NTDH4 786
22. #define NTDH5 882
23. #define NTDH6 990
24. #define NTDH7 112
25. //列出全部D调的频率
26.
27. #define WHOLE 1
28. #define HALF 0.5
29. #define QUARTER 0.25
30. #define EIGHTH 0.125
31. #define SIXTEENTH 0.625
32. //列出所有节拍
33. int tune[]= //根据简谱列出各频率
34. {
35. NTD3,NTD3,NTD4,NTD5,
36. NTD5,NTD4,NTD3,NTD2,
37. NTD1,NTD1,NTD2,NTD3,
38. NTD3,NTD2,NTD2,
39. NTD3,NTD3,NTD4,NTD5,
40. NTD5,NTD4,NTD3,NTD2,
41. NTD1,NTD1,NTD2,NTD3,
42. NTD2,NTD1,NTD1,
43. NTD2,NTD2,NTD3,NTD1,
44. NTD2,NTD3,NTD4,NTD3,NTD1,
45. NTD2,NTD3,NTD4,NTD3,NTD2,
46. NTD1,NTD2,NTDL5,NTD0,
47. NTD3,NTD3,NTD4,NTD5,
48. NTD5,NTD4,NTD3,NTD4,NTD2,
49. NTD1,NTD1,NTD2,NTD3,
50. NTD2,NTD1,NTD1
51. };
52. float durt[]= //根据简谱列出各节拍
53. {
54. 1,1,1,1,
55. 1,1,1,1,
56. 1,1,1,1,
57. 1+0.5,0.5,1+1,
58. 1,1,1,1,
59. 1,1,1,1,
60. 1,1,1,1,
61. 1+0.5,0.5,1+1,
62. 1,1,1,1,
63. 1,0.5,0.5,1,1,
64. 1,0.5,0.5,1,1,
65. 1,1,1,1,
66. 1,1,1,1,
67. 1,1,1,0.5,0.5,
68. 1,1,1,1,
69. 1+0.5,0.5,1+1,
70. };
71. int length;
72. int tonepin=6; //得用6号接口
73. void setup()
74. {
75. pinMode(tonepin,OUTPUT);
76. length=sizeof(tune)/sizeof(tune[0]); //计算长度
77. }
78. void loop()
79. {
80. for(int x=0;x)
81. {
82. tone(tonepin,tune[x]);
83. delay(500*durt[x]); //这里用来根据节拍调节延时,500这个指数可以自己调整,在该音乐中,我发现用500比较合适。
84. noTone(tonepin);
85. }
86. delay(2000);
87. }
无源蜂鸣器与播放音乐(总结)相关推荐
- arduino无源蜂鸣器歌曲编码_Arduino加无源蜂鸣器,播放音乐《葫芦娃》
Arduino加无源蜂鸣器,播放音乐<葫芦娃> #define NOTE_D0 -1 #define NOTE_D1 294 #define NOTE_D2 330 #define NOT ...
- STM32 使用STM32F103控制无源蜂鸣器发声播放音乐
使用STM32控制无源蜂鸣器发声播放音乐 [注:学习STM32总结做的笔记,大神勿喷.有不足之处还望不吝赐教. -----本篇大部分转载而来,有侵权请联系作者,谢谢.] 原博客地址: https:// ...
- stm32无源蜂鸣器定时器_使用STM32控制无源蜂鸣器发声播放音乐
[实例简介] 利用GPIO控制无源蜂鸣器发声,播放音乐.使用SysTick延时,使用位带操作寻址IO口引脚. [实例截图] [核心代码] pMusic ├── CMSIS │ ├── core_c ...
- Arduino红外遥控无源蜂鸣器播放音乐
Arduino红外遥控无源蜂鸣器播放音乐/模拟电子琴 简介 关于频谱 实验材料 接线 实验代码 模拟电子琴 接线 代码 总结 原文链接:https://www.yourcee.com/newsinfo ...
- 51单片机播放音乐(一):蜂鸣器
51单片机播放音乐(一):蜂鸣器 原理 蜂鸣器 乐谱转成循环次数 单片机代码 仿真电路图 本文完整源码 原理 蜂鸣器 蜂鸣器分为有(震动)源的和无源的,有源的无法控制频率,所以用无源的才能播放音乐.无 ...
- 51单片机(二十七)—— 蜂鸣器播放音乐
1.实验原理介绍 蜂鸣器是电路中经常使用的发声器件,我们一般使用蜂鸣器发出"嘀嘀"的声音,用它作为提示音.有没有想过用蜂鸣器还可以播放音乐呢?这显然是件很有意思的事情. 本文使用蜂 ...
- 用龙芯1c库实现无源蜂鸣器唱歌《送别》
龙芯1c库是把龙芯1c的常用外设的常用功能封装为一个库,可用于裸机编程和实时系统,类似于STM32库.Git地址:http://git.oschina.NET/caogos/OpenLoongsonL ...
- 用Arduino播放音乐
温馨提示 学校开设了Arduino的课程,老师也发了一整套的学习设备,于是心血来潮结合了以前用c语言beep函数制作音乐播放器的经验,制作了一个十分简单的Arduino版本的音乐播放器.本人菜鸟一个, ...
- Arduino Uno 送你一首葫芦娃 无源蜂鸣器实验
本次实验使用的是无源蜂鸣器,播放一首葫芦娃 无源指的是不包含振荡源, 相对于有源蜂鸣器,就是包含振荡源. 无源需要2k-5k的方波来驱动发声,所以音色多变. 有源则通电就能蜂鸣,发音频率固定,音色单一 ...
最新文章
- CocoStudio 0.2.4.0 UI编辑器下根Panel控件设置背景图片时一个BUG
- python中单个下划线是什么意思
- 素数与量子物理的结合能带来解决黎曼猜想的新可能吗?
- anaconda切换盘符以及手动安装包
- 【Java网络编程(一)】IP地址、端口、URL、网络爬虫原理、TCP UDP协议
- Swagger扩展为你添油加气
- hdu2544 最短路-Floyd算法
- OD使用教程7(上)- 调试篇07|解密系列
- android 控件监听方法是,Android | Android中监听Button的实现
- androidstudio4.1.1 build model卡主_在C++中加载PyTorch1.4的FasterRCNN模型
- 共享软件加密的一些误区
- X5内核视频之问答汇总
- java web 邮件_Java Web(十二) JavaMail发送邮件
- 使用NLPIR汉语分词系统进行分词
- 电脑开机后网络一直转圈,程序也打不开——亲测解决办法
- EMUI/MIUI卸载系统预装软件,开启上帝模式无需ROOT权限
- 关于word文档受保护的问题,不能编辑,转成能编辑的文档
- 基于matlab在信号与系统仿真中的应用,基于MATLAB在信号与系统仿真中的应用
- 视觉SLAM十四讲 报错 Could not find a configuration file for package “OpenCV“ that is compatible with reques
- 51开发板上为什么会有多个晶振
热门文章
- MySQL数据库-学习笔记
- 223. 矩形面积(矩形面积并简单版)
- 学习ASP.NET的步骤
- 为什么下搜酷狗输入法那么快?
- 2023最新Android 车载系统开发教程,车载开发入门
- 水泵smart200编程_S7-200 SMART控制液压系统,实现了S7-200 SMART与S7-1200的通讯
- 争夺存量用户关键战,助力企业构建完美标签体系丨01期直播回顾
- android异步任务载入数据界面实现
- 91手机助手电脑版 v5.6.5.1376 官方版
- 超级课程表显示服务器出错怎么办,超级课程表导入失败怎么办 超级课程表导入不了解决方法...