一、实验设备
PC机一台、实验箱一台。
二、实验内容
实现电子琴功能,自动演奏歌曲《葫芦娃》片段,并设置两个按键来实现歌曲的“暂停”和“开始/停止”。
图1 《葫芦娃》曲谱片段
三、实验步骤
①先在CUBE软件中进行硬件的图形化配置,选择STM32F407ZE芯片后,先进行常规的RCC和SYS设置,并配置时钟树使得HCLK为168MHz(如图2所示),在项目管理中进行项目的命名、存放地址、IDE等配置。
图2 时钟树的配置
②分析实验得,需要打开定时器并开启PWN波输出,设置PWN波Prescaler为83即可,Counter Period和pulse进行不报错设置(如图3所示)。
图3 定时器的配置
③分析实验得,需要两个按键来实现控制功能,打开两个GPIO并设置为输入模式(如图4所示)。
图4 GPIO开关的配置
④生成配置代码,进入到KEIL中完成相关功能代码,先进行KEIL的常规配置,设置晶振频率为8MHz,并设置硬件调试模式为J-LINK/J-TRACE Cortex,先根据曲谱写入曲谱数组,并写入pwn波输出函数,在while循环中使用递增不断改变曲谱的值,根据曲谱的值改变频率从而改变音调,从而实行歌曲的自动循环演奏,根据对两个按键的扫描通过改变play的值,来完成歌曲的暂停与播放,并通过改变i的值为0来实现歌曲的从头播放,编译下载后,进行硬件连线从而实现实验功能。
//曲谱
uint8_t num[75] = {0,0, 1,1,1,1,3,3,3, 1,1,1,1,3,0,0, 6,6,6,6,6,5,6,6,5,5,1,1,3,3,0,0,0, 8,6,6,5,6,6,5,5,1,1,2,2,0,0, 7,7,7,7,7,7,5,3,3,3,3,5,5,5,5,5,5,0};
//电子琴
while (1)
{
flag = KEY_Scan();
if(flag!=0)
{
if(flag == 1)
{
if(play == 0){play = 1;i = 0;}
else play = 0;
}
else if(flag == 2)
{
if(play == 0)play = 1;
else play = 0;
}
}
if(play == 1)
{
key = num[i];
i++;
if(i >= 75) i = 0;
switch(key)
{
case 0:
{
__HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_2,0);
break;
}
case 1:
{
__HAL_TIM_SetAutoreload(&htim1,1000000/262);
__HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_2,1000000/262*0.9);
break;
}
case 2:
{
__HAL_TIM_SetAutoreload(&htim1,1000000/294);
__HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_2,1000000/294*0.9);
break;
}
case 3:
{
__HAL_TIM_SetAutoreload(&htim1,1000000/330);
__HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_2,1000000/330*0.9);
break;
}
case 4:
{
__HAL_TIM_SetAutoreload(&htim1,1000000/349);
__HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_2,1000000/349*0.9);
break;
}
case 5:
{
__HAL_TIM_SetAutoreload(&htim1,1000000/392);
__HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_2,1000000/392*0.9);
break;
}
case 6:
{
__HAL_TIM_SetAutoreload(&htim1,1000000/440);
__HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_2,1000000/440*0.9);
break;
}
case 7:
{
__HAL_TIM_SetAutoreload(&htim1,1000000/492);
__HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_2,1000000/492*0.9);
break;
}
case 8:
{
__HAL_TIM_SetAutoreload(&htim1,1000000/523);
__HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_2,1000000/523*0.9);
break;
}
}
HAL_Delay(200);
}
else if(play == 0)__HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_2,0);
四、实验收获
①学会了在以不同按键实现不同功能的工程中,在按键扫描函数中加入按键正忙变量,来避免出现按键冲突。
②学会了自主设计单片机时,如何规划单片机代码的实现顺序,来逐步验证功能,防止一次性敲完所有代码后,在一次性验证时出现问题,排查错误范围太广。
③通过这次的实验,将理论的单片机知识和实际中的具体问题方案联系了起来,加深了对具体知识的印象,体会了通过STM32分析问题、设计/开发具体问题方案的过程。