在上一篇的测评中成功的驱动了蜂鸣器,在这一篇中我们进一步结合OLED屏幕和蜂鸣器制作一个简易音乐盒子。
当单片机用于演奏歌曲时,只需搞清楚两个概念即可,也就是“音符(音调)”和“节拍”。音调表示一个音符该唱的频率,节拍表示一个音符该唱多长的时间。我们创建两个数组分别控制这两个变量并且交替修改就能得到我们想要的输出音乐效果。
我们可以在网上搜索到音符与频率对照表如下图:
这里我们定义一个UC16的数组用来存放我们的频率信息:
// 低7 1 2 3 4 5 6 7 高1 高2 高3 高4 高5 不发音
uc16 tone[] = {247,262,294,330,349,392,440,294,523,587,659,698,784,1000};//音频数据表
另外一个部分就是控制音长的部分,也是我们常说的节拍部分,节拍的修改是通过延长或缩短频率的时间所实现的。
接着我们需要添加一个修改输出频率与就是控制音调的函数:
void Sound(u16 frq)
{
u32 time;
if(frq != 1000)
{
// time = 500000/((u32)frq);
time = 100000/((u32)frq);
//BEEP (0);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9,GPIO_PIN_RESET);//打开蜂鸣器--根据自己的硬件情况调整,通常就是控制蜂鸣器的gpio引脚置1
delay_us(time);
//BEEP(1);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_9,GPIO_PIN_SET);//关闭蜂鸣器--根据自己的硬件情况调整,通常就是控制蜂鸣器的gpio引脚置0
delay_us(time);
}else
delay_us(1000);
}
我们将想要编写的音乐写到另一个存放音频和节拍信息的函数中通过调用void Sound(u16 frq)函数并进行延时就可以输出音乐了
void play_music(void)
{
// 低 1 2 3 4 5 6 7 中1 2 3 4 5 6 7 高1 2 3 4 5 6 7
// uc16 tone[] = {262,294,330,349,392,440,494,523,587,659,698,784,880,998,1046,1175,1318,1397,1568,1760,1967};//音频数据表
// // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
// //
// u8 music[]={9,11,14,12,11,20,//音调
// 9,11,12,14,11,20,
// 14,16,15,14,15,14,19,14,18,20,
// 9,11,12,11,12,14,8,11,12,20,
// 9,7,8,20,
// 8,8,9,11,11,14,8,9,11,20};
// u8 time[] ={2,2,2,2,6,4,//时间
// 2,2,2,2,6,4,
// 6,2,4,4,2,2,2,2,6,4,
// 6,2,4,2,2,4,2,2,6,4,
// 2,2,4,6,4,
// 4,2,2,4,4,4,2,2,6,4};
// uc16 tone[] = {247,262,294,330,349,392,440,494,523,587,659,698,784,1000};//音频数据表
uc16 tone[] = {262,294,330,349,392,440,494,523,587,659,698,784,880,998,1046,1175,1318,1397,1568,1760,1967};
//
u8 music1[]={13,1,2,3,4,5,6,7,8};
u8 time1[] = {4,4,4,4,4,4,4,4,4};
// u8 music[]={13,1,2,3,4,5,6,7,8};//测试基础音
// u8 time[] ={4,4,4,4,4,4,4,4,4};
u32 yanshi;
u16 i,e;
yanshi = 2;//10; 4; 2
for(i=0;i<sizeof(music1)/sizeof(music1[0]);i++){
for(e=0;e<((u16)time1[i])*tone[music1[i]]/yanshi;e++){
Sound((u32)tone[music1[i]]);
}
}
在介绍使用蜂鸣器播放音乐的程序时所使用的频率都是理论值,根据不同电路蜂鸣器的差异可以在理论的音频数据上下修改值不断尝试使得输出音乐更好听。
在这里我结合蜂鸣器音乐输出和oled屏幕功能制作了一个简易播放生日歌的程序:
2564f7089735b901ab03ce37b6e854d8