51蜂鸣器以及使用

本文介绍了如何使用C语言编程,结合定时器和ULN2003集成电路驱动蜂鸣器,实现乐谱中的音高控制,包括蜂鸣器发声原理、无源蜂鸣器驱动注意事项以及使用定时器播放天空之城音乐示例。
摘要由CSDN通过智能技术生成


定时器相关可见:https://blog.csdn.net/qq_53922901/article/details/135730245?spm=1001.2014.3001.5501

蜂鸣器介绍

有源无源蜂鸣器的外观基本一致不好分辨,需要提前了解。
在这里插入图片描述

驱动电路

在这里插入图片描述

集成电路驱动

原理图

在这里插入图片描述
在这里插入图片描述

ULN2003介绍

在这里插入图片描述

逻辑框图

在这里插入图片描述

典型应用电路

在这里插入图片描述

注意
无源蜂鸣器不能长时间通电,但是单片机I/O口默认给高电平,通过非门之后会使蜂鸣器通电,所以蜂鸣器是默认通电状态,不过单片机设有限流电阻,自己组装时要注意。给0时形成高阻态,使电路不通点
高阻态
高阻态这是一个数字电路里常见的术语,指的是电路的一种输出状态,既不是高电平也不是低电平。
如果高阻态再输入下一级电路的话,对下级电路无任何影响,和没接一样,如果用万用表测的话有可能是高电平也有可能是低电平,随它后面接的东西定。

乐理相关

键盘与音高对照

在这里插入图片描述

  • #为升音,即升高半个音,每相邻的键盘(无论黑白)都是相隔半音,例如#c,就是c右上黑键的音。
  • b为降音,即降低半个音,例如eb,就是e左上黑键的音

音符

从左到右依次(由慢到快)是全音符、二分音符、四分音符、八分音符、十六分音符、三十二分音符、六十四分音符,之间都是两倍的关系。
在这里插入图片描述
在这里插入图片描述

以上面谱子,是以C为主音,以四分音符为准,即每个普通音(普通数字)的持续时间与四分音符的时长一致。

  • 如:5-,即延长5这个音的时间两倍。5- -即延长四倍
  • 如:5下面一横,即缩短时间为原本的1/2,以此类推。

c调音与频率对照表

在这里插入图片描述
在这里插入图片描述
相邻按十二平均律计算,下一个音高频率 = 上一个音高频率*2^(1/12)

转换数据

使用excel得到需要使用的数据(音高使用的是赫尔姆霍茨音调记号法)
在这里插入图片描述
重装载值用于给定时器赋值

实现蜂鸣器发声

代码如下:

#include <REGX52.H>
#include <intrins.h>
// 蜂鸣器端口
sbit Buzzer = P2^5;

unsigned int i;

void Delay500us(void)	//@11.0592MHz
{
	unsigned char data i;

	_nop_();
	i = 227;
	while (--i);
}
/**
   * @brief 	蜂鸣器发声时长
   * @param		ms 发声时长(单位毫秒)
   * @retval	无
   */
void Buzzer_Time(unsigned int ms){
	for(i=0;i<ms*2;i++){
			Buzzer = !Buzzer;
			Delay500us();	// 以1000Hz的频率响
		}
}

实现蜂鸣器使用定时器播放天空之城

main.c内容如下:

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

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

//播放速度,值为四分音符的时长(500ms)
#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[]={
	//音符,时值,
	
	//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++;									// +1显示为音乐时长
			Delay(SPEED/4*Music[MusicSelect]);	//选择音符对应的时值
			MusicSelect++;									// 在+1显示为下次的音高
			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口
	}
}

Delay.c延时函数如下:

void Delay(unsigned int xms)
{
	unsigned char i, j;
	while(xms--)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}


  • 29
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值