stm32蜂鸣器音乐代码
时间: 2023-08-31 22:10:27 浏览: 36
以下是一个简单的 STM32 蜂鸣器音乐代码示例,使用了 TIM2 定时器和 GPIO 口驱动蜂鸣器。需要注意的是,这个代码只适用于 STM32F1 系列芯片。
```c
#include "stm32f10x.h"
// 音符频率表,以 C4 为基准
uint16_t note_freq[] = {
262, 277, 294, 311, 330, 349, 370, 392, 415, 440, 466, 494,
523, 554, 587, 622, 659, 698, 740, 784, 831, 880, 932, 988
};
// 节拍表,单位为毫秒
uint16_t note_time[] = {
500, 250, 250, 500, 500, 500, 250, 250, 500, 250, 250, 500,
500, 250, 250, 500, 500, 500, 250, 250, 500, 250, 250, 500
};
// 当前播放的音符和节拍
uint8_t current_note = 0;
uint16_t current_time = 0;
// 定时器初始化
void TIM2_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
// 使能 TIM2 和 GPIOA 时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// 配置 TIM2 基本参数
TIM_TimeBaseInitStruct.TIM_Prescaler = 7200 - 1; // 分频系数,72MHz / 7200 = 10kHz
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数模式
TIM_TimeBaseInitStruct.TIM_Period = 1000 - 1; // 自动重载值,10kHz / 1000 = 10Hz
TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);
// 配置 NVIC 中断优先级
NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
// 使能 TIM2 更新中断
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
// 配置 GPIOA.0 为推挽输出模式
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStruct);
}
// 播放下一个音符
void play_next_note(void)
{
if (current_note >= sizeof(note_freq) / sizeof(note_freq[0])) {
// 播放完毕,停止定时器
TIM_Cmd(TIM2, DISABLE);
} else {
// 设置蜂鸣器频率和持续时间
TIM_SetAutoreload(TIM2, note_freq[current_note] - 1);
current_time = note_time[current_note];
current_note++;
}
}
int main(void)
{
TIM2_Init();
TIM_Cmd(TIM2, ENABLE);
while (1);
}
// 定时器更新中断处理函数
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) {
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
// 持续时间减少
if (current_time > 0) {
current_time--;
}
// 持续时间结束,播放下一个音符
if (current_time == 0) {
GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET);
play_next_note();
}
// 持续时间一半时关闭蜂鸣器
if (current_time == note_time[current_note - 1] / 2) {
GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_RESET);
}
}
}
```
这个代码示例播放了一个简单的旋律,可以通过修改 `note_freq` 和 `note_time` 数组来播放不同的音乐。在 `play_next_note` 函数中,当播放完毕时,停止定时器以停止蜂鸣器。