51单片机中的蜂鸣器

一.蜂鸣器的相关概念

34f6bc33c6b74cf5829ef6dbf35948ac.png

 蜂鸣器的驱动电路bb21d30c845f42678551855bc487d2fd.png

 蜂鸣器引脚相应原理图72b0c66e33de4046a602bb17e0a919ff.png

 a138afeb887e4f15aa4302430c9cad08.png

 二.蜂鸣器的种类

蜂鸣器分为有源蜂鸣器和无源蜂鸣器。有源蜂鸣器和无源蜂鸣器的区别:这里的“源”不是指电源。而是指震荡源。 也就是说,有源蜂鸣器内部带震荡源,所以只要一通电就会叫。 而无源内部不带震荡源,所以如果用直流信号无法令其鸣叫。必须用2K~5K的方波去驱动它。 有源蜂鸣器往往比无源的贵,就是因为里面含有震荡电路。

三.相应代码

1.蜂鸣器播放提示音

此现象为按下独立按键数码管会出现对应数字及蜂鸣器会发出声响

(1).Buzzer.c

#include <REGX52.H>
#include <INTRINS.H>

//蜂鸣器端口:
sbit Buzzer=P1^5;

/**
  * @brief  蜂鸣器私有延时函数,延时500us
  * @param  无
  * @retval 无
  */
void Buzzer_Delay500us()		//@12.000MHz
{
	unsigned char i;

	_nop_();
	i = 247;
	while (--i);
}

/**
  * @brief  蜂鸣器发声
  * @param  ms 发声的时长,范围:0~32767
  * @retval 无
  */
void Buzzer_Time(unsigned int ms)
{
	unsigned int i;//i为翻转次数
	for(i=0;i<ms*2;i++)//for循环为0.5ms 而延时为整ms,所以需乘2
	{
		Buzzer=!Buzzer;//翻转并延长一段时间
		Buzzer_Delay500us();
	}
}

(2).Buzzer.h

#ifndef __BUZZER_H__
#define __BUZZER_H__

void Buzzer_Time(unsigned int ms);

#endif

(3)main.c

#include <REGX52.H>
#include "Delay.h"
#include "Key.h"
#include "Nixie.h"
#include "Buzzer.h"

unsigned char KeyNum;

void main()
{
	Nixie(1,0);
	while(1)
	{
		KeyNum=Key();
		if(KeyNum)
		{
			Buzzer_Time(100);//蜂鸣器发声时长为100ms
			Nixie(1,KeyNum);
		}
	}
}

2.蜂鸣器播放音乐

代码烧录后蜂鸣器会播放音乐 这里选用的音乐是天空之城

#include <REGX52.H>
#include "Delay.h"
#include "Timer0.h"

//蜂鸣器端口定义
sbit Buzzer=P1^5;

//播放速度,值为四分音符的时长(ms)
#define SPEED	500

//音符与索引对应表,P:休止符,L:低音,M:中音,H:高音,下划线:升半音符号#
#define P	0
#define L1	1
#define L1_	2
#define L2	3
#define L2_	4
#define L3	5
#define L4	6
#define L4_	7
#define L5	8
#define L5_	9
#define L6	10
#define L6_	11
#define L7	12
#define M1	13
#define M1_	14
#define M2	15
#define M2_	16
#define M3	17
#define M4	18
#define M4_	19
#define M5	20
#define M5_	21
#define M6	22
#define M6_	23
#define M7	24
#define H1	25
#define H1_	26
#define H2	27
#define H2_	28
#define H3	29
#define H4	30
#define H4_	31
#define H5	32
#define H5_	33
#define H6	34
#define H6_	35
#define H7	36

//索引与频率对照表
unsigned int FreqTable[]={
	0,
	63628,63731,63835,63928,64021,64103,64185,64260,64331,64400,64463,64528,
	64580,64633,64684,64732,64777,64820,64860,64898,64934,64968,65000,65030,
	65058,65085,65110,65134,65157,65178,65198,65217,65235,65252,65268,65283,
};

//乐谱
unsigned char code Music[]={
	//音符,时值(这里加code是将此部分存入单片机中的ROM 因为RAM部分只有512个字节)
	
	//1
	P,	4,
	P,	4,
	P,	4,
	M6,	2,
	M7,	2,
	
	H1,	4+2,
	M7,	2,
	H1,	4,
	H3,	4,
	
	M7,	4+4+4,
	M3,	2,
	M3,	2,
	
	//2
	M6,	4+2,
	M5,	2,
	M6, 4,
	H1,	4,
	
	M5,	4+4+4,
	M3,	4,
	
	M4,	4+2,
	M3,	2,
	M4,	4,
	H1,	4,
	
	//3
	M3,	4+4,
	P,	2,
	H1,	2,
	H1,	2,
	H1,	2,
	
	M7,	4+2,
	M4_,2,
	M4_,4,
	M7,	4,
	
	M7,	8,
	P,	4,
	M6,	2,
	M7,	2,
	
	//4
	H1,	4+2,
	M7,	2,
	H1,	4,
	H3,	4,
	
	M7,	4+4+4,
	M3,	2,
	M3,	2,
	
	M6,	4+2,
	M5,	2,
	M6, 4,
	H1,	4,
	
	//5
	M5,	4+4+4,
	M2,	2,
	M3,	2,
	
	M4,	4,
	H1,	2,
	M7,	2+2,
	H1,	2+4,
	
	H2,	2,
	H2,	2,
	H3,	2,
	H1,	2+4+4,
	
	//6
	H1,	2,
	M7,	2,
	M6,	2,
	M6,	2,
	M7,	4,
	M5_,4,
	
	
	M6,	4+4+4,
	H1,	2,
	H2,	2,
	
	H3,	4+2,
	H2,	2,
	H3,	4,
	H5,	4,
	
	//7
	H2,	4+4+4,
	M5,	2,
	M5,	2,
	
	H1,	4+2,
	M7,	2,
	H1,	4,
	H3,	4,
	
	H3,	4+4+4+4,
	
	//8
	M6,	2,
	M7,	2,
	H1,	4,
	M7,	4,
	H2,	2,
	H2,	2,
	
	H1,	4+2,
	M5,	2+4+4,
	
	H4,	4,
	H3,	4,
	H3,	4,
	H1,	4,
	
	//9
	H3,	4+4+4,
	H3,	4,
	
	H6,	4+4,
	H5,	4,
	H5,	4,
	
	H3,	2,
	H2,	2,
	H1,	4+4,
	P,	2,
	H1,	2,
	
	//10
	H2,	4,
	H1,	2,
	H2,	2,
	H2,	4,
	H5,	4,
	
	H3,	4+4+4,
	H3,	4,
	
	H6,	4+4,
	H5,	4+4,
	
	//11
	H3,	2,
	H2,	2,
	H1,	4+4,
	P,	2,
	H1,	2,
	
	H2,	4,
	H1,	2,
	H2,	2+4,
	M7,	4,
	
	M6,	4+4+4,
	P,	4,
	
	0xFF	//终止标志
};

unsigned char FreqSelect,MusicSelect;

void main()
{
	Timer0Init();
	while(1)
	{
		if(Music[MusicSelect]!=0xFF)	//如果不是停止标志位
		{
			FreqSelect=Music[MusicSelect];	//选择音符对应的频率
			MusicSelect++;
			Delay(SPEED/4*Music[MusicSelect]);	//选择音符对应的时值
			MusicSelect++;
			TR0=0;
			Delay(5);	//音符间短暂停顿
			TR0=1;
		}
		else	//如果是停止标志位
		{
			TR0=0;//关闭定时器
			while(1);
		}
	}
}

void Timer0_Routine() interrupt 1
{
	if(FreqTable[FreqSelect])	//如果不是休止符
	{
		/*取对应频率值的重装载值到定时器*/
		TL0 = FreqTable[FreqSelect]%256;		//设置定时初值
		TH0 = FreqTable[FreqSelect]/256;		//设置定时初值
		Buzzer=!Buzzer;	//翻转蜂鸣器IO口
	}
}

 

 

<think>好的,我需要解释STC89C51单片机蜂鸣器的工作原理。首先,用户可能对单片机如何控制蜂鸣器不太了解,所以得从基础开始讲。 蜂鸣器分有源和无源两种,必须区分清楚,这点很重要。有源和无源的工作方式不同,驱动方法也不同。用户可能不知道两者的区别,需要明确说明。 接着,需要讲单片机如何通过IO口控制蜂鸣器。可能涉及到高低电平驱动和三极管的使用,因为直接驱动可能电流不够。要解释为什么需要三极管或驱动电路,比如电流放大。 然后,提到PWM信号控制无源蜂鸣器的音调,这里可能需要说明频率和音调的关系。用户可能想了解如何产生不同的声音,比如音调变化或音乐播放。 还要注意STC89C51的IO口结构,推挽输出和准双向口的区别,以及如何配置。比如高电平驱动和低电平驱动的不同接法,这部分需要准确,避免用户接错电路。 最后,给出示例代码,让用户更直观地理解如何编程控制。代码要简单明了,展示如何通过延时改变频率,同时提醒实际开发中使用定时器更好。 检查是否有遗漏的部分,比如保护电路、续流二极管的作用,这些对防止反向电动势损坏元件很重要。需要确保信息准确,语言通俗易懂,结构清晰。</think>STC89C51单片机蜂鸣器的工作原理可分为以下几个关键点: --- ### 一、蜂鸣器类型与驱动基础 1. **有源蜂鸣器** - 内置振荡电路,**只需直流电压即可发声**(如$+5V$)。 - 控制逻辑:通过单片机IO口输出**高低电平**直接控制(需配合三极管放大电流)。 - 示例电路: $$ V_{CC} \rightarrow 蜂鸣器(+) \rightarrow 蜂鸣器(-) \rightarrow NPN三极管集电极 $$ $$ 单片机IO \rightarrow 三极管基极(通过限流电阻) $$ 2. **无源蜂鸣器** - **需外部提供PWM信号**驱动,通过频率变化控制音调。 - 典型驱动电路:使用三极管或MOS管放大电流,配合PWM输出。 - 频率公式: $$ f = \frac{1}{T} \quad (T为PWM周期) $$ --- ### 二、STC89C51的硬件控制 1. **IO口驱动能力** - STC89C51的IO口**最大拉电流约20mA**,而蜂鸣器工作电流通常为30-100mA。 - **必须外接三极管**(如S8050)或驱动芯片(如ULN2003)进行电流放大。 2. **典型电路连接** - 高电平驱动: $$ IO口 \xrightarrow{1k\Omega电阻} 三极管基极 $$ $$ 三极管发射极接地,集电极接蜂鸣器负极 $$ - **注意**:蜂鸣器正极需串联限流电阻(如$100\Omega$)防止过流。 --- ### 三、软件控制逻辑 1. **有源蜂鸣器控制** ```c sbit Buzzer = P1^0; // 假设蜂鸣器接P1.0 void main() { Buzzer = 1; // 开启蜂鸣器 DelayMs(1000); Buzzer = 0; // 关闭蜂鸣器 } ``` 2. **无源蜂鸣器控制(以1kHz为例)** ```c void Beep() { while(1) { Buzzer = ~Buzzer; DelayUs(500); // 半周期延时,总周期1ms → f=1kHz } } ``` --- ### 四、关键注意事项 1. **反接保护** - 蜂鸣器是感性负载,需并联**续流二极管**(如1N4148)防止反向电动势损坏电路。 2. **IO口模式配置** - 建议将IO口设置为**推挽输出模式**(通过配置PxM1/PxM0寄存器),提高驱动能力。 --- ### 五、应用场景 - **有源蜂鸣器**:报警提示音(单音调) - **无源蜂鸣器**:音乐播放、多音调告警(需复杂PWM控制) --- 通过上述硬件电路设计和软件编程,STC89C51可有效控制蜂鸣器发声。实际开发中建议使用定时器中断生成精确PWM信号。
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值