【蓝桥杯】单片机学习(6)——蜂鸣器+继电器

1、蜂鸣器简介

蜂鸣器按照驱动方式可分为有源蜂鸣器和无源蜂鸣器。有源蜂鸣器内部带有振荡器,只要给BZ段一个低电平,蜂鸣器就会响;而无源蜂鸣器内部不带震荡源,必须给500HZ~4.5KHZ之间的频率脉冲信号它才会响。比较而言,有源蜂鸣器内部多一个震荡电路。驱动发音较为简单;无源蜂鸣器的价格较低,声音频率可以控制。

无源蜂鸣器是直流电压驱动的,只需对驱动口输出驱动电平,并通过放大电路放大驱动电流,就能使蜂鸣器发出声音,改变单片机引脚输出波形的频率,可以调整控制蜂鸣器音调,产生各种不同音色、音调的声音; 改变输出电平的高低电平占空比,则可以控制蜂鸣器的声音大小。

2、蜂鸣器工作过程(CT107D开发板)。

蜂鸣器正常工作的前提条件是两端有电压差,如下图所示我们可以看到蜂鸣器的引脚为BUZZ(ER),其中一端已经接了+5V电源,所以只需另一端接低电平,该蜂鸣器即可以正常工作。
在这里插入图片描述
BUZZ引脚对应的I/O口是P0^ 6, BUZZ和P0^6 之间有M74HC573和ULN2003两个芯片,M74HC573就是一个简单的锁存器,输出前后状态相同,注意保证它的使能端有效即可,在前面几个模块也已经多次出现,在这里就不赘述了,主要介绍一下ULN2003。
蜂鸣器原理图
ULN2003:高耐压、大电流复合晶体管阵列,由七个硅NPN 复合晶体管组成,每一对达林顿都串联一个2.7K 的基极电阻,在5V 的工作电压下它能与TTL 和CMOS 电路直接相连,可以直接处理原先需要标准逻辑缓冲器来处理的数据,输入5VTTL电平,输出可达500mA/50V。内部结构图如下:
ULN2003
由上图我们可以看到,ULN2003其实主要有7个反相器组成。这意味着如果我们需要BUZZ引脚为低电平,那么I/O口 P0^ 6 输出应该为高电平,即P0^6 = 1,同时我们要保证M74HC573的使能端有效,即 Y5C=1。我们看一下Y5C的相关模块:
Y5C相关模块
Y5和WR经过与非门得到Y5C,若Y5C=1,则需要Y5=0且WR=0。当J13的跳线帽2和3相连时(即WR和GND短接),表示的是蜂鸣器 继电器模块,所以我们只需要再满足Y5=0即可。这就又涉及到了74HC138模块:
HC138模块

74HC138 这个芯片大家就不陌生了,3-8译码器。若想Y5=0,则需要满足P2^ 7 = 1P2^ 6= 0P2^5 = 1,即将P2口高三位写成101,其余位清零即可。

P2 = ((P2 & 0x1F)|0xA0);//通过Y5C控制74HC573使能有效

注意这个模块写完后要关闭使能:

P2 = P2 & 0x1F;//P2 &= 0x1F 关闭使能

其实和LED模块比起来就是多了ULN2003芯片的使用,其它基本相同。继电器模块和蜂鸣器模块基本上完全相同。区别在于控制继电器的I/0口是P0^4,引脚是RELAY。继电器工作时, P0 ^6 = 1
在这里插入图片描述
关于蜂鸣器,继电器,LED灯的常用模板:

#include<reg52.h>
sbit buzz = P0^6;//蜂鸣器对应的引脚是P0^6
sbit relay = P0^4;//继电器对应的引脚
sbit led = P0^0;//P0^0 ~ P0^7对应8个LED灯
void main()
{
	P2 = ((P2 & 0x1F) | 0xA0);//Y5控制使能端有效
	buzz = 0;//打开蜂鸣器
	P2 = P2 & 0x1F;//使能端无效,关闭蜂鸣器
	
	P2 = ((P2 & 0x1F) | 0xA0);//Y5控制使能端有效
	relay = 1;//打开继电器
	P2 = P2 & 0x1F;//使能端无效,关闭继电器
	
	P2 = ((P2 & 0x1F) | 0x80);//Y4控制使能端有效
	led = 0; //点亮其中一个LED小灯
	P2 = P2 & 0x1F;//使能端无效
	
	while(1);
}

3、以普中科技开发板为例

原理图:
在这里插入图片描述
在这里插入图片描述
和CT107D开发板的原理基本相同,稍微简单一些,P1^5 = 1时,经过ULN2003,BZ = 0,蜂鸣器可以工作。

示例代码如下:

//演奏音乐八月桂花 

#include <reg52.h>    
#include <intrins.h>    

sbit Beep =  P1^5; 
   
unsigned char n=0;              //n为节拍常数变量    
unsigned char code music_tab[] ={   
0x18, 0x30, 0x1C , 0x10,        //格式为: 频率常数, 节拍常数, 频率常数, 节拍常数,    
0x20, 0x40, 0x1C , 0x10,   
0x18, 0x10, 0x20 , 0x10,   
0x1C, 0x10, 0x18 , 0x40,   
0x1C, 0x20, 0x20 , 0x20,   
0x1C, 0x20, 0x18 , 0x20,   
0x20, 0x80, 0xFF , 0x20,   
0x30, 0x1C, 0x10 , 0x18,   
0x20, 0x15, 0x20 , 0x1C,   
0x20, 0x20, 0x20 , 0x26,   
0x40, 0x20, 0x20 , 0x2B,   
0x20, 0x26, 0x20 , 0x20,   
0x20, 0x30, 0x80 , 0xFF,   
0x20, 0x20, 0x1C , 0x10,   
0x18, 0x10, 0x20 , 0x20,   
0x26, 0x20, 0x2B , 0x20,   
0x30, 0x20, 0x2B , 0x40,   
0x20, 0x20, 0x1C , 0x10,   
0x18, 0x10, 0x20 , 0x20,   
0x26, 0x20, 0x2B , 0x20,   
0x30, 0x20, 0x2B , 0x40,   
0x20, 0x30, 0x1C , 0x10,   
0x18, 0x20, 0x15 , 0x20,   
0x1C, 0x20, 0x20 , 0x20,   
0x26, 0x40, 0x20 , 0x20,   
0x2B, 0x20, 0x26 , 0x20,   
0x20, 0x20, 0x30 , 0x80,   
0x20, 0x30, 0x1C , 0x10,   
0x20, 0x10, 0x1C , 0x10,   
0x20, 0x20, 0x26 , 0x20,   
0x2B, 0x20, 0x30 , 0x20,   
0x2B, 0x40, 0x20 , 0x15,   
0x1F, 0x05, 0x20 , 0x10,   
0x1C, 0x10, 0x20 , 0x20,   
0x26, 0x20, 0x2B , 0x20,   
0x30, 0x20, 0x2B , 0x40,   
0x20, 0x30, 0x1C , 0x10,   
0x18, 0x20, 0x15 , 0x20,   
0x1C, 0x20, 0x20 , 0x20,   
0x26, 0x40, 0x20 , 0x20,   
0x2B, 0x20, 0x26 , 0x20,   
0x20, 0x20, 0x30 , 0x30,   
0x20, 0x30, 0x1C , 0x10,   
0x18, 0x40, 0x1C , 0x20,   
0x20, 0x20, 0x26 , 0x40,   
0x13, 0x60, 0x18 , 0x20,   
0x15, 0x40, 0x13 , 0x40,   
0x18, 0x80, 0x00   
};   
   
void int0()  interrupt 1    //采用中断0 控制节拍    
{  TH0=0xd8;   
   TL0=0xef;   
   n--;   
}   
   
void delay (unsigned char m)   //控制频率延时    
{   
 unsigned i=3*m;   
 while(--i);   
}   
   
void delayms(unsigned char a)  //毫秒延时子程序    
{   
  while(--a);                  //采用while(--a) 不要采用while(a--); 各位可编译一下看看汇编结果就知道了!    
}   
   
void main()   
{ unsigned char p,m;          //m为频率常数变量    
  unsigned char i=0;   
  TMOD&=0x0f;   
  TMOD|=0x01;   
  TH0=0xd8;TL0=0xef;   
  IE=0x82;   
play:   
   while(1)   
    {   
    a: p=music_tab[i];   
       if(p==0x00)       { i=0, delayms(1000); goto play;}      //如果碰到结束符,延时1秒,回到开始再来一遍    
       else if(p==0xff)  { i=i+1;delayms(100),TR0=0; goto a;}   //若碰到休止符,延时100ms,继续取下一音符    
            else         {m=music_tab[i++], n=music_tab[i++];}  //取频率常数 和 节拍常数    
             TR0=1;                                             //开定时器1    
           while(n!=0) Beep=~Beep,delay(m);                     //等待节拍完成, 通过P1口输出音频(可多声道哦!)    
       TR0=0;                                                   //关定时器1    
    }   
}  

前一篇: 单片机学习(5)——独立按键与矩阵按键

下一篇: 单片机学习(7)——UART串口通信

  • 6
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值