问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

STM32-PWM驱动无源蜂鸣器播放周杰伦的《发如雪》

创作时间:
作者:
@小白创作中心

STM32-PWM驱动无源蜂鸣器播放周杰伦的《发如雪》

引用
CSDN
1.
https://blog.csdn.net/weixin_45651178/article/details/146080287

本文将介绍如何使用STM32微控制器驱动无源蜂鸣器播放周杰伦的《发如雪》。文章将详细讲解音符频率对照表、GPIO和TIM初始化、音乐模块以及主函数的实现。

C调音符与频率对照表

// 音符频率对照表(单位:Hz)
#define L1     262    // 低音1
#define L1_    277
#define L2     294
#define L2_    311
#define L3     300
#define L4     349
#define L4_    370
#define L5     392
#define L5_    415
#define L6     440
#define L6_    466
#define L7     494
#define N1     523    // 中音1
#define N1_    554
#define N2     587
#define N2_    622
#define N3     659
#define N4     698
#define N4_    740
#define N5     784
#define N5_    831
#define N6     880
#define N6_    932
#define N7     988
#define H1     1046    // 高音1
#define H1_    1109
#define H2     1175
#define H2_    1245
#define H3     1318
#define H4     1397
#define H4_    1480
#define H5     1568
#define H5_    1661
#define H6     1760
#define H6_    1865
#define H7     1976
#define END    0      // 结束标志

GPIO和TIM初始化

#include "stm32f10x.h"                  // Device header

void RCC_Configuration(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
}

void GPIO_Configuration(void)
{
    // 初始化GPIO
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}

void TIM_Configuration(uint16_t freq)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    TIM_OCInitTypeDef TIM_OCInitStructure;

    uint16_t prescaler = 72;  // 72MHz/72 = 1MHz
    uint16_t period = (freq == 0) ? 0 : (1000000 / freq);

    TIM_InternalClockConfig(TIM2);

    // 初始化时基单元
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInitStructure.TIM_Period = period - 1;
    TIM_TimeBaseInitStructure.TIM_Prescaler = prescaler - 1;
    TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);

    // 初始化PWM
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = period / 2;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OC1Init(TIM2, &TIM_OCInitStructure);

    TIM_Cmd(TIM2, ENABLE);
}

音乐模块

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "BUZZER.h"

// 音符频率对照表(单位:Hz)
#define L1     262    // 低音1
#define L1_    277
#define L2     294
#define L2_    311
#define L3     300
#define L4     349
#define L4_    370
#define L5     392
#define L5_    415
#define L6     440
#define L6_    466
#define L7     494
#define N1     523    // 中音1
#define N1_    554
#define N2     587
#define N2_    622
#define N3     659
#define N4     698
#define N4_    740
#define N5     784
#define N5_    831
#define N6     880
#define N6_    932
#define N7     988
#define H1     1046    // 高音1
#define H1_    1109
#define H2     1175
#define H2_    1245
#define H3     1318
#define H4     1397
#define H4_    1480
#define H5     1568
#define H5_    1661
#define H6     1760
#define H6_    1865
#define H7     1976
#define END    0      // 结束标志

#define BPM 90                       // 整体节奏控制
#define BEAT_DURATION (60000/BPM)    // 四分音符基准时长

// 节拍类型重定义
typedef enum {
    T1_16 = BEAT_DURATION/4,    // 十六分音符
    T1_8  = BEAT_DURATION/2,    // 八分音符
    T3_8  = BEAT_DURATION*3/4,  // 附点八分音符
    T1_4  = BEAT_DURATION,      // 四分音符
    T1_2  = BEAT_DURATION*2,    // 二分音符
    T1    = BEAT_DURATION*4     // 全音符
} NoteDuration;

// 乐曲数据结构
typedef struct {
    uint16_t freq;      // 频率
    uint16_t duration;  // 持续时间(ms)
} Note;

const Note Music[] = {
    // 前奏
    {N5, T1_4}, {N6, T1_8}, {H1, T1_8}, {N6, T1_4}, {N5, T1_4}, {N3, T1_4},
    {N5, T1_4}, {N6, T1_8}, {H1, T1_8}, {N6, T1_4}, {N5, T1_4}, {N3, T1_4},
    // 主歌A段
    {N5, T3_8}, {N5, T1_8}, {N6, T1_4}, {N5, T1_4}, {N3, T1_4}, // 狼牙月 伊人憔悴
    {N5, T3_8}, {N5, T1_8}, {N6, T1_4}, {N5, T1_4}, {N3, T1_4}, // 我举杯 饮尽了风雪
    {N2, T1_8}, {N3, T1_8}, {N5, T1_4}, {N3, T1_4}, {N2, T1_4},  // 是谁打翻前世柜
    {L6, T1_8}, {N1, T1_8}, {N2, T1_4}, {N3, T1_4}, {N2, T1_4},  // 惹尘埃是非
    // 副歌B段
    {N5, T1_2}, {N5, T1_8}, {N6, T1_8}, {N5, T1_4}, {N3, T1_4},  // 你发如雪 凄美了离别
    {N5, T1_2}, {N5, T1_8}, {N6, T1_8}, {N5, T1_4}, {N3, T1_4},  // 我焚香感动了谁
    {N2, T1_8}, {N3, T1_8}, {N5, T1_4}, {N3, T1_4}, {N2, T1_4},  // 邀明月 让回忆皎洁
    {L6, T1_8}, {N1, T1_8}, {N2, T1_4}, {N3, T1_4}, {N2, T1_4},  // 爱在月光下完美
    // 间奏(钢琴solo简化)
    {N5, T1_8}, {N6, T1_8}, {H1, T1_8}, {N6, T1_8}, {N5, T1_8}, {N3, T1_8}, {N5, T1_4},
    {N5, T1_8}, {N6, T1_8}, {H1, T1_8}, {N6, T1_8}, {N5, T1_8}, {N3, T1_8}, {N5, T1_4},
    // 主歌A'段
    {N5, T3_8}, {N5, T1_8}, {N6, T1_4}, {N5, T1_4}, {N3, T1_4}, // 啦儿啦 铜镜映无邪
    {N5, T3_8}, {N5, T1_8}, {N6, T1_4}, {N5, T1_4}, {N3, T1_4}, // 扎马尾 你若撒野
    {N2, T1_8}, {N3, T1_8}, {N5, T1_4}, {N3, T1_4}, {N2, T1_4},  // 今生我把酒奉陪
    {0, T1_4}, {L6, T1_8}, {N1, T1_8}, {N2, T1_4}, {N3, T1_4},   // 休止+尾奏衔接
    // 尾声
    {N2, T1_2}, {N3, T1_4}, {N5, T1_4}, {N3, T1_4}, {N2, T1_2},
    {H1, T1_2}, {N6, T1_2}, {N5, T1_2}, {END, 0}  // 结束句
};

void Play_Music(void)
{
    uint16_t i = 0;
    while (1)
    {
        if (Music[i].freq == END) break;

        if (Music[i].freq == 0)
        {
            TIM_Cmd(TIM2, DISABLE);
        }
        else
        {
            TIM_Configuration(Music[i].freq);
            TIM_Cmd(TIM2, ENABLE);
        }
        Delay_ms(Music[i].duration);
        i++;
    }
    TIM_Cmd(TIM2, DISABLE);
}

主函数

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "BUZZER.h"
#include "MUSIC.h"
#include "KEY.h"

uint8_t KeyNum;

int main(void)
{
    KEY_Init();
    OLED_Init();
    RCC_Configuration();
    GPIO_Configuration();

    while (1)
    {
        Play_Music();
    }
}
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号