蜂鸣器

蜂鸣器:是一种一体化结构的电子讯响器,采用直流电压供电,分为 压电式 蜂鸣器和 电磁式 蜂鸣器(无源和有源), 51 开发板一般是 压电式 的。

根据网上查的资料可以知道无源和有源的区别:

⑴有无震荡源

无源这里的“源”不是指电源,而是指 震荡源。也就是说,有源蜂鸣器内部带震荡源,所以只要一通电就会叫。而无源内部不带震荡源,所以如果用直流信号无法令其鸣叫。

⑵价格不同

有源蜂鸣器往往比无源蜂鸣器 ,就是因为里面多个震荡电路。

怎么区分? 有绿色电路板的一种是无源蜂鸣器,没有电路板而用黑胶封闭的一种是有源蜂鸣器。

无源蜂鸣器通过 脉冲频率 才能发声。

代码如下:

# include "reg52.h"
# include "intrins.h"
typedef unsigned int u16;
 
sbit BEEP=P2^5;
void delay_10us(u16 ten_us)
{
	while(ten_us--);
}
void main()
{
	u16 i=2000;
 
	while(1)
	{
		while(i--)
		{
			
			BEEP=!BEEP;
			delay_10us(100);	
		}
		i=0;//赋0就不会再响了
		BEEP=1;//这赋0或者1都行
	}
	
	while(1);
}

蜂鸣器模拟枪声

main.c

/*********************************************************************************
* 【函数功能】: 蜂鸣器测试-模拟枪声			   			            			    
* 【使用说明】: 短接蜂鸣器J5跳帽,按下K1按键
**********************************************************************************/

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

# define uchar unsigned char
# define uint  unsigned int

sbit  BEEP= P2^5;
sbit  K1  = P3^1;

uchar  H_count,L_count;

/*********************************************************/
void  main()
{	
 	P0=0;
	BEEP=1;
    TMOD=0x01; 
    TH0=0xff; 
    TL0=0xa0;
    H_count=0xff;
    L_count=0xa0;      
    EA=1;
    ET0=1; 
    
    while(1)
    {
       while(K1);
       TR0=1;
    }
}

/*********************************************************
  Time0中断函数
**********************************************************/
void Time0(void) interrupt 1 using 0
{
	BEEP=~BEEP;
	if( L_count!=0x00 )
	{
	   L_count--;
	   TH0=H_count; 
       TL0=L_count;
       return;
     }else  H_count--;
		
	if( H_count!=0xfc )
	{
	   L_count--;
	   TH0=H_count; 
       TL0=L_count;
       return;
	}
	else
     {
        H_count=0xff;
        L_count=0xa0;
        TH0=H_count;
        TL0=L_count;
        BEEP=1;
        TR0=0;
     }   
}

门铃

main.c

/*	
实验接线:
	BEEP-->P15
	独立按键模块-->单片机管脚
	K1-->P31
实验现象:
	按下K1键,蜂鸣器发出”叮咚”门铃声
*/


# include "reg52.h"
			 
typedef unsigned int u16;	 
typedef unsigned char u8;

sbit beep=P2^5;
sbit k1=P3^1;
u8 ding,dong,flag,stop;
u16 n;
void delay(u16 i)
{
	while(i--);
}
void time0init()	  //定时器0初始化
{
	TMOD=0X01;	 //定时器0 方式1
	TH0=0Xff;
	TL0=0X06; //定时250us
//	TR0=1;
	EA=1;
	ET0=1;
}
void biaohaoinit()	   //各个标号初始化
{
	ding=0;		//叮声音  计数标志
	dong=0;		//咚声音  计数标志
	n=0;		//定时0.5s标志
	flag=0;
	stop=0;	   //结束标志
}
void main()
{
	time0init();
	biaohaoinit();
	while(1)
	{
		if(k1==0)	   //判断按键是否按下
		{
			delay(1000);  //消抖
			if(k1==0)
			{
				TR0=1;	//打开定时器0
				while(!stop);
			}
		}	
	}	
}
void time0() interrupt 1
{
	n++;
	TH0=0Xff;
	TL0=0X06; //250us
	if(n==2000)		//定时0.5s  叮响0.5秒,咚响0.5秒
	{
		n=0;
		if(flag==0)
		{
			flag=~flag;
		}
		else
		{
			flag=0;
			stop=1;
			TR0=0;	  //关闭定时器0
		}
	}
	if(flag==0)
	{					   //通过改变定时计数时间可以改变门铃的声音
		ding++;			  //叮
		if(ding==1)
		{
			ding=0;
			beep=~beep;
		}
	}
	else
	{
		dong++;
		if(dong==2)		  //咚
		{
			dong=0;
			beep=~beep;
		}	
	}
}

按k1响k2停

main.c

/*
实验说明:
	此程序兼容了有源和无源蜂鸣器
实验现象:
	按下K1键,蜂鸣器发出声音,按下K2键,蜂鸣器停止发声
*/

# include "reg52.h"			 //此文件中定义了单片机的一些特殊功能寄存器

typedef unsigned int u16;	  //对数据类型进行声明定义
typedef unsigned char u8;

sbit k1=P3^1;
sbit k2=P3^0;

sbit beep=P2^5;

u8 start=0;

/*******************************************************************************
* 函 数 名         : delay
* 函数功能		   : 延时函数,i=1时,大约延时10us
*******************************************************************************/
void delay(u16 i)
{
	while(i--);	
}

void sound()
{
	u8 i=100;
	while(i--)
	{
		beep=~beep;
		delay(100);	
	}
}
void keypros()
{
	if(k1==0)			 //开始
	{
		delay(1000);
		if(k1==0)
		{
			start=1;		
		}
		while(!k1);
	}
	if(k2==0)			  //停止
	{
		delay(1000);
		if(k2==0)
		{
			start=0;		
		}
		while(!k2);
	}
}
/*******************************************************************************
* 函 数 名       : main
* 函数功能		 : 主函数
* 输    入       : 无
* 输    出    	 : 无
*******************************************************************************/
void main()
{	
	while(1)
	{
		keypros();
		if(start==1)
		{
			sound();
		}
		else
		{
			beep=1;
		}		
	}		
}


数码管

动态数码管

动态数码管:静态和动态数码管本质 区别是:静态数码管中只要给了段码数码管就一定工作( 显示只取决于段码端),动态数码管中段码端给了段码值后还需要 COM端(即公共端)配合才能点亮数码管。

快速切换工作的数码管,动态数码管利用了人眼的视觉暂留,则人看到的是所有的数码管都在亮(其实亮度是比静态驱动低的)。肉眼看到的范围是 20-50ms

要学会看芯片手册!!!!

静态数码管

单个数码管循环输出0-9代码:

# include "reg52.h"
typedef unsigned int u16;
typedef unsigned char u8;
 
# define SMG_A_F_PORT P0//宏定义数码管P0端口
u8 gsmg_code[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,
							0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//定义数组存放0-F段码,gsmg中g代表全局变量
void delay_10us(u16 ten_us)
{
	while(ten_us--);
}
void main()
{
	
	u8 i=0;
	u8 sz=sizeof(gsmg_code)/sizeof(gsmg_code[0]);//数组元素个数
	
	while(1)
	{
		for(i=0;i<sz-6;i++)//只要0-9所以把A-F的减去
		{
			SMG_A_F_PORT=gsmg_code[i];
			delay_10us(50000);
		}	
	}
	while(1);
}

实验现象

3-8译码器

  • 头上有一横表示在低电平时有效

  • 真值:L:表示低电平0 H:表示高电平1 X:表示无论是高电平还是低电平都不影响真值

代码如下:

# include "reg52.h"
 
 
typedef unsigned int u16;
typedef unsigned char u8;
 
# define SMG_A0_F_PORT P0//宏定义数码管P0端口
sbit A0=P2^2;
sbit A1=P2^3;
sbit A2=P2^4;
u8 gsmg_code[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,
			  0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//定义数组存放0-F段码,gsmg中g代表全局变量
void delay_10us(u16 ten_us)
{
	while(ten_us--);
}
void main()
{
	u8 i=0;
	while(1)
	{
		for(i=0;i<8;i++)
		{
			switch(i)
			{
				case 0:A0=1;A1=1;A2=1;break;//Y7//板子从左边数第一个数码管,下面以此类推
				case 1:A0=0;A1=1;A2=1;break;//Y6
				case 2:A0=1;A1=0;A2=1;break;//Y5
				case 3:A0=0;A1=0;A2=1;break;//Y4
				case 4:A0=1;A1=1;A2=0;break;//Y3
				case 5:A0=0;A1=1;A2=0;break;//Y2
				case 6:A0=1;A1=0;A2=0;break;//Y1
				case 7:A0=0;A1=0;A2=0;break;//Y0
			}
			SMG_A0_F_PORT=gsmg_code[i];
			delay_10us(100);//延时1毫秒左右
			SMG_A0_F_PORT=0x00;//消影
			
		}
	}
	while(1);
}

没消影:

消影后:

例子

main.c

/*
实验说明:
	
实验现象:
	按K4键进入数字设置,按K1和K3键对闪烁的数字进行加和减,按K2键进行数码管移位设置
	再次按下K4键退出设置。
*/


# include "reg52.h"			

typedef unsigned int u16;	
typedef unsigned char u8;

sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;

sbit k1=P3^1;
sbit k2=P3^0;
sbit k3=P3^2;
sbit k4=P3^3;	 //定义按键端口

# define KEY1 1
# define KEY2 2
# define KEY3 3
# define KEY4 4

u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
					0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值

u8 DisplayData[8];
char datnum1=0,datnum2=0,datnum3=0,datnum4=0;
u8 setflag=0;
u8 wei_change=0;

/*******************************************************************************
* 函 数 名         : delay
* 函数功能		   : 延时函数,i=1时,大约延时10us
*******************************************************************************/
void delay(u16 i)
{
	while(i--);	
}

/*******************************************************************************
* 函 数 名         : Timer0Init
* 函数功能		   : 定时器0初始化
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void Timer0Init()
{
	TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。

	TH0=0Xd8;	//给定时器赋初值,定时10ms
	TL0=0Xf0;	
	ET0=1;//打开定时器0中断允许
	EA=1;//打开总中断
	//TR0=1;//打开定时器			
}

/*******************************************************************************
* 函 数 名         : DigDisplay
* 函数功能		   : 数码管动态扫描函数,循环扫描8个数码管显示
*******************************************************************************/
void DigDisplay()
{
	u8 i;
	for(i=0;i<8;i++)
	{
		switch(i)	 //位选,选择点亮的数码管,
		{
			case(0):
				LSA=1;LSB=1;LSC=1; break;//显示第7位
			case(1):
				LSA=0;LSB=1;LSC=1; break;//显示第6位
			case(2):
				LSA=1;LSB=0;LSC=1; break;//显示第5位
			case(3):
				LSA=0;LSB=0;LSC=1; break;//显示第4位
			case(4):
				LSA=1;LSB=1;LSC=0; break;//显示第3位 
			case(5):
				LSA=0;LSB=1;LSC=0; break;//显示第2位 
			case(6):
				LSA=1;LSB=0;LSC=0; break;//显示第1位 
			case(7):
				LSA=0;LSB=0;LSC=0; break;//显示第0位	
		}
		P0=DisplayData[i];//发送段码
		delay(100); //间隔一段时间扫描	
		P0=0x00;//消隐
	}
}

//mode=0 单次   1:连续
u8 KeyScan(u8 mode)
{
	static u8 keyen=1;
	if(mode==1)
	{
		keyen=1;
	}
	if(keyen==1&&(k1==0||k2==0||k3==0||k4==0))
	{
		delay(1000);  //消抖处理
		keyen=0;
		if(k1==0)return KEY1;
		else if(k2==0)return KEY2;
		else if(k3==0)return KEY3;
		else if(k4==0)return KEY4;				
	}
	else if(k1==1&&k2==1&&k3==1&&k4==1)
	{
		keyen=1;
	}
	return 0;	
}

void datapros()
{
	u8 key;
	key=KeyScan(0);
	
	if(key==KEY4)	   //设置
	{
		setflag++;
		TR0=1;	   //开启定时器
		if(setflag==2)
		{
			TR0=0;		//关闭定时器
			setflag=0;	
		}
	}

	if(setflag==0)	 //默认/退出设置显示
	{
		DisplayData[0]=smgduan[datnum4];
		DisplayData[1]=smgduan[datnum3];
		DisplayData[2]=smgduan[datnum2];
		DisplayData[3]=smgduan[datnum1];
	}
	else	  //进入设置  数码管选中闪烁
	{
		if(key==KEY2)	    //数据位数移动变化
		{
			wei_change++;
			if(wei_change>3)wei_change=0;
			DisplayData[0]=smgduan[datnum4];
			DisplayData[1]=smgduan[datnum3];
			DisplayData[2]=smgduan[datnum2];
			DisplayData[3]=smgduan[datnum1];	
		}

		else if(key==KEY1)	 //数据加
		{
			switch(wei_change)
			{
				case 0:  datnum1++;
						if(datnum1>9)datnum1=0;
						break;
				case 1:  datnum2++;
						if(datnum2>9)datnum2=0;
						break;
				case 2:  datnum3++;
						if(datnum3>9)datnum3=0;
						break;
				case 3:  datnum4++;
						if(datnum4>9)datnum4=0;
						break;

			}	
		}
		else if(key==KEY3)	 //数据减
		{
			switch(wei_change)
			{
				case 0:  datnum1--;
						if(datnum1<=0)datnum1=9;		
						break;
				case 1:  datnum2--;
						if(datnum2<=0)datnum2=9;
						break;
				case 2:  datnum3--;
						if(datnum3<=0)datnum3=9;
						break;
				case 3:  datnum4--;
						if(datnum4<=0)datnum4=9;
						break;

			}	
		}
			
	}
	
}
/*******************************************************************************
* 函 数 名       : main
* 函数功能		 : 主函数
* 输    入       : 无
* 输    出    	 : 无
*******************************************************************************/
void main()
{	
	Timer0Init();
	while(1)
	{	
		datapros();
		DigDisplay();	
	}		
}

/*******************************************************************************
* 函 数 名         : void Timer0() interrupt 1
* 函数功能		   : 定时器0中断函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void Timer0() interrupt 1
{
	static u8 i;
	TH0=0Xd8;	//给定时器赋初值,定时10ms
	TL0=0Xf0;
	i++;
	if(i==50)	  //500ms
	{
		switch(wei_change)
		{
			case 0: DisplayData[3]=0x00;break;
			case 1: DisplayData[2]=0x00;break;
			case 2: DisplayData[1]=0x00;break;
			case 3: DisplayData[0]=0x00;break;
		}	
	}
	if(i==100)	   //1s
	{
		i=0;
		switch(wei_change)
		{
			case 0: DisplayData[3]=smgduan[datnum1];break;
			case 1: DisplayData[2]=smgduan[datnum2];break;
			case 2: DisplayData[1]=smgduan[datnum3];break;
			case 3: DisplayData[0]=smgduan[datnum4];break;
		}			
	}
}