【51单片机】从 0 到 1 玩转 51 蜂鸣器:分清有源无源,轻松驱动它奏响新年旋律

🔥小龙报:个人主页

🎬作者简介:C++研发,嵌入式,机器人方向学习者

❄️个人专栏:《工科必装软件安装教程》《嵌入式的开端 ---- 51单片机》
✨ 永远相信美好的事情即将发生

文章目录


前言

蜂鸣器是嵌入式设备中最基础的音频输出器件,广泛应用于各类电子设备的提示音、报警音场景。本文从蜂鸣器的核心原理入手,区分有源与无源蜂鸣器的差异,结合 51 单片机实操,先通过简单代码实现基础发声测试,再深入讲解定时器中断驱动的音乐演奏逻辑,完整实现《Happy New Year》的播放,帮助初学者吃透蜂鸣器的驱动与音频控制核心。

一、应用场景

大部分的电子产品、家电(风扇、空调、电水壶)都会有蜂鸣器,用于提示设备的工作状态

二、原理

蜂鸣器是一种将电信号转换为声音信号的器件,常用来产生设备的按键音、报警音等提示信号。​
蜂鸣器按驱动方式可分为有源蜂鸣器和无源蜂鸣器​

有源蜂鸣器 :内部自带振荡源,将正负极接上直流电压即可持续发声,频率固定。​
无源蜂鸣器:内部不带振荡源,需要控制器提供振荡脉冲才可发声,调整提供振荡脉冲的频率,可发出不同频率的声音。​

注意: 蜂鸣器有正负极,顶部印有+号的为正极,若蜂鸣器引脚没剪,则长的为正极。

三、接线图

四、代码实现

4.1 测试代码

csharp 复制代码
#include<reg52.h>

sbit speak=P2^1;

//带参延时函数
void delay_ms(unsigned int xms)   //@12MHz
{
    unsigned int i, j;
    for(i=xms;i>0;i--)
    {
        for(j=124;j>0;j--)
        {}
    }
}

void main()
{
   while(1){
   speak=1;
   delay_ms(1);
   speak=0;
   delay_ms(1); 
   }
}

4.2 音乐演奏(Happy New Year)

csharp 复制代码
#include <reg52.h>

#define uchar unsigned char
sbit speak = P2 ^ 1;
bit flag = 0; // 标志音乐输出脚电平的高低
uchar ptr = 0x00;
uchar high;
uchar low;

uchar code music[] = {
    0xfc, 0x44, 0x7f, 0xfc, 0x44, 0x7f, 0xfc, 0x44, 0xff, 0xfa, 0x68, 0xff,
    0xfd, 0x23, 0x7f, 0xfd, 0x23, 0x7f, 0xfd, 0x23, 0xff, 0xfc, 0x44, 0xff,
    0xfc, 0x44, 0x7f, 0xfd, 0x23, 0x7f, 0xfd, 0x82, 0xff, 0xfd, 0x82, 0xff,
    0xfd, 0x23, 0x7f, 0xfd, 0x23, 0x7f, 0xfc, 0xac, 0xff, 0xff, 0xff, 0xff,
    0xfc, 0xac, 0x7f, 0xfd, 0x23, 0x7f, 0xfd, 0x34, 0xff, 0xfd, 0x34, 0xff,
    0xfd, 0x23, 0x7f, 0xfc, 0xac, 0x7f, 0xfd, 0x23, 0xff, 0xfc, 0x44, 0xff,
    0xfc, 0x44, 0x7f, 0xfd, 0x23, 0x7f, 0xfc, 0xac, 0xff, 0xfa, 0x68, 0xff,
    0xfc, 0x0c, 0x7f, 0xfc, 0xac, 0x7f, 0xfc, 0x44, 0xff, 0xff, 0xff, 0xff,
    0x00}; // happy new year 歌曲

// 带参延时函数
void delay_ms(unsigned int xms) //@12MHz
{
    unsigned int i, j;
    for (i = xms; i > 0; i--)
    {
        for (j = 124; j > 0; j--)
        {
        }
    }
}

void Count1(void) interrupt 1
{
    TH0 = high;
    TL0 = low;
    if (flag == 0)
    {
        speak = 0;
        flag = 1;
    }
    else
    {
        speak = 1;
        flag = 0;
    }
}

void Init()
{
    TMOD = 0x01;
    EA = 1;
    ET0 = 1;
}

void main()
{
    uchar time;
    Init();
    TH0 = high;
    TL0 = low;
    while (1)
    {
        if (music[ptr] != 0xff && music[ptr] != 0x00)
        {
            TR0 = 0;
            speak = 1;
            delay_ms(10);
            high = music[ptr];
            low = music[ptr + 1];
            time = music[ptr + 2];
            TR0 = 1;
            delay_ms(time);
            ptr += 3;
        }
        else if (music[ptr] == 0xff)
        {
            time = music[ptr + 2];
            delay_ms(time);
            ptr += 3;
        }
        else
        {
            TR0 = 0;
            speak = 1;
            delay_ms(2000);
            ptr = 0;
        }
    }
}

总结与每日励志

✨本文从蜂鸣器原理、接线到代码实现,完整覆盖了 51 单片机驱动蜂鸣器的核心方法:从简单延时翻转电平发声,到定时器中断动态调整频率实现音乐播放,层层递进拆解音频控制逻辑。嵌入式学习没有捷径,每一行代码的调试、每一个音调的校准,都是技术积累的过程。✨保持耐心,深耕细节,小小的蜂鸣器也能奏响你嵌入式之路的精彩乐章!

相关推荐
不会就选b31 分钟前
C++补充部分(一)--lambda 表达式
开发语言·c++
LCG米3 小时前
STM32串口接收卡死根因排查:ORE溢出标志陷阱、错误标志清除顺序与中断恢复实测
stm32·单片机·嵌入式硬件·串口·嵌入式
创界工坊工作室5 小时前
38-基于单片机的老人健康监测系统
单片机·嵌入式硬件·51单片机·proteus
quaer7 小时前
弗洛伊德算法--判圈法寻找环的入口O(n) O(1)
数据结构·算法
三佛科技-134163842127 小时前
20W~200W副边反馈SSR隔离方案HN1562+碳化硅MOS(含光耦817,431)
单片机·嵌入式硬件·物联网·智能家居·pcb工艺
丰色木夕8 小时前
Ubuntu22.04下源码编译安装USD-Brep
c++·ubuntu·nvidia·usd-brep
恒锐丰科技林技术员8 小时前
EG2103 高压 MOS/IGBT 驱动芯片解析:半桥驱动的高性价比之选
经验分享·嵌入式硬件·硬件工程
鱼很腾apoc10 小时前
【MySQL】第4期 用户管理与 C 语言连接编程详解
linux·服务器·c语言·mysql·connector/c
_Ningye10 小时前
STM32 — 11.5 硬件SPI读写W25Q64
stm32·单片机·嵌入式硬件
xys_67811 小时前
深挖数据结构:树和二叉树(上)
数据结构·算法