栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

STM32歌唱《孤勇者》(标准库)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

STM32歌唱《孤勇者》(标准库)

先说一下自己玩两年的单片机的想法吧,玩了大概有两年了,从刚刚开始的不知所措,到现在的成熟,终于还是搞明白了一件事,编程思路,远远比源码更重要,所以,我接下来会给大家完整的介绍,完成此项目的心得,太心酸了。最后也会把main函数里面完整的代码粘出来。

此项目是哔哩哔哩上面看到的一个小玩意,B站上面的利用的51单片机,而我移植他们的一部分程序,加载到32单片机上了。

首先,有一块带无源蜂鸣器的板子,一定是无源蜂鸣器,无源蜂鸣器,会根据加载不同频率的信号,发出不同的声音。

然后,就是乐理知识,每一个音符的频率大小是多少,我也找出来了,这里有低音、中音、高音三种。最基础也就7个:哆来咪发唆啦西;但是这里面又多出来带#号的音符:例:低音4#:表示,比音调4高半个音,比音调5低半个音,就记住比前一个高,比后一个低就行了,咱们有不学音乐,大致了解就行了。

高音的音乐很少很少,而且《孤勇者》也没有用到高音,所以在程序中定义一个数组来存放这些基础音调的频率,我们演奏的歌曲的时候,需要哪个,直接调用,就可以完成曲子了。

在数组中还有,低音的一半,这个我也不知道干啥的,在最后调用也没有用到,这是人家的源码,我就没有修改。

我的程序中定义数组:

 unsigned int music_table[] = 
{130,139,147,156,165,175,185,196,208,220,233,247,  //0-11半音
 262,277,294,311,329,349,370,392,415,440,466,494,  //12-23 低音
 523,554,587,622,659,698,740,784,830,880,932,988,  //24-35 中音
 0  //0:不发声音,停止播放,在音乐中叫休止符
};
 

 先解释,数组中数据怎么演奏出来吧,定义了两个数组,第一个数组表示基础音符的频率,第二个数组存放《孤勇者》乐谱的频率组合所对应第一个数组的地址。利用数组嵌套的方式去调用。

		j=music_table[music[x]];

 最基础的源码贴出来了,该拿出来,《孤勇者》的乐谱了,我也找了出来;演奏的是我用红色框起来的那段高潮部分,我也用一个数组来保存这段乐谱:

有人看见就蒙圈了:我来解释一下数组里面数据什么意思;下面还有一个宏定义,来表示这些数据

B6N:表示音符6的低音;

B6H:表示音符6的高音;

36:表示第一个数组的第36的数据0;也就是刚刚上面代码中的休止符,表示停顿。

unsigned char music[] = 
{
B6N,B7N,B1H,B2H,B7N,B1H,B1H,36,
//爱  你  孤  身  走 暗  巷
B1H,B7N,B1H,B2H,B7N,B1H,B1H,36,
//爱 你  不  跪  的  模  样
B1H,B2H,B3H,B2H,B3H,B2H,B3H,36,
//爱 你  对  峙  过  绝  望
B3H,B2H,B3H,36,B5H,B5H,B3H,36,
//不 肯  哭      一      场
B6N,B7N,B1H,B2H,B7N,B1H,B1H,36,
//爱 你  破  烂  的 衣  裳
B1H,B7N,B1H,B2H,B7N,B1H,B1H,36,
//却 敢  赌  命  运 的  枪
B1H,B2H,B3H,B2H,B3H,B2H,B3H,36,
//爱 你  和  我  那  么  像
B3H,B2H,B3H,36,B5H,B5H,B3H,36,36,
//缺 口  都     一      样
B5H,B3H,B3H,36,36,B5H,B3H,36,36,
//去 吗            配  吗
B5H,B3H,B5H,B6H,B3H,B5H,36,
//这 褴  褛  的  披  风
B5H,B3H,B5H,B3H, 36,
//战  马  斩 啊
B5H,B3H,B5H,B6H,B3H,B5H,36,
//以  最  卑  微  的  梦
												B5H,B5H,B3H,B2H,B2H,B2H,B1H,B3H,B3H,B2H,B2H,B2H,B1H,B1H,B6N,36,36,
//掷 那  黑      夜  中  的  呜          咽  与  怒  吼
												B5H,B5H,B3H,B2H,B2H,B2H,B1H,B3H,B3H,B2H,B2H,B2H,B1H,B1H,B6N,36,
//谁 说  站      在  光  里  的              才  算  英  雄
};																	 

还有一个宏定义:

#define B6N 19
#define B7N 21
#define B1H 23
#define B2H 24
#define B3H 26
#define B4H 28
#define B5H 29
#define B6H 31

《孤勇者》对应的音符组合,每个音符的频率在第一个数组的位置。

接下来就是控制频率了,频率就是在一秒钟跳变了几次,所以我就直接利用延迟函数,来控制每次跳变的时间,也就是周期的一半:

j:表示频率,控制每个音符持续多长时间,控制每的音符的周期

i:也表示频率,控制while(i--)控制周期
 delay_us(500000/j):1/262等于周期T(s),换成一半周期的,单位us的周期
 

		i=j*0.6;//半节拍(控制每个音符持续多少时间)
		while(i--)//控制周期(1s跳变多少次)
		{
			GPIO_Trgger();
			delay_us(500000/j);// 1/262等于周期T(s),换成一半周期的,单位us的周期
		}

 main函数的程序:没有多少新东西,就是那个时间控制的有点微妙,多看几遍;

#include "stm32f10x.h"   
#include "SysTick.h"
#include "usart.h" 
#include "gpio.h" 
 
#define B6N 19
#define B7N 21
#define B1H 23
#define B2H 24
#define B3H 26
#define B4H 28
#define B5H 29
#define B6H 31
 
 unsigned int music_table[] = {130,139,147,156,165,175,185,196,208,220,233,247,//0-11半音
                  262,277,294,311,329,349,370,392,415,440,466,494,//12-23 低音
                  523,554,587,622,659,698,740,784,830,880,932,988,0};//24-35 中音
 
unsigned char music[] = {B6N,B7N,B1H,B2H,B7N,B1H,B1H,36,
												//爱  你  孤  身  走 暗  巷
												B1H,B7N,B1H,B2H,B7N,B1H,B1H,36,
												//爱 你  不  跪  的  模  样
												B1H,B2H,B3H,B2H,B3H,B2H,B3H,36,
												//爱 你  对  峙  过  绝  望
												B3H,B2H,B3H,36,B5H,B5H,B3H,36,
												//不 肯  哭      一      场
												B6N,B7N,B1H,B2H,B7N,B1H,B1H,36,
												//爱 你  破  烂  的 衣  裳
												B1H,B7N,B1H,B2H,B7N,B1H,B1H,36,
												//却 敢  赌  命  运 的  枪
												B1H,B2H,B3H,B2H,B3H,B2H,B3H,36,
												//爱 你  和  我  那  么  像
												B3H,B2H,B3H,36,B5H,B5H,B3H,36,36,
												//缺 口  都     一      样
												B5H,B3H,B3H,36,36,B5H,B3H,36,36,
												//去 吗            配  吗
												B5H,B3H,B5H,B6H,B3H,B5H,36,
												//这 褴  褛  的  披  风
												B5H,B3H,B5H,B3H, 36,
												//战  马  斩 啊
												B5H,B3H,B5H,B6H,B3H,B5H,36,
												//以  最  卑  微  的  梦
												B5H,B5H,B3H,B2H,B2H,B2H,B1H,B3H,B3H,B2H,B2H,B2H,B1H,B1H,B6N,36,36,
												//掷 那  黑      夜  中  的  呜          咽  与  怒  吼
												B5H,B5H,B3H,B2H,B2H,B2H,B1H,B3H,B3H,B2H,B2H,B2H,B1H,B1H,B6N,36,
												//谁 说  站      在  光  里  的              才  算  英  雄
                        };																	 
																	 
int main(void)
{
	uint16_t i=0,j=0;
	unsigned int x=0,endx=0;

	My_USART_Init();
	SysTick_Init(72);
	My_GPIOInit();
	endx = sizeof(music);
	while(1)
	{
		
		j=music_table[music[x]];
		i=j*0.6;//半节拍(控制每个音符持续多少时间)
		while(i--)//控制周期(1s跳变多少次)
		{
			GPIO_Trgger();
			delay_us(500000/j);// 1/262等于周期T(s),换成一半周期的,单位us的周期
		}
		
		if(j==0)//休止符
		{
			
			delay_ms(200);
			GPIO_Trgger_JQD();
		}
		x++;
		if(x>=endx)x=0;
	}
}

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/971194.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号