stm32蜂鸣器播放音乐 您所在的位置:网站首页 stm32蜂鸣器播放音乐16进制的乐谱 stm32蜂鸣器播放音乐

stm32蜂鸣器播放音乐

2023-08-29 04:39| 来源: 网络整理| 查看: 265

  最近学习stm32芯片,使用的是蓝桥杯的f103的旧板子,看到上面有蜂鸣器,所以就想写代码来控制蜂鸣器播放一首音乐。   这里我参考了这篇文章基于STM32F103,用蜂鸣器播放歌曲。同这篇文章一样,我也遇到了蜂鸣器发出的声音不对。参考了这篇文章,以及查找网上的其他资料,最终完成了蜂鸣器的调试,以及歌曲的编写,文章最后会附上代码。   先对音符这类东西进行说明吧。因为自己也不是学音乐的,一些关于音乐的知识都是网上搜集的,所以如果有讲得不对的地方,也请各位读者在评论指正,我会及时改正。   首先在百度上搜索每个音符的频率,这里我参考的是音符与频率对照表 C调音符与频率对照表 其实对于哪个调来说,我感觉不出来什么差别(可能我没有什么艺术细胞吧),而且在代码里我的音符的频率对应图片里的音符的频率是高一个八度。【如下图】

// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // 低7 1 2 3 4 5 6 7 高1 高2 高3 高4 高5 高6 高7 高高1 uc16 tone[] = {247,262,294,330,349,392,440,494,523,587,659,698,784,880,988,1046,0};

  也许我上面说的有些迷糊,但是我们通过上面那张表就可以得到每个音符所对应的频率,这个是我们需要的。   有了每个音符的频率还不够,我们还需要知道每个音符持续的时间,也就是音符时值。   这里我拿我的选的一个曲子举例子。 在这里插入图片描述    Eb \text{Eb} Eb指的是曲子的调是Eb调,(每个调之前的区别,我个人感觉不出大差别,所以我的音符频率是按C调频率来的),后面的 4 4 \frac44 44​指的是以四分音符为一拍,一小节四拍。在后面的音符=120,指的是一分钟120拍,所以我们从这里就可以知道,一个四分音符的时值是0.5s. 那么什么是四分音符呢? 音符

  如上图,音符下面有三条横线的,就是三十二分音符,有两条横线的就是十六分音符,一条横线的就是八分音符,没有横线的就是四分音符。   这些音符对应的时值分别为(设四分音符的时值为 t t t)

四分音符= t t t八分音符= t / 2 t/2 t/2十六分音符= t / 4 t/4 t/4三十二音符= t / 8 t/8 t/8

  除了上面四个音符外,有时谱子里还会遇到一个音符跟着一个小点,这种称为附点。 附点 有附点的音符的时值,与附点跟随的音符有关。附点的时值为跟随的音符时值的一半。所以有附点的音符的时值为 跟随的音符的时值×1.5

例如,图中的 3 ˙ . ‾ \underline{\dot 3.} 3˙.​的时值计算如下 设四分音符的时值为 t t t 3 ˙ ‾ \underline{\dot 3} 3˙​为八分音符,时值为 t / 2 t/2 t/2 附点的时值为跟随音符的时值的一半,在这里也就是 t / 4 t/4 t/4 因此 3 ˙ . ‾ \underline{\dot 3.} 3˙.​ 的时值为 t / 2 + t / 4 = 3 t / 4 t/2+t/4=3t/4 t/2+t/4=3t/4 //-------------------------------------------------------------------------- 举一反三 6. 6. 6.的时值计算如下 设四分音符的时值为 t t t 6 6 6为四分音符,所以时值为 t t t 附点为跟随音符的时值的一半,为 t / 2 t/2 t/2 所以 6. 6. 6.的时值为 t + t / 2 = 3 t / 2 t+t/2=3t/2 t+t/2=3t/2

  关于音符的介绍差不多就到这里了,接下来就是代码相关的东西了。 【蜂鸣器的控制就不用我说了吧,一般原理图上都是用三极管驱动蜂鸣器,所以引脚出高低就能控制蜂鸣器的叫与不叫,至于引脚出高还是低,蜂鸣器响,具体的还是看自己板子上的原理图吧】 首先是定义一个音符的频率数组,至于数组中的数从哪来,可以参考我前面发的音符频率对照表,或者要是知道音符频率的关系,自己算也可以。

// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // 低7 1 2 3 4 5 6 7 高1 高2 高3 高4 高5 高6 高7 高高1 uc16 tone[] = {247,262,294,330,349,392,440,494,523,587,659,698,784,880,988,1046,0};

接下来就是写谱子的音符,这里我就截我选的曲子 蓝色线截选的音符,就是我让单片机播放的曲子片段。 相应的音符数组如下

u8 BrokenMoon[]={ 3,5,6,8, 9,8,9,10,8,6, 5,3,8,9,6,6,8, 9,8,9,10,12,13, 15,14,13,14,13,12,13,12,10, 9,10,8,9,8,9, 10,6,8,9,8,6,6,5, 6,5,6,8,9,10,9,5, 6 };

数组里对应的数字,就是tone数组的元素下标,也就是每个音符。   然后是关于音符时值的数组【每个音符具体的时值与你选的谱子的曲速和音符种类有关,我在上面都讲解了一下,如果还是没看懂的话,可以去B站看看相关知识,大概几分钟就可以看完】

//因为我选的曲子速度是每分钟120拍,所以可以算出每个音符相对应时值 //时值 全音符2s 二分音符 1s 四分音符 0.5s 八分音符 0.25s // 十六分音符 0.125s 三十二分音符 0.0625s //比例为32:1 //全音符 64 二分音符 32 四分音符 16 八分音符 8 //十六分音符 4 三十二分音符 2 u8 scale = 16;//每个音符时值放大的比例,用于将时值数组转换为实际的时间长度 //其实scale的值应该为32,但是测试的时候,感觉播放的速度过快,所以调成16 //大家在实际操作的时候,也可以改一改,但是建议能不改scale的值就别改scale的值 u8 BrokenMoonTime[]={ 8,8,8,8, 16,8,8,16,8,8, 8,8,8,8,16,8,8, 16,8,8,16,8,8, 8,8,2,2,4,8,16,8,8, 16,8,8,16,8,8, 12,4,4,4,8,16,8,8, 12,2,2,8,8,8,8,16, 32 };

  准备好音符和时值数组之后,一个重要的函数就来了。

void BUZZER_Play(u16 frq){ u32 time; if(frq){ // time = 500000/((u32)frq);//单个脉冲的高电平持续时间(单位为us)为1*10^6/2f=500000/f f为音符的频率 time = 50000/((u32)frq); BUZZER_ON(); delay_us(time); BUZZER_OFF(); delay_us(time*9);//调节占空比 } else delay_us(1000); }

  这是用蜂鸣器播放一个脉冲的函数。函数的参数,频率frq,即单个音符对应频率。函数执行的就是蜂鸣器播放该频率下的一个脉冲。   根据,之前的参考的文章,他们的设置高电平的占空比为50%,但我具体测试的时候,发现修改time的值虽然会有使音色改善,但也造成了播放速度过快,后面想了想,觉得蜂鸣器的占空比为50%不太合理,根据测试,选择了10%的占空比,大家具体测试的时候,如果发现音色不好,可以修改高电平的占空比。

具体方法如下:

先将time= 500000/((u32)frq);写到BUZZER_Play()函数里,然后让蜂鸣器响和不响的延时时间都相同,为time下载代码测试音色,根据实际情况,修改time = 500000/((u32)frq)中的500000的值,直到自己一个满意的效果。然后比较修改后time的值与原来time = 500000/((u32)frq)的。将原来time值假设为 t 0 t_0 t0​,调试完之后的值为 t 1 t_1 t1​将蜂鸣器响的延迟时间设置为 t 1 t_1 t1​,将蜂鸣器关闭的延迟时间设置为 t 0 − t 1 t_0-t_1 t0​−t1​

修改完的代码,样子如下

void BUZZER_Play(u16 frq){ u32 time; if(frq){ time = m/((u32)frq);//m根据实际测试结果进行修改 BUZZER_ON(); delay_us(time); BUZZER_OFF(); delay_us(t_0-t_1);//t_0-t_1的值根据实际测试结果计算出来的 } else delay_us(1000); }

  写完播放一个固定频率的脉冲之后,就是写在一段时间内播放固定频率的脉冲的函数。

void MUSIC_Play(void){ u16 i,j; for(i=0;i 3,5,6,8, 9,8,9,10,8,6, 5,3,8,9,6,6,8, 9,8,9,10,12,13, 15,14,13,14,13,12,13,12,10, 9,10,8,9,8,9, 10,6,8,9,8,6,6,5, 6,5,6,8,9,10,9,5, 6 }; u8 BrokenMoonTime[]={ 8,8,8,8, 16,8,8,16,8,8, 8,8,8,8,16,8,8, 16,8,8,16,8,8, 8,8,2,2,4,8,16,8,8, 16,8,8,16,8,8, 12,4,4,4,8,16,8,8, 12,2,2,8,8,8,8,16, 32 }; void BUZZER_Play(u16 frq){ u32 time; if(frq){ // time = 500000/((u32)frq);//单个脉冲的高电平持续时间(单位为us)为1*10^6/2f=500000/f f为音符的频率 time = 50000/((u32)frq); BUZZER_ON(); delay_us(time); BUZZER_OFF(); delay_us(time*9);//调节占空比 } else delay_us(1000); } void MUSIC_Play(u8 *music,u8 *time,u16 length){ u16 i,j; for(i=0;i


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有