无源蜂鸣器与播放音乐(总结)

原作者链接:http://blog.sina.com.cn/s/blog_bf63e2650102wibs.html

如若侵犯原作者,请及时联系本人,本人立刻删除


单片机产生音乐的原理:
       
音乐的产生主要是通过单片机的I/O口输出高低不同的脉冲信号来控制蜂鸣器发音,要想产生音频脉冲信号,需要算出某音频的周期(1/频率),然后将此周期除以2,即为半周期的时间。利用单片机定时器计时这个半周期的时间,每当计时到后就输出脉冲的I/O口反相,这样就在此I/O口上得到此脉冲的频率。

通常,利用单片机的内部定时器0,工作在方式一下,改变计数初始值TH0TL0来产生不同的率。

 例如,若单片机采用12MHzs晶振,要产生频率为587Hzs的音频脉冲时,其音频信号的脉冲周期T=1/587=1703.5775us,半周期时间为852us,因此总要令计时器计数=852us/1us=852,在每计数852时将I/O口反相,就得到C大调的中调Re

 由于定时器0的在方式一计数方式为16位计数器,最多只能装载的数为216次方即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: STM32无源蜂鸣器是一种低成本的音频装置,它可以通过振动产生声音。虽然它的音质相对较差,但对于一些简单的音乐播放需求来说,是一种有效的选择。 要在STM32上使用无源蜂鸣器播放音乐,首先需要将音乐转换为适合蜂鸣器播放的格式。蜂鸣器只能发出单音,因此需要将音乐转换为一系列频率不同的音符。 接下来,可以使用STM32的GPIO(通用输入/输出)引脚来控制蜂鸣器。通过改变GPIO引脚的电平,可以产生不同的频率振动,从而发出不同的音符。 编写STM32的程序来控制蜂鸣器播放音乐。首先,配置GPIO引脚为输出模式,并将其设置为低电平以确保蜂鸣器不会一直处于激活状态。 接下来,使用一个循环来依次播放音符。在每个循环中,将GPIO引脚设置为高电平,以产生振动,并保持一段时间来产生音符的持续时间。然后,将GPIO引脚恢复为低电平,以停止振动。 通过循环控制不同音符的播放次数和间隔时间,可以实现音乐的播放。为了控制音乐的速度和节奏,可以调整循环的延迟时间。 需要注意的是,由于无源蜂鸣器的音质受限,播放的音乐可能会有失真或低音不够丰富的问题。如果需要更好的音质,可以考虑使用外部音频芯片或模块来实现音乐播放功能。 ### 回答2: 在STM32微控制器上使用无源蜂鸣器播放音乐可以通过PWM(脉宽调制)技术实现。无源蜂鸣器是一种简单而廉价的电子元件,它可以发出事先设计好的音调。以下是实现步骤: 1. 首先,在STM32开发环境中编写代码,配置IO引脚和定时器以产生PWM信号。为了控制无源蜂鸣器的音调,我们需要使用定时器来生成不同频率的PWM信号。 2. 在代码中定义音符的频率和持续时间。音符的频率决定了所发出的声音,持续时间决定了音符的长度。 3. 在代码中定义一个主循环,在该循环中依次播放每个音符。通过改变PWM信号的频率和持续时间,可以产生不同的音调和音乐效果。 4. 使用延迟函数或定时器中断来控制音符的持续时间。当一个音符播放完毕后,延迟一段时间以控制音符之间的间隔,从而使音乐更加流畅。 5. 在主循环中循环播放所有音符,直到所有音符播放完毕或者接收到停止播放的指令。 通过以上步骤,我们可以使用STM32微控制器和无源蜂鸣器播放音乐。需要注意的是,由于无源蜂鸣器只能发出简单的音调,所以播放的音乐可能会有限制。如果需要播放更复杂的音乐,可能需要使用其他音频设备或者扬声器。 ### 回答3: 要在STM32上使用无源蜂鸣器播放音乐,您可以通过PWM(脉冲宽度调制)的方式来控制蜂鸣器的音调和音乐。下面是实现的步骤: 1. 首先,连接无源蜂鸣器到STM32开发板上的GPIO引脚上。确保接线正确。 2. 在STM32的代码中,配置相关的GPIO引脚为PWM输出模式。 3. 初始化一个定时器,用于产生PWM信号,并设置其频率为所需的音调。 4. 创建一个数组,用于存储音乐的音符和其对应的频率。您可以根据需要添加不同的音符和频率。 5. 在代码中使用循环来播放音乐。使用定时器产生的PWM信号来控制蜂鸣器的音高,通过定时器的开启和停止来控制音符的长度和间隔。 6. 在循环中,依次读取音乐数组中的音符和频率,并将当前音符的频率写入定时器的自动重装载寄存器。 7. 播放下一个音符前,通过延时函数来控制音符的持续时间。 8. 重复步骤6和7,直到所有的音乐都播放完毕。 9. 如果您希望播放连续的音乐,可以在播放结束后重新开始播放。 这就是如何在STM32上使用无源蜂鸣器播放音乐的一般步骤。您可以根据实际需求自定义音乐和频率,以实现更多的功能和效果。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值