1 项目介绍
- 使用矩阵键盘、蜂鸣器、流水灯和电位计设计音乐键盘,让不同按键发出不同音调,电位计用来控制声音大小,流水灯用来显示声音档位。
- 不同按键发出不同音调,共十六个键,要求每个键发出音调不同
- 电位计用来控制声音大小,旋转电位器声音音量会变化。
- 流水灯用来显示声音档位,LED点亮个数应该与音量成正比。
2、设计思路及硬软件框图
2.1设计思路
依据所给的任务解析,大致设计思路如下:
首先,用到的模块有蜂鸣器、矩阵键盘、流水灯、OLED屏、电位器,使用的功能包括定时器、PWM波、ADC。
各项系统初始化后,while循环里读取按键值,如何ADC采样,之后将得到的参数处理,通过传给相关函数改变PWM波的频率、占空比来达到改变音量、音调变化,然后用PWM波驱动蜂鸣器。同时处理得到的音调音量显示在OLED屏幕上,音量参数还能改变LED灯亮的个数。
2.2硬件介绍
本项目使用的硬件:有蜂鸣器、矩阵键盘、流水灯、OLED屏、ADC电位器。
蜂鸣器:蜂鸣器是一种一体化结构的电子讯响器,采用直流电压供电,广泛应用于计算机、打印机、复印机、报警 器、电子玩具、汽车电子设备、电话机、定时器等电子产品中作发声器件,主要分为有源蜂鸣器和无源蜂鸣器。本项目使 用的是无源蜂鸣器。
矩阵键盘:矩阵键盘是单片机外部设备中所使用的排布类似于矩阵的键盘组。矩阵式结构的键盘显然比直接法要复杂一些,识别也要复杂一些,列线通过电阻接正电源,并将行线所接的单片机的I/O口作为输出端,而列线所接的I/O口则作为输入。
LED阵列:发光二极管,简称为LED,是一种常用的发光器件。
OLED显示屏:OLED显示技术与传统的LCD显示方式不同,无需背光灯,采用非常薄的有机材料涂层和玻璃基板(或柔性有机基板),当有电流通过时,这些有机材料就会发光。而且OLED显示屏幕可以做得更轻更薄,可视角度更大,并且能够显著的节省耗电量。
ADC电位器:电位器是具有三个引出端、阻值可按某种变化规律调节的电阻元件。电位器通常由电阻体和可移动的电刷组成。当电刷沿电阻体移动时,在输出端即获得与位移量成一定关系的电阻值或电压。
2.3软件框图
首先系统初始化;定时器、OLED、GPIO、ADC中断初始化。然后两部分:
音调部分:检测按键读取键值,并处理成音调;显示键值到OLED屏上。调节PWM波频率,驱动蜂鸣器播放乐音
音量部分:同时开启ADC采样读取电位器电压,并处理成音量,根据音量,流水灯显示声音档位
显示音量到OLED上,调节PWM波占空比,更改音量
3、主要代码片段及说明
int key_value = 0;
int adcResult,volume1,volume,i,num=0;
int LED_tab[8] = {LED_LED0_PIN,LED_LED1_PIN, LED_LED2_PIN,LED_LED3_PIN, LED_LED4_PIN, LED_LED5_PIN,LED_LED6_PIN,LED_LED7_PIN};
定义键值,音量等参数,并定义流水灯数组方便控制。
SYSCFG_DL_init();
NVIC_EnableIRQ(ADC0_INT_IRQn);
adcflag = ADCFlagConversionStart;//初始化ADC标志位
OLED_Init();
OLED_Clear();
DL_TimerG_startCounter(PWM_0_INST);
DL_TimerG_setCaptureCompareValue(PWM_0_INST,0,DL_TIMER_CC_1_INDEX);//先将音量调为0,不然会突然响一下
将系统初始化;开启定时器、OLED初始化,先将PWM波调为0,不然会突然响一下。
OLED_ShowCHinese(32,0,0);OLED_ShowCHinese(48,0,1);OLED_ShowCHinese(64,0,2);OLED_ShowCHinese(80,0,3);
OLED_ShowCHinese(0,2,0);OLED_ShowCHinese(16,2,4);
OLED_ShowCHinese(0,4,0);OLED_ShowCHinese(16,4,5);
OLED_ShowString(32, 2, ":");
OLED_ShowString(32, 4, ":");
OLED_ShowString(72, 2, "(0-80)");
OLED_ShowString(72, 4, "(0-16)");
在OLED屏上显示,通过取模软件打出中文,构成显示菜单界面
while(1)
{
key_value = getKeyValue();
OLED_ShowNum(48, 4, (unsigned int)key_value, 2, 16);
DL_ADC12_startConversion(ADC12_0_INST);//开始ADC采样
adcResult = DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_0);
volume=adcResult/500;
volume1=adcResult/50;
OLED_ShowNum(48, 2, volume1, 2, 16);
读取键值,开启ADC模数转换,将其转换成音量并显示。
while(num!=volume)
{
if(num<volume)
{
DL_GPIO_clearPins(LED_PORT, LED_tab[num+1]);
num++;
}
if(num>volume)
{
DL_GPIO_setPins(LED_PORT, LED_tab[num]);
num--;
}
}
通过判定音量大小开启LED灯的个数。
DL_TimerG_setCaptureCompareValue(PWM_0_INST,volume,DL_TIMER_CC_1_INDEX);//volume音量控制
if(key_value!=0)
{
DL_TimerG_setLoadValue(PWM_0_INST,100+key_value*50);//tonality音调控制
}
else
DL_TimerG_setLoadValue(PWM_0_INST,0);
配置PWM波驱动蜂鸣器,并通过条件语句让按键按下时才发出音乐。
4、 该项目完成的功能及图片展示
4.1 OLED辅助显示
OLED屏第一行显示中文的主题“音乐键盘“字样,第二行显示“音量: (0-100)“,第三行显示“音调: (0-16)“。空白处是可以跟随变化的音量和音调值。 调节电位器可以调整音量大小。LED灯亮的个数可以表示声音档位。一个灯亮就是世界两个灯三个灯依次对应。二十几,三十几。矩阵键盘发出不同音调的声音,
4.2矩阵键盘按下发出不同声音
按下按键发出声音,0-16键值代表不同音调,由低到高,声音由尖锐到低沉
4.3电位器调整音量大小。
旋转电位器可以调节音量,顺时针音量变大,逆时针音量变小,
4.4LED流水灯表示声音档位
OLED屏音量显示在0~80之间,LED灯亮个数可以跟随音量的十位数变化。例如:音量23有2个LED灯亮,音量65有6个。
5、遇到的主要难题及解决方法
本次项目设计过程中主要遇到问题有图形化配置困难和查找对应函数,解决方法是查找TI官网的例程和函数库,其他方面也有一些小问题,如OLED显示中文取模显示失败,最通过后新建函数方法解决。
6、总结与展望
这次的项目设计让我受益匪浅,熟悉了STM32单片机的基本操作,包括GPIO、定时器、ADC、PWM等模块的使用,掌握了矩阵键盘、蜂鸣器、流水灯、OLED屏、电位计等硬件的连接和驱动方法,锻炼了代码编写、调试和问题解决的能力,了解了电子音乐制作的基本原理和方法。同时该项目仍有不足,音调和音色效果还有提升空间,可以尝试进一步优化音调和音色效果,提升音乐键盘的音质。扩展功能,加入更多音效、节奏控制、音轨录制等功能,打造更丰富的音乐体验。