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

相关推荐
Navigator_Z7 分钟前
LeetCode //C - 1203. Sort Items by Groups Respecting Dependencies
c语言·算法·leetcode
笨鸟先飞的橘猫34 分钟前
c++游戏后端开源框架学习——wukong(十、lua热更新)
c++·游戏·开源
我变成萤火虫1 小时前
2026 ICPC沈阳邀请赛Vp补题
数据结构·c++·算法·贪心算法·stl·排序算法·动态规划
神威难绷泪1 小时前
数据结构:二叉树
数据结构·二叉树
风起洛阳@不良使1 小时前
中级软考(软件攻城狮)第3章知识点——数据结构与数据运算(线性结构+非线性结构)
数据结构·算法·链表
嵌入式阿蔡1 小时前
OTA 实战四:安全启动与固件签名(Secure Boot)—— 拒绝非法固件
网络·stm32·单片机·嵌入式硬件·嵌入式实时数据库
LCMICRO-133108477461 小时前
国产长芯微LP8628完全P2P替代AD8628,零漂移、单电源、输入输出轨到轨高精度运放
arm开发·嵌入式硬件·fpga开发·硬件工程·精密运放·ad8628
索西引擎1 小时前
【数据结构】B树与B+树:结构性质、对比分析与磁盘优化机理
数据结构·b树
xx~t1 小时前
嵌入式学习22
数据结构·学习·算法·排序算法
我是苏苏1 小时前
C#基础:不写for循环的五种方式
数据结构·算法·c#