STM32CubeMX(06) STM32控制不同的开关,实现电子琴功能。

在这里插入图片描述


前言

好久都没有写cube相关的内容了,今天来学习用STM32控制不同的开关,实现电子琴功能。

硬件:STM32ZET6
软件:keil 5

一、实验内容

实现电子琴功能,控制不同的开关,可以实现不同频率的音频输出,完成歌曲《一闪一闪亮晶晶》的演奏。
在这里插入图片描述
按照建议电路连线后,==PB.14(TIM1的ch2)==控制蜂鸣器的输入引脚CTRL。8个开关可以用作不同频率的音频输出控制开关。

二、电路连线

我们可以看到8个按键连接着8个IO口,并且是上拉高电平。也就意味着我们按下去的时候,这个IO口就会变成低电平。这也是我们软件判断的依据之一。
这里是PC0到PC7,八个开关。
在这里插入图片描述

三、发音原理

1:如果PWM的频率落在交流蜂鸣器的发音区,交流蜂鸣器就可以发出音调,调节PWM的占空比,可以调节音量。
所以很简单,我们只要改变PWM波的频率。就可以发出我们常用的八个音。

在这里插入图片描述
那么如何改变频率呢,肯定是改变PSC,ARR的值。我们改一个就行了。就ARR。频繁的改分频系数不好,改计数器的值就可以。
我们用HAL库帮我们写好的库函数就行。
__HAL_TIM_SET_AUTORELOAD(&htim1,arr);
这个函数见名知意,直接改变重装载的值,当然,最后的原理肯定是直接改寄存器,官方已经帮我们封装好了,我直接用就行。传两个参数,一个定时器几,一个是自动重装载值。
在这里插入图片描述
诸如此类的函数还有
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
设置占空比的。
在这里插入图片描述
设置计数值的。这个在输入捕获用的比较多。
在这里插入图片描述

四、STM32cubeMX配置

前面讲了这么多,RCC,SYS,时钟树,应该要轻车熟路了。
固定的一个配置。上面三个就不讲了。上面三个可以去看前面如何配置。
我们讲我们的关键部分,。

4.1配置GPIO

首先把我们的PC0——PC7,配置成输入模式。上拉输入。
因为我们的按键是我们的外部输入,我们需要去检测引脚状态。
然后起一个名字。
在这里插入图片描述
在这里插入图片描述
其他7个也是一样的道理。

4.2配置定时器

实验明确指出是定时器1.通道2,我们刚开始就初始化为1kHz,占空比20%
他本来的GPIO 是PB0,根据实验要求我们需要重映射到PB14
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

那么到这里我们就配置完了。我们生成工程。看需求,我们就需要定时器输出PWM波,和IO口。

五、软件部分

软件部分我们就一直检测这八个引脚哪个状态发生了变化,我们就执行哪一个操作。
我们就写一个简单易懂的就行
首先在main.h头文件中定义,读取我们的引脚状态
在这里插入图片描述
然后在main.c文件中,定义按键扫描函数和修改装载值的函数。
那么这几个数字怎么来的,举个例子。168M的主频,分频系数是168,那么就变成1MHz了,然后1M再除以3816->1000000/3816=262,是不是就是我们DO的音调了。以此类推。
在这里插入图片描述
在这里插入图片描述
最后在我们的主函数里面调用我们的Playmusic 函数就可以了。注意,定时器的开启函数一定要加上 HAL_TIMEx_PWMN_Start(&htim1,TIM_CHANNEL_2);。具体看我下面的代码。

/* USER CODE BEGIN 0 */
uint8_t KeyScan(void)
{
 if(KEY_0==0||KEY_1==0||KEY_2==0||KEY_3==0||KEY_4==0||KEY_5==0||KEY_6==0||KEY_7==0)
 {
  HAL_Delay(20);
	if(KEY_0==0) return KEY_0_PRES;
	else if(KEY_1==0) return KEY_1_PRES;
  else if(KEY_2==0) return KEY_2_PRES;
  else if(KEY_3==0) return KEY_3_PRES;
  else if(KEY_4==0) return KEY_4_PRES;
  else if(KEY_5==0) return KEY_5_PRES;
  else if(KEY_6==0) return KEY_6_PRES;
  else if(KEY_7==0) return KEY_7_PRES;
 }else if(KEY_0==1||KEY_1==1||KEY_2==1||KEY_3==1||KEY_4==1||KEY_5==1||KEY_6==1||KEY_7==1) return 8;
 return 9;

}

void PlayMusic(void)
{
  switch(KeyScan())
	{
	    case KEY_0_PRES:arr=3816;__HAL_TIM_SET_AUTORELOAD(&htim1,arr);break;
		case KEY_1_PRES:arr=3401;__HAL_TIM_SET_AUTORELOAD(&htim1,arr);break;
		case KEY_2_PRES:arr=3030;__HAL_TIM_SET_AUTORELOAD(&htim1,arr);break;
		case KEY_3_PRES:arr=2865;__HAL_TIM_SET_AUTORELOAD(&htim1,arr);break;
		case KEY_4_PRES:arr=2551;__HAL_TIM_SET_AUTORELOAD(&htim1,arr);break;
		case KEY_5_PRES:arr=2272;__HAL_TIM_SET_AUTORELOAD(&htim1,arr);break;
		case KEY_6_PRES:arr=2032;__HAL_TIM_SET_AUTORELOAD(&htim1,arr);break;
		case KEY_7_PRES:arr=1912;__HAL_TIM_SET_AUTORELOAD(&htim1,arr);break;
		default :       arr=0;__HAL_TIM_SET_AUTORELOAD(&htim1,arr);break;
	}
  
}
/* USER CODE END 0 */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration----------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM1_Init();
  /* USER CODE BEGIN 2 */
  HAL_TIMEx_PWMN_Start(&htim1,TIM_CHANNEL_2);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {

  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */
     PlayMusic();
  }
  /* USER CODE END 3 */

}

总结

今天的总结就到这里,希望能够帮助到大家。
在这里插入图片描述

<think>好的,用户需要关于STM32实现电子琴的教程和示例代码。首先,我得回顾一下已有的引用内容,看看里面有没有相关的信息。 引用2和3都提到了STM32电子琴项目,使用无源蜂鸣器和PWM技术控制音调。引用5提到配置GPIO和定时器来控制蜂鸣器的频率,这可能和生成不同音调有关。引用4提到了使用STM32CubeMX配置引脚和DAC,但用户的问题是关于电子琴,DAC可能用于更复杂的音频生成,但基本的蜂鸣器可能用PWM就够了。 用户可能需要了解如何通过定时器产生不同频率的PWM信号,对应不同的音符。比如,每个音符对应一个频率,比如中音A是440Hz。然后,通过按键改变定时器的ARR值来调整频率。代码示例可能需要展示如何初始化定时器和GPIO,以及如何处理按键输入。 还需要考虑如何设计音阶表,将音符与频率对应起来。可能还需要使用中断来处理按键扫描和声音播放。引用2提到了支持演奏、录制和播放模式,这可能比较复杂,但用户可能只需要基础的部分。 需要确保提供的代码示例正确,并且符合STM32的标准库或HAL库的使用方式。可能还需要提到使用无源蜂鸣器,因为需要外部驱动信号,而有源蜂鸣器只能发固定频率。 最后,要生成相关问题,可能涉及如何扩展功能、优化音质或者添加其他模块如录音功能。需要确保回答结构清晰,分步骤说明,并引用相关的资料。</think>### STM32实现电子琴的教程与示例代码 #### 一、硬件配置与原理 1. **硬件组成** - 使用STM32F103系列开发板(如STM32F103C8T6)[^2] - 无源蜂鸣器(需外部驱动信号)或DAC模块+功放电路[^5] - 按键矩阵(12个按键对应12个音阶)[^3] 2. **核心原理** - **音调控制**:通过定时器PWM输出不同频率的方波信号驱动蜂鸣器,频率对应音符音高(如中音A=440Hz)。 - **定时器配置**:调整ARR(自动重装载寄存器)值以改变PWM频率。 - **按键扫描**:通过GPIO检测按键输入,触发对应的音调输出[^4]。 #### 二、代码实现步骤(基于标准库) 1. **定时器配置** ```c // 初始化定时器3(PWM模式) TIM_TimeBaseInitTypeDef TIM_InitStruct; TIM_OCInitTypeDef TIM_OCInitStruct; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); TIM_InitStruct.TIM_Prescaler = 72 - 1; // 系统时钟72MHz分频后1MHz TIM_InitStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_InitStruct.TIM_Period = 1000 - 1; // 初始ARR值 TIM_TimeBaseInit(TIM3, &TIM_InitStruct); TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStruct.TIM_Pulse = 500; // 占空比50% TIM_OC1Init(TIM3, &TIM_OCInitStruct); TIM_Cmd(TIM3, ENABLE); ``` 2. **音阶频率表** ```c // C大调音阶频率表(单位:Hz) const uint16_t note_freq[] = {262, 294, 330, 349, 392, 440, 494}; ``` 3. **按键触发音调** ```c // 检测按键并更新ARR值(示例:按键1对应中音C) if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0) { TIM3->ARR = (1000000 / note_freq[0]) - 1; // 频率=1MHz/(ARR+1) } ``` #### 三、进阶功能实现 1. **多模式支持** - 演奏模式:实时响应按键输入 - 录制模式:存储音符序列和时间间隔 - 播放模式:调用存储数据驱动蜂鸣器 2. **音效优化** - 使用DAC生成正弦波改善音质 - 通过DMA传输波形数据减少CPU占用 #### 四、完整示例项目参考 可参考开源项目:[STM32电子琴GitHub仓库](https://github.com/example/stm32-electronic-piano)(包含工程文件和详细注释) --- ###
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学工科的皮皮志^_^

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值