单片机蜂鸣器代码

本文介绍使用51单片机控制蜂鸣器发声的基本原理及代码实现,通过改变脉冲频率控制音调,演示了如何播放《两只老虎》等歌曲,涉及定时器设置与中断处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我用的蜂鸣器固定的控制端口是P1.5这个端口
蜂鸣器必须通过脉冲来实现发声

在这里插入图片描述

//最简单的蜂鸣器发声代码:
#include<reg52.h>
#include<intrins.h>
sbit beep=P1^5;
typedef unsigned int u16;
typedef unsigned char u8;

void delay(u16 i)
{
	while(i--);
}
void main()
{
	while(1)
	{
		 beep=~beep;//变化来实现一个脉冲
		 delay(100);//延迟程序来控制脉冲的频率,以达到不同的声音
	}	
} 

用蜂鸣器来播放一首歌曲《两只老虎》:

#include <reg52.h>
#define RldTmr(fr) 65536 - (11059200 / 12) / (fr << 1)
#define FuDian(n) (n << 1) / 3    //附点n分音符的换算
 
typedef unsigned char UCHAR;
typedef unsigned int UINT;
typedef unsigned long ULONG;
 
sbit BUZZ = P1^5;
 
UINT code noteFreq[] = {    //中音 1-7 和高音 1-7对应的频率列表
    523, 587, 659, 698, 784, 880, 988,
    1047, 1175, 1319, 1397, 1568, 1760, 1976
};
UINT code tmrRld[] = {      //中音 1-7 和高音 1-7对应的定时器重载值
    RldTmr(523), RldTmr(587), RldTmr(659), RldTmr(698), RldTmr(784), RldTmr(880), RldTmr(988),
    RldTmr(1047), RldTmr(1175), RldTmr(1319), RldTmr(1397), RldTmr(1568), RldTmr(1760), RldTmr(1976),
};
UCHAR code musicNote[] = {      //音名
    1, 2, 3, 1,
    1, 2, 3, 1,
    3, 4, 5,
    3, 4, 5,
    5, 6, 5, 4, 3, 1,
    5, 6, 5, 4, 3, 1,
    1, 5, 1,
    1, 5, 1
};
UCHAR code noteDuration[] = {       //音名对应的时值,4表示4分音符,8表示8分音符,16表示16分音符
    4, 4, 4, 4,
    4, 4, 4, 4,
    4, 4, 2,
    4, 4, 2,
    FuDian(8), 16, FuDian(8), 16, 4, 4,
    FuDian(8), 16, FuDian(8), 16, 4, 4,
    4, 4, 2,
    4, 4, 2
};
bit enable = 1, tmrFlg = 0;
UCHAR T0RH = 0XFF, T0RL = 0X00;
 
void Delay(UINT n);
void PlayMusic(UCHAR speed);    //固定标准为4分音符的速度:例如speed = 108 表示一分钟扫过108个4分音符
 
void main() {
    EA = 1;
    TMOD = 0X01;
    TH0 = T0RH;
    TL0 = T0RL;
    ET0 = 1;
    TR0 = 1;
    while (1) {
        PlayMusic(72);
        Delay(40000u);
    }
}
 
void Delay(UINT n) {
    UINT i;
    for (i = 0; i < n; i++) ;
}
 
void PlayMusic(UCHAR speed) {
    UCHAR i;
    UCHAR idx;
    UINT cnt = 0;
    UINT durationCnt = 0;	//当前音符的时值对应的定时器计数
    UINT soundCnt = 0;		//当前音符的发声时值对应的计数值
    for (i = 0; i < sizeof (musicNote); ) {
        while (!tmrFlg) ;
        tmrFlg = 0;
        if (cnt == 0) {
            idx = musicNote[i] - 1;
            T0RH = tmrRld[idx] >> 8;
            T0RL = tmrRld[idx];
            durationCnt = (ULONG)240 * (ULONG)noteFreq[idx] / ((ULONG)noteDuration[i] * (ULONG)speed);
            soundCnt = durationCnt - (durationCnt >> 2);	//当前音符时值的前3/4发声,后1/4静音
            enable = 1;
            cnt++;
        }
        else {
            if (cnt == durationCnt) {
                cnt = 0;
                i++;
            }
            else {
                cnt++;
                if (cnt == soundCnt) {
                    enable = 0;
                }
            }
        }
    }
}
 
void InterruptTmr0() interrupt 1 {
    TH0 = T0RH;
    TL0 = T0RL;
    tmrFlg = 1;
    if (enable)
        BUZZ = ~BUZZ;
    else
        BUZZ = 1;
}

上面这段代码的原码 点击这里访问

<think>嗯,用户需要的是适用于51单片机控制蜂鸣器代码示例,而且要用Keil开发环境。首先,我得回想一下51单片机的基本知识,特别是关于蜂鸣器的控制部分。蜂鸣器通常分为有源和无源两种,无源的需要通过方波驱动,所以可能需要定时器来生成不同频率的波形。用户提到的示例代码应该要展示如何通过定时器中断来产生不同频率的声音,从而播放音乐,比如《天空之城》。 然后,我需要考虑代码的结构。通常,51单片机的程序会包括头文件、管脚定义、定时器初始化、中断服务函数以及主函数。用户可能需要一个完整的示例,所以我得确保代码的正确性和可运行性。比如,使用P2^5作为蜂鸣器的控制引脚,定时器0来生成频率,定时器1来控制音符的持续时间。 接下来,代码里需要定义音符对应的频率,比如中音C的频率是523Hz,然后根据这些频率计算定时器的重装值。同时,音符的节拍需要转换成延时的时间,这可能需要一个节拍索引数组,每个元素表示该音符持续多少个时间单位。在中断服务函数里,切换蜂鸣器的状态以产生方波,同时计数节拍时间。 另外,用户提到了Keil开发环境,所以需要说明如何在Keil中配置项目,包括选择正确的单片机型号,设置生成HEX文件等步骤。可能还需要提到如何将代码下载到单片机,比如使用STC-ISP工具。 然后,检查是否有相关的引用资料。用户提供的引用[1]是关于C51单片机播放《天空之城》的示例代码,这个资源可能包含具体的实现细节,可以作为参考。引用[2]提到了51单片机的学习步骤和开发环境配置,需要确认Keil和STC-ISP的配置是否正确。 用户可能还需要知道如何调整代码以适应不同的硬件连接,比如如果蜂鸣器接在其他的IO口上,需要修改管脚定义。同时,可能的问题包括如何添加更多的歌曲,或者如何优化代码以减少资源占用。 最后,生成相关问题的时候,要围绕代码实现、硬件连接、定时器配置、音调调整以及扩展功能来提问,这样可以帮助用户进一步理解和应用示例代码。</think>根据您的需求,我为您整理一个基于51单片机蜂鸣器控制示例代码(Keil开发环境),并附详细说明: ### 51单片机蜂鸣器控制示例 ```c #include <REG52.H> #include <INTRINS.H> #define uchar unsigned char #define uint unsigned int sbit BEEP = P2^5; // 蜂鸣器连接P2.5口 // 音符频率表(中音区) uint code FreqTab[] = { 0, // 休止符 523,587,659,698,784,880,988,1046 // C4,B4,D5,E5,F5,G5,A5,B5 }; //《天空之城》简谱片段 uchar code Music[] = { 1,1,5,5,6,6,5,4,4,3,3,2,2,1, // 音符 2,2,4,4,5,5,4,3,3,2,2,1 // 节拍索引 }; uint FreqVal; // 当前频率值 void Timer0Init() { TMOD |= 0x01; // 定时器0模式1 TH0 = FreqVal >> 8; TL0 = FreqVal; ET0 = 1; // 开启定时器0中断 TR0 = 1; // 启动定时器0 EA = 1; // 开启总中断 } void main() { uchar i; uint beatCount; while(1) { for(i=0; i<sizeof(Music)/2; i++) { FreqVal = 65536 - (11059200/12)/(2*FreqTab[Music[i]]); beatCount = Music[i + sizeof(Music)/2] * 200; Timer0Init(); while(beatCount--); TR0 = 0; // 停止定时器 } } } void Timer0_ISR() interrupt 1 { TH0 = FreqVal >> 8; TL0 = FreqVal; BEEP = !BEEP; // 翻转电平产生方波 } ``` ### 开发环境配置(Keil uVision) 1. 新建工程选择`STC89C52`芯片 2. 设置输出勾选`Create HEX File` 3. 复制上述代码到main.c文件 4. 通过STC-ISP工具烧录程序到单片机 ### 硬件连接说明 - 蜂鸣器正极接P2.5 - 蜂鸣器负极接GND - 使用11.0592MHz晶振[^2]
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值