这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 【Let'sdo第3期-拾色播放器DIY】--实现蜂鸣器驱动,并播放八阶音符

共3条 1/1 1 跳转至

【Let'sdo第3期-拾色播放器DIY】--实现蜂鸣器驱动,并播放八阶音符

工程师
2025-12-16 03:44:36     打赏

简介

在本章节我们将继续下一个任务即实现蜂鸣器的驱动从而来实现八阶的音符。

image.png

本任务的主要难点在于配置PWM来生成上述频率的PWM频率即可,然后通过不同的频率组合即可播放一首完整的音乐。


首先在初始化方法中配置和定义好对应的音调信息。

def __init__(self, pin=board.A0, base_volume=0.6):
        """初始化蜂鸣器播放器"""
        self.buzzer = pwmio.PWMOut(
            pin,
            duty_cycle=0,
            frequency=440,
            variable_frequency=True
        )
        self.base_volume = base_volume
        
        # 音符频率表
        self.notes = {
            "C4": 261.63, "CS4": 277.18, "D4": 293.66, "DS4": 311.13,
            "E4": 329.63, "F4": 349.23, "FS4": 369.99, "G4": 392.00,
            "GS4": 415.30, "A4": 440.00, "AS4": 466.16, "B4": 493.88,
            "C5": 523.25, "CS5": 554.37, "D5": 587.33, "DS5": 622.25,
            "E5": 659.25, "F5": 698.46, "FS5": 739.99, "G5": 783.99,
        }


然后创建一个播放单个音调的方法

def play_tone(self, freq, duration, volume=None):
        """播放指定频率的声音"""
        if volume is None:
            volume = self.base_volume
        
        if freq > 0:
            self.buzzer.frequency = int(freq)
            self.buzzer.duty_cycle = int(volume * 65535)
        
        time.sleep(duration)
        
        if freq > 0:
            # 淡出效果
            self.buzzer.duty_cycle = int(volume * 65535 * 0.3)
            time.sleep(0.02)
        
        self.buzzer.duty_cycle = 0
        time.sleep(0.01)  # 音符间间隔

然后将多个音调组合在一起的话即可来形成一首完整的曲子。

def play_note(self, note_name, duration, volume=None):
        """播放音符(通过名称)"""
        if note_name == "R" or note_name not in self.notes:
            self.play_tone(0, duration, 0)
        else:
            self.play_tone(self.notes[note_name], duration, volume)
    
    def play_song(self, song_data, tempo=1.0):
        """播放歌曲数据"""
        for note, duration in song_data:
            self.play_note(note, duration * tempo)
    
    def beep(self, count=1, freq=1000, duration=0.1):
        """发出哔哔声(用于提示)"""
        for _ in range(count):
            self.play_tone(freq, duration, 0.8)
            time.sleep(0.05)

然后就是两层的封装方法使其调用播放的音频更加方便。 之后我们便可以按照对应的乐谱来定义对应的音乐了。我这里定义了两首音乐、分别是欢乐颂和小蜜蜂

ODE_TO_JOY = [
    ("E4", 0.5), ("E4", 0.5), ("F4", 0.5), ("G4", 0.5),
    ("G4", 0.5), ("F4", 0.5), ("E4", 0.5), ("D4", 0.5),
    ("C4", 0.5), ("C4", 0.5), ("D4", 0.5), ("E4", 0.5),
    ("E4", 0.75), ("D4", 0.25), ("D4", 1.0),

    ("E4", 0.5), ("E4", 0.5), ("F4", 0.5), ("G4", 0.5),
    ("G4", 0.5), ("F4", 0.5), ("E4", 0.5), ("D4", 0.5),
    ("C4", 0.5), ("C4", 0.5), ("D4", 0.5), ("E4", 0.5),
    ("D4", 0.75), ("C4", 0.25), ("C4", 1.0),
]

BEEHIVE = [
    ("E4", 0.2), ("F4", 0.2), ("G4", 0.2), ("E4", 0.2),
    ("F4", 0.2), ("G4", 0.2), ("G4", 0.3), ("A4", 0.3),
    ("G4", 0.2), ("F4", 0.2), ("E4", 0.2), ("D4", 0.2),
    ("C4", 0.5), ("C4", 0.2), ("D4", 0.2), ("E4", 0.2),
    ("F4", 0.2), ("E4", 0.2), ("D4", 0.2), ("C4", 0.2),
]

之后来进行播放即可

# ------------------- 初始化播放器 -------------------

player = BuzzerPlayer(board.A0, base_volume=0.7)

print("音乐播放器启动...")
player.beep(2, 1000, 0.1)
time.sleep(0.5)

# ------------------- 主循环播放 -------------------

try:
    while True:
        print("播放: 欢乐颂")
        player.play_song(ODE_TO_JOY, tempo=0.9)
        time.sleep(1)

        print("播放: 小蜜蜂")
        player.play_song(BEEHIVE, tempo=1.0)
        time.sleep(1)

except KeyboardInterrupt:
    player.buzzer.duty_cycle = 0
    print("\n程序结束")

不过讲真的这个D掉真的有点难听


效果如下

image.png

接线连接图(单片机的A0连接蜂鸣器的+

image.png




关键词: 拾色播放器     pwm     蜂鸣器    

专家
2025-12-16 07:40:17     打赏
2楼

谢谢分享


菜鸟
2025-12-16 13:18:36     打赏
3楼

不错,很细致


共3条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]