stm32hal库蜂鸣器唱歌
时间: 2025-06-03 16:19:47 浏览: 15
### 使用STM32 HAL库实现蜂鸣器播放音乐的功能
以下是一个完整的示例代码,展示如何使用STM32 HAL库控制蜂鸣器播放歌曲。代码分为初始化模块、蜂鸣器控制模块和主函数模块。
#### 初始化模块
在初始化模块中,配置GPIO引脚和定时器以生成PWM信号。
```c
#include "stm32f1xx_hal.h"
// 定义定时器句柄
TIM_HandleTypeDef htim1;
// 初始化GPIO和TIM
void Buzzer_Init(void) {
__HAL_RCC_GPIOA_CLK_ENABLE(); // 使能GPIOA时钟
__HAL_RCC_TIM1_CLK_ENABLE(); // 使能TIM1时钟
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_8; // PA8作为PWM输出引脚
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
htim1.Instance = TIM1;
htim1.Init.Prescaler = (SystemCoreClock / 2000000) - 1; // 设置预分频器为2MHz
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 1000 - 1; // 初始周期值
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
HAL_TIM_PWM_Init(&htim1);
TIM_OC_InitTypeDef sConfigOC = {0};
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 500; // 初始占空比50%
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1);
}
```
#### 蜂鸣器控制模块
定义一个函数来控制蜂鸣器发声,输入参数为频率和持续时间。
```c
// 蜂鸣器发声函数
void Buzzer_Beep(uint16_t frequency, uint16_t duration) {
if (frequency == 0) { // 如果频率为0,则停止发声
HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);
HAL_Delay(duration);
return;
}
uint16_t period = (uint16_t)(SystemCoreClock / frequency / 2); // 计算并设置定时器周期和占空比
__HAL_TIM_SET_AUTORELOAD(&htim1, period - 1);
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, period / 2);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); // 开启定时器
HAL_Delay(duration); // 延时一段时间
HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1); // 关闭定时器
}
```
#### 主函数模块
在主函数中,定义音符频率和持续时间数组,并调用`Buzzer_Beep`函数播放歌曲。
```c
int main(void) {
HAL_Init(); // 初始化HAL库
Buzzer_Init(); // 初始化蜂鸣器
// 定义音符频率(Hz)
uint16_t note_freq[] = {262, 294, 330, 349, 392, 440, 494, 523}; // C4, D4, E4, F4, G4, A4, B4, C5
// 定义音符持续时间(ms)
uint16_t note_duration[] = {500, 500, 500, 500, 500, 500, 500, 1000};
while (1) {
for (int i = 0; i < sizeof(note_freq) / sizeof(note_freq[0]); i++) {
Buzzer_Beep(note_freq[i], note_duration[i]); // 播放音符
HAL_Delay(100); // 音符间隔
}
}
}
```
### 注意事项
- 确保GPIO引脚和定时器配置正确[^1]。
- 频率计算公式基于系统时钟频率,需根据实际硬件调整[^2]。
- 在播放音符时,适当添加延时以避免音符之间的干扰[^3]。
```c
// 示例:播放一首简单的曲子
void play_song(void) {
uint16_t song_freq[] = {262, 294, 330, 349, 392, 440, 494, 523}; // C4到C5
uint16_t song_duration[] = {500, 500, 500, 500, 500, 500, 500, 1000};
for (int i = 0; i < sizeof(song_freq) / sizeof(song_freq[0]); i++) {
Buzzer_Beep(song_freq[i], song_duration[i]);
HAL_Delay(100);
}
}
```
阅读全文
相关推荐














