2019-10-09蜂鸣器

1.蜂鸣器的的原理

1.1、无源蜂鸣器原理

(1)早期的蜂鸣器都是无源的
(2)内部结构和材料
(3)发声原理:两个金属片靠的很近,分别通正电和负电,那他们会相吸,不通电则分开,一吸一分产生声音。
(4)控制信号,是高低电平相间的方波
(5)电路图


蜂鸣器电路图

(6)音调如何控制,音调受震动频率控制,就等于控制信号的频率。频率越高音调越高,听起来越刺耳
(7)声音大小如何控制,由硬件决定的,没法写代码去控制声音大小。

1.2、有源蜂鸣器

(1)无源蜂鸣器的缺陷
(2)内置振荡电路后形成有源蜂鸣器
(3)有源蜂鸣器也可以用频率信号驱动

2.让蜂鸣器想起来

(1)接线确定。P0.0接到J8上面。
(2)最简单:使用delay让蜂鸣器响起来
(3)调节delay时间感受音调变化

#include 

sbit BUZZER = P0^0;                 // buzzer的驱动引脚

void delay(void)
{
    unsigned char i, j;

    for (i=0; i<5; i++)
        for (j=0; j<5; j++);
}


void main(void)
{
    while (1)
    {
        BUZZER = 1;
        delay();
        BUZZER = 0;
        delay();
    }
}

3.用定时器控制蜂鸣器音调

3.1、上节delay驱动方法的问题

(1)不容易精准控制时间
(2)CPU控制蜂鸣器中不能做其他事

3.2、定时器控制蜂鸣器响

(1)10kHZ => 1/1000s = 100us => 高电平+低电平一共100us
那么高电平和低电平的时间都是50us。所以要定的时间就是50us。
(2)外部晶振12MHZ + 12T设置 => 内部时钟频率1MHZ => 1us

#include 


sbit BUZZER = P1^7;                 // buzzer的驱动引脚

#define XKHZ    1                   // 要定多少Khz,就直接写这里
#define US      (500/XKHZ)          // 1000hz除以2,高低电平各一半
#define N       (65535-US)


void timer0_isr(void) interrupt 1 using 1
{
    TL0 = N % 256;    // 低8位
    TH0 = N / 256;    // 高8位

    BUZZER = !BUZZER;
}



void main(void)
{
    TMOD = 0x01;        // T0使用16bit定时器
    TL0 = N % 256;
    TH0 = N / 256;

    TR0 = 1;            // T0打开开始计数
    ET0 = 1;            // T0中断允许
    EA = 1;             // 总中断允许

    BUZZER = 1;

    while (1);
}

4.蜂鸣器发出滴滴声

#include 


sbit BUZZER = P0^0;                 // buzzer的驱动引脚

#define XKHZ    4                   // 要定多少Khz,就直接写这里
#define US      (500/XKHZ)
#define N       (65535-US)


unsigned int count;
unsigned char flag = 0;         // flag = 0表示有声音,flag = 1表示没声音


void timer0_isr(void) interrupt 1 using 1
{
    TL0 = N % 256;
    TH0 = N / 256;

    if (count-- == 0)
    {
        // 说明到了翻转的时候了
    //  count = 600;

        if (flag == 0)
        {
            // 之前是处于有声音的,说明本次是从有声音到无声音的翻转
            flag = 1;
            count = 600*10;
        }
        else
        {
            // 之前是处于没声音的,说明本次是从没声音到有声音的翻转
            flag = 0;
            BUZZER = !BUZZER;
            count = 600;
        }
    }
    else
    {
        // 常规情况,也就是不反转时
        if (flag == 0)
        {
            BUZZER = !BUZZER;           // 4999次声音
        }
        else
        {
            // 空的就可以,因为不进行任何IO操作就是没声音
        }
    }
    
}



void main(void)
{
    TMOD = 0x01;        // T0使用16bit定时器
    TL0 = N % 256;
    TH0 = N / 256;

    TR0 = 1;            // T0打开开始计数
    ET0 = 1;            // T0中断允许
    EA = 1;             // 总中断允许

    BUZZER = 1;

    // 设置响和不响的周期时间
    count = 600;        // 5000*100us = 500ms
    flag = 0;

    while (1);
}

5.让蜂鸣器唱歌

5.1、为什么蜂鸣器可以唱歌

(1)发声音调可变
(2)发声长度可变

5.2、体验写好的唱歌程序

(1)复制代码过去
(2)修改控制蜂鸣器的IO引脚定义

5.3、代码理解

(1)按照习惯去调好代码风格,然后再看
(2)看的过程中尝试修改并调试

/************************************************************************  
[文件名]  C51音乐程序(八月桂花)  
[功能]    通过单片机演奏音乐  
  
/**********************************************************************/   
#include     
//#include     
//本例采用89C52, 晶振为11.0592MHZ    
//关于如何编制音乐代码, 其实十分简单,各位可以看以下代码.    
//频率常数即音乐术语中的音调,而节拍常数即音乐术语中的多少拍;    
//所以拿出谱子, 试探编吧!    

sbit Beep =  P0^0 ;             // 要根据实际的接线来修改
   
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   
};   

 // T0定时控制的是音乐的节拍(某一个音节持续的时间)而不管音调(频率)
 // 音调是直接使用delay做出来的。
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;       // timer0 工作在模式1,16位定时器下 
    TH0 = 0xd8;
    TL0 = 0xef;         // 这个TH和TL的值合起来定了1个10ms左右的一个时间
    IE = 0x82;   
play:   
    while (1)   
    {   
a:      p = music_tab[i];   
        if (p == 0x00)          // 一遍播放完了,延时1s后自动开始下一遍    
        { 
            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++];
        }  // m取频率常数 和 n取节拍常数    
        TR0 = 1;                              //开定时器1    
        while (n != 0)
        { 
            Beep = ~Beep;
            delay(m);           //等待节拍完成, 通过P1口输出音频(可多声道哦!)    
        }
        TR0 = 0;                            //关定时器1    
    }   
}
  

你可能感兴趣的:(2019-10-09蜂鸣器)