单片机实验四(电子琴自动演奏)

一、实验设备

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分析问题、设计/开发具体问题方案的过程。

  • 4
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值