原作者链接: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);

}

如果我们能够控制好频率和节拍,那就有可能演奏出动听的音乐。因此,我们首先需要搞清楚各音调的频率,具体见下表(分别为低音、中音和高音):

我们知道了音调的频率后,下一步就是控制音符的演奏时间。每个音符都会播放一定的时间,这样才能构成一首优美的曲子,而不是生硬的一个调的把所有的音符一股脑的都播放出来。音符节奏分为一拍、半拍、1/4拍、1/8拍,我们规定一拍音符的时间为1;半拍为0.5;1/4拍为0.25;1/8拍为0.125……,所以我们可以为每个音符赋予这样的拍子播放出来,音乐就成了。

这里我们具体以《欢乐颂》为例:

从简谱看,该音乐是D调的,这里的各音符对应的频率对应的是上表中D调的部分。另外,该音乐为四分之四拍,每个对应为1拍。(我们知道,音符节奏分为一拍、半拍、1/4拍、1/8拍,我们规定一拍音符的时间为1;半拍为0.5;1/4拍为0.25;1/8拍为0.125……,)几个特殊音符说明如下:

第一,普通音符。如第一个音符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. }

无源蜂鸣器与播放音乐(总结)相关推荐

  1. arduino无源蜂鸣器歌曲编码_Arduino加无源蜂鸣器,播放音乐《葫芦娃》

    Arduino加无源蜂鸣器,播放音乐<葫芦娃> #define NOTE_D0 -1 #define NOTE_D1 294 #define NOTE_D2 330 #define NOT ...

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

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

  3. stm32无源蜂鸣器定时器_使用STM32控制无源蜂鸣器发声播放音乐

    [实例简介] 利用GPIO控制无源蜂鸣器发声,播放音乐.使用SysTick延时,使用位带操作寻址IO口引脚. [实例截图] [核心代码] pMusic ├── CMSIS │   ├── core_c ...

  4. Arduino红外遥控无源蜂鸣器播放音乐

    Arduino红外遥控无源蜂鸣器播放音乐/模拟电子琴 简介 关于频谱 实验材料 接线 实验代码 模拟电子琴 接线 代码 总结 原文链接:https://www.yourcee.com/newsinfo ...

  5. 51单片机播放音乐(一):蜂鸣器

    51单片机播放音乐(一):蜂鸣器 原理 蜂鸣器 乐谱转成循环次数 单片机代码 仿真电路图 本文完整源码 原理 蜂鸣器 蜂鸣器分为有(震动)源的和无源的,有源的无法控制频率,所以用无源的才能播放音乐.无 ...

  6. 51单片机(二十七)—— 蜂鸣器播放音乐

    1.实验原理介绍 蜂鸣器是电路中经常使用的发声器件,我们一般使用蜂鸣器发出"嘀嘀"的声音,用它作为提示音.有没有想过用蜂鸣器还可以播放音乐呢?这显然是件很有意思的事情. 本文使用蜂 ...

  7. 用龙芯1c库实现无源蜂鸣器唱歌《送别》

    龙芯1c库是把龙芯1c的常用外设的常用功能封装为一个库,可用于裸机编程和实时系统,类似于STM32库.Git地址:http://git.oschina.NET/caogos/OpenLoongsonL ...

  8. 用Arduino播放音乐

    温馨提示 学校开设了Arduino的课程,老师也发了一整套的学习设备,于是心血来潮结合了以前用c语言beep函数制作音乐播放器的经验,制作了一个十分简单的Arduino版本的音乐播放器.本人菜鸟一个, ...

  9. Arduino Uno 送你一首葫芦娃 无源蜂鸣器实验

    本次实验使用的是无源蜂鸣器,播放一首葫芦娃 无源指的是不包含振荡源, 相对于有源蜂鸣器,就是包含振荡源. 无源需要2k-5k的方波来驱动发声,所以音色多变. 有源则通电就能蜂鸣,发音频率固定,音色单一 ...

最新文章

  1. CocoStudio 0.2.4.0 UI编辑器下根Panel控件设置背景图片时一个BUG
  2. python中单个下划线是什么意思
  3. 素数与量子物理的结合能带来解决黎曼猜想的新可能吗?
  4. anaconda切换盘符以及手动安装包
  5. 【Java网络编程(一)】IP地址、端口、URL、网络爬虫原理、TCP UDP协议
  6. Swagger扩展为你添油加气
  7. hdu2544 最短路-Floyd算法
  8. OD使用教程7(上)- 调试篇07|解密系列
  9. android 控件监听方法是,Android | Android中监听Button的实现
  10. androidstudio4.1.1 build model卡主_在C++中加载PyTorch1.4的FasterRCNN模型
  11. 共享软件加密的一些误区
  12. X5内核视频之问答汇总
  13. java web 邮件_Java Web(十二) JavaMail发送邮件
  14. 使用NLPIR汉语分词系统进行分词
  15. 电脑开机后网络一直转圈,程序也打不开——亲测解决办法
  16. EMUI/MIUI卸载系统预装软件,开启上帝模式无需ROOT权限
  17. 关于word文档受保护的问题,不能编辑,转成能编辑的文档
  18. 基于matlab在信号与系统仿真中的应用,基于MATLAB在信号与系统仿真中的应用
  19. 视觉SLAM十四讲 报错 Could not find a configuration file for package “OpenCV“ that is compatible with reques
  20. 51开发板上为什么会有多个晶振

热门文章

  1. MySQL数据库-学习笔记
  2. 223. 矩形面积(矩形面积并简单版)
  3. 学习ASP.NET的步骤
  4. 为什么下搜酷狗输入法那么快?
  5. 2023最新Android 车载系统开发教程,车载开发入门
  6. 水泵smart200编程_S7-200 SMART控制液压系统,实现了S7-200 SMART与S7-1200的通讯
  7. 争夺存量用户关键战,助力企业构建完美标签体系丨01期直播回顾
  8. android异步任务载入数据界面实现
  9. 91手机助手电脑版 v5.6.5.1376 官方版
  10. 超级课程表显示服务器出错怎么办,超级课程表导入失败怎么办 超级课程表导入不了解决方法...