51单片机完全学习——蜂鸣器

一、蜂鸣器工作原理

蜂鸣器需要不断地接通断开,通过接通和断开的时间间隔,来改变蜂鸣器的声音。主要有两个参数来控制,一个是音调,一个是声音大小。其中音调是受振动频率控制的,就等于控制信号的频率。频率越高音调越高,声音听起来越刺耳。声音大小由硬件决定,不能软件控制。

无源蜂鸣器需要一定的频率的波形去控制它,才能发出声音。

有源蜂鸣器只需要通电就可以响起来,有源蜂鸣器也可以用频率信号驱动。

二、让蜂鸣器响起来

首先是接线,随便接在单片机的某一个引脚就可以,然后通过给引脚输出0或1,来达到闭合和释放的目的,然后通过延时来控制音调的变化。注意这个delay()函数需要自己去实现,不同的延时蜂鸣器的音调是不一样的。

BUZZER = 0;
delay();
BUZZER = 1;	 
delay();

三、使用定时器来控制蜂鸣器

使用定时器来控制蜂鸣器的好处是:我们之前在延时的时候CPU是不能去做其他事情的,因此CPU就会浪费掉,当我们使用定时器的时候定时时间一到进入到中断里面然后将蜂鸣器的引脚电平进行取反这样就可以得到我们想要的效果了。而且主函数里面还可以做其他事情。由于定时器的延时时间比较短,我们使用cont来将定时时间扩大20倍,这样就可以增加延时时间。

unsigned char cont = 0;
sbit BUZZER = P2^7;


void main(void)
{
	unsigned char key = 0;
	TMOD = 0x01;    //设置定时器的工作模式位16位
	TH0 = 0xff;     //设置定时器的初始值高8位
	TL0 = 0xf6;     //设置定时器的初始值低8位
	TR0 = 1;        //开启定时器T0
	ET0 = 1;        //打开定时器T0的中断
	EA = 1;         //打开总中断
	
	while(1)
	{

  }
}


void timer0_int(void) interrupt 1 using 1   //中断处理程序中使用内部寄存器bank1 r0 r1这些寄存器都有4个bank
{                                           //这样在运行中断的时候就不用再保存主程序的寄存器了,可以提高程序运行速度
    TH0 = 0xff;
	TL0 = 0xf6;	
	if (cont == 20)
	{
        BUZZER = !BUZZER;
		cont = 0;
	}
	cont++;
	
}

四、使用蜂鸣器发出滴滴声

首先我们知道蜂鸣器发出滴滴声,其实就是间隔一段时间响一下,我们上面做的那种是一直响,我们只需要间隔一段时间让他不响,这样就可以发出滴滴的声音了。只需要将上面的程序进行修改就可以了,我们也是用一个计数器来控制响和不响的时间长短,响和不响的间隔是可以不一样的,我们这是一样的。也就是计数的前3000次,一直在响。后3000次一直没有响,这样就可以产生滴滴声了。

    if (cont < 3000)
	{
		BUZZER = !BUZZER;
	}
	cont++;
	if (cont >= 3000)
	{
		BUZZER = 0;
		if (cont == 6000)
		{
			cont = 0;
		}
	}

但是上面发出的那种滴滴声音只要程序一运行起来他的间隔就是不变的,我们下面进行一些简单的修改就可以将他变成在程序运行过程中,响的频率是可以动态发生变化的。

    if (cont < 3000-i)   //每响一个周期,计数器的上限会被减少
	{                    //这样就可以达到响声越来越急促的效果
		BUZZER = !BUZZER;
	}
	cont++;
	if (cont >= 3000-i)
	{
		BUZZER = 0;
		if (cont == 6000 - 2 * i)
		{
			cont = 0;
		    i += 100;  //响声收敛的速度,由他来进行控制
			if (i == 3000)
			{
				i = 0; //主要是进行一个复位
			}
		}
	}

五、让蜂鸣器唱歌

为什么蜂鸣器可以唱歌?因为蜂鸣器的音调可以控制,其次蜂鸣器响的时间可以控制。我们使用定时器来控制节拍也就是每个音调响的长度,然后使用延时函数来控制蜂鸣器的频率,这样我们就可以发出不同的音调和每个音调的长度。

#include <reg51.h>
#include <intrins.h>

#include "shumaguan.h"

#define uchar unsigned char
	
uchar i = 0, yj = 0, jp = 0, zdjs = 0;
sbit BUZZER = P2^7;


uchar code sound[]={0x26,0x10,0x26,0x10,0x24,0x20,0x26,0x20,0x1c,0x20,0x20,0x40,0x26,0x10,
                    0x26,0x10,0x24,0x20,0x26,0x20,0x19,0x20,0x1c,0x40,0x00};

void delay(yj)
{
   uchar yj2 = 2;
   while(yj != 0)
   {      
      while(yj2 != 0)
		  {
			  yj2--;
			}
			  yj2 = 2;
		      yj--;  
   }
}

void main(void)
{
	unsigned char key = 0;
	TMOD = 0x01;    //设置定时器的工作模式位16位
	TH0 = 0xd8;     //设置定时器的初始值高8位  初始时间为10毫秒
	TL0 = 0xef;     //设置定时器的初始值低8位
	TR0 = 1;        //开启定时器T0
	ET0 = 1;        //打开定时器T0的中断
	EA = 1;         //打开总中断
	
	while(1)
	{
        BUZZER = !BUZZER;  //蜂鸣器取反
		yj = sound[2 * i];
		jp = sound[2 * i + 1];
		if (yj == 0x00)  //主要是用来判断结束标志
		{
			i = 0;
		}
		delay(yj);
		while(zdjs == jp)   //当定时zdjs*10等于jp时播放下一个音节,音节的长度节拍由jp进行控制
		{
			i++;
			zdjs = 0;
		}
  }
}


void timer0_int(void) interrupt 1 using 1   //中断处理程序中使用内部寄存器bank1 r0 r1这些寄存器都有4个bank
{                                           //这样在运行中断的时候就不用再保存主程序的寄存器了,可以提高程序运行速度
  TH0 = 0xd8;
  TL0 = 0xef;	
  zdjs++;     //定时器每次到时间后计数器加一

} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值