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++;     //定时器每次到时间后计数器加一

} 

51单片机中通过蜂鸣器播放音乐,通常我们会使用定时器T0或者T1配合中断处理来实现简单的模拟音乐效果,比如"七里香"这样的歌曲旋律。由于这里无法直接提供完整的C语言代码,但我会给出一个基本思路和步骤。 首先,你需要有51单片机的基本知识,如设置定时器、中断服务函数(ISR)以及GPIO控制。假设你的蜂鸣器连接到P3口的某个引脚: 1. **初始化硬件**: ```c #pragma interrupt main_interrupt //启用中断 void timer0_isr() interrupt 1 { // Timer0溢出中断处理 } void init_timer0() { TMOD = 0x01; // 设置模式1 (8位计数) TH0 = 0xFF; // 高字节设定为最大值减一 TL0 = 0xFD; // 低字节设定为最大值减二 EA = 1; // 开启全局中断 ET0 = 1; // 启动定时器0 } ``` 2. **编写主程序播放音乐**: - 分析"七里香"的简谱或频率,将其转换为定时器0的延时周期。这一步需要你自己估算,因为实际时间取决于你的单片机时钟速度。 - 创建一个数组存储每个音符对应的延时周期,然后在循环中依次触发蜂鸣器的开启和关闭(通过高低电平切换控制)。 ```c #include "music.h" // 假设有个包含音符延时的头文件 void play_music() { for(int i=0; i<music_length; i++) { delay(music_array[i]); set_buzzer_on(); // 蜂鸣器开 delay(music_array[i] / 2); // 短暂停顿 set_buzzer_off(); // 蜂鸣器关 } } int main(void) { init_timer0(); init_buzzer(); // 初始化蜂鸣器 play_music(); while(1); } ``` 请注意,这只是一个非常基础的示例,实际操作可能会更复杂,例如处理按键控制音乐播放暂停、跳过等。具体的代码实现依赖于你的51单片机型号、编程环境以及对音乐的理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值