STM32蜂鸣器播放歌曲《小星星》

这篇博客介绍了如何使用STM32F103RB芯片通过STM32Cube配置并生成Keil文件,然后在Keil中编写代码,实现蜂鸣器播放歌曲《小星星》。主要步骤包括芯片选择、配置、代码编写,并给出了beep.c和beep.h的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、芯片选择及配置
利用STM32Cube软件配置芯片并生成Keil文件。(需要提前配置环境,没有此软件可以跳过此步 )
在这里插入图片描述
选用SMT32F103RB芯片
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
配置完成,点击此处生成Keil文件。
在这里插入图片描述
二、keil代码编程
main.c(偷懒把所有代码粘了进来)


/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  ** This notice applies to any and all portions of this file
  * that are not between comment pairs USER CODE BEGIN and
  * USER CODE END. Other portions of this file, whether 
  * inserted by the user or by software development tools
  * are owned by their respective copyright owners.
  *
  * COPYRIGHT(c) 2021 STMicroelectronics
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *   1. Redistributions of source code must retain the above copyright notice,
  *      this list of conditions and the following disclaimer.
  *   2. Redistributions in binary form must reproduce the above copyright notice,
  *      this list of conditions and the following disclaimer in the documentation
  *      and/or other materials provided with the distribution.
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
  *      may be used to endorse or promote products derived from this software
  *      without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ******************************************************************************
  */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f1xx_hal.h"

/* USER CODE BEGIN Includes */
#include "beep.h"

/* USER CODE END Includes */

/* Private variables ---------------------------------------------------------*/
TIM_HandleTypeDef htim2;

/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/

// 定义音符表 
#define M1  523
#define M2  587
#define M3  659
#define M4  698
#define M5  784
#define M6  880
#define M7  988
#define ST  0

// 定义歌曲 表 
const uint16_t mic[][2] =
{
   
	{
   M1,1},{
   M1,1},{
   M5,1},{
   M5,1},
	{
   M6,1},{
   M6,1},{
   M5,1},{
   ST,1},
	{
   M4,1},{
   M4,1},{
   M3,1},{
   M3,1},
	
由于蜂鸣器只能发出单一频率的声音,因此需要将歌曲转换为一系列频率的组合。以下是一个简单的代码示例,演奏小星星: ```c // 定义乐谱数组,每个元素表示一个音符的频率和持续时间 // 0表示休止符 uint16_t melody[] = { 0, 262, 262, 392, 392, 440, 440, 392, 330, 330, 294, 294, 262, 0, 392, 392, 370, 370, 349, 349, 330, 0, 392, 392, 370, 370, 349, 349, 330, 0, 262, 262, 262, 392, 392, 440, 440, 392, 330, 330, 294, 294, 262, 0, 392, 392, 370, 370, 349, 349, 330, 0, 392, 392, 370, 370, 349, 349, 330, 0, 262, 262, 392, 392, 440, 440, 392, 330, 330, 294, 294, 262, 0}; // 定义节拍数组,每个元素表示一个音符的节拍 // 4表示1拍,2表示1/2拍,3表示3/4拍,可根据需要调整 uint16_t beats[] = { 4, 4, 4, 4, 4, 4, 2, 2, 4, 4, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 4, 4, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 2, 4}; // 播放一段音符,freq为频率,duration为持续时间 void playNote(uint16_t freq, uint16_t duration) { uint32_t period = 1000000 / freq; // 计算周期,单位为微秒 uint32_t delay = period / 2; // 计算半个周期的时间,单位为微秒 uint32_t cycles = duration * freq / 1000; // 计算需要发出的周期数 for (uint32_t i = 0; i < cycles; i++) { GPIOA->ODR ^= GPIO_PIN_5; // 翻转PA5引脚电平 delay_us(delay); // 等待半个周期 } } int main(void) { HAL_Init(); // 初始化HAL库 __HAL_RCC_GPIOA_CLK_ENABLE(); // 使能GPIOA时钟 GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = GPIO_PIN_5; // 确定PA5引脚 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 设置为推挽输出模式 GPIO_InitStruct.Pull = GPIO_NOPULL; // 不使用上/下拉 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; // 设置GPIO速度 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // 初始化GPIOA for (uint16_t i = 1; i < sizeof(melody)/sizeof(melody[0]); i++) { if (melody[i] == 0) // 如果是休止符,等待相应时间 { delay_ms(beats[i]*250); } else // 否则播放音符 { playNote(melody[i], beats[i]*250); } delay_ms(50); // 在音符之间适当加一点延迟,避免音符之间太紧凑 } while (1) { // 循环播放 for (uint16_t i = 1; i < sizeof(melody)/sizeof(melody[0]); i++) { if (melody[i] == 0) { delay_ms(beats[i]*250); } else { playNote(melody[i], beats[i]*250); } delay_ms(50); } } } ``` 在该代码中,`melody`和`beats`两个数组分别表示歌曲的乐谱和节拍,每个元素的意义如代码中注释所述。`playNote()`函数用于播放一个音符,其中使用了定时器来计算半个周期的时间。在`main()`函数中,循环播放歌曲,并在每个音符之间加上适当的延迟。 需要注意的是,该代码仅为演示用途,未对定时器进行精度、范围等方面的优化,实际使用时可能需要进行一些改进。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值