2019-10-09蜂鳴器

1.蜂鳴器的的原理

1.1、無(wú)源蜂鳴器原理

(1)早期的蜂鳴器都是無(wú)源的
(2)內(nèi)部結(jié)構(gòu)和材料
(3)發(fā)聲原理:兩個(gè)金屬片靠的很近,分別通正電和負(fù)電,那他們會(huì)相吸,不通電則分開(kāi),一吸一分產(chǎn)生聲音。
(4)控制信號(hào),是高低電平相間的方波
(5)電路圖


蜂鳴器電路圖

(6)音調(diào)如何控制,音調(diào)受震動(dòng)頻率控制,就等于控制信號(hào)的頻率。頻率越高音調(diào)越高,聽(tīng)起來(lái)越刺耳
(7)聲音大小如何控制,由硬件決定的,沒(méi)法寫(xiě)代碼去控制聲音大小。

1.2、有源蜂鳴器

(1)無(wú)源蜂鳴器的缺陷
(2)內(nèi)置振蕩電路后形成有源蜂鳴器
(3)有源蜂鳴器也可以用頻率信號(hào)驅(qū)動(dòng)

2.讓蜂鳴器想起來(lái)

(1)接線確定。P0.0接到J8上面。
(2)最簡(jiǎn)單:使用delay讓蜂鳴器響起來(lái)
(3)調(diào)節(jié)delay時(shí)間感受音調(diào)變化

#include <reg51.h>

sbit BUZZER = P0^0;                 // buzzer的驅(qū)動(dòng)引腳

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.用定時(shí)器控制蜂鳴器音調(diào)

3.1、上節(jié)delay驅(qū)動(dòng)方法的問(wèn)題

(1)不容易精準(zhǔn)控制時(shí)間
(2)CPU控制蜂鳴器中不能做其他事

3.2、定時(shí)器控制蜂鳴器響

(1)10kHZ => 1/1000s = 100us => 高電平+低電平一共100us
那么高電平和低電平的時(shí)間都是50us。所以要定的時(shí)間就是50us。
(2)外部晶振12MHZ + 12T設(shè)置 => 內(nèi)部時(shí)鐘頻率1MHZ => 1us

#include <reg51.h>


sbit BUZZER = P1^7;                 // buzzer的驅(qū)動(dòng)引腳

#define XKHZ    1                   // 要定多少Khz,就直接寫(xiě)這里
#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定時(shí)器
    TL0 = N % 256;
    TH0 = N / 256;

    TR0 = 1;            // T0打開(kāi)開(kāi)始計(jì)數(shù)
    ET0 = 1;            // T0中斷允許
    EA = 1;             // 總中斷允許

    BUZZER = 1;

    while (1);
}

4.蜂鳴器發(fā)出滴滴聲

#include <reg51.h>


sbit BUZZER = P0^0;                 // buzzer的驅(qū)動(dòng)引腳

#define XKHZ    4                   // 要定多少Khz,就直接寫(xiě)這里
#define US      (500/XKHZ)
#define N       (65535-US)


unsigned int count;
unsigned char flag = 0;         // flag = 0表示有聲音,flag = 1表示沒(méi)聲音


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

    if (count-- == 0)
    {
        // 說(shuō)明到了翻轉(zhuǎn)的時(shí)候了
    //  count = 600;

        if (flag == 0)
        {
            // 之前是處于有聲音的,說(shuō)明本次是從有聲音到無(wú)聲音的翻轉(zhuǎn)
            flag = 1;
            count = 600*10;
        }
        else
        {
            // 之前是處于沒(méi)聲音的,說(shuō)明本次是從沒(méi)聲音到有聲音的翻轉(zhuǎn)
            flag = 0;
            BUZZER = !BUZZER;
            count = 600;
        }
    }
    else
    {
        // 常規(guī)情況,也就是不反轉(zhuǎn)時(shí)
        if (flag == 0)
        {
            BUZZER = !BUZZER;           // 4999次聲音
        }
        else
        {
            // 空的就可以,因?yàn)椴贿M(jìn)行任何IO操作就是沒(méi)聲音
        }
    }
    
}



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

    TR0 = 1;            // T0打開(kāi)開(kāi)始計(jì)數(shù)
    ET0 = 1;            // T0中斷允許
    EA = 1;             // 總中斷允許

    BUZZER = 1;

    // 設(shè)置響和不響的周期時(shí)間
    count = 600;        // 5000*100us = 500ms
    flag = 0;

    while (1);
}

5.讓蜂鳴器唱歌

5.1、為什么蜂鳴器可以唱歌

(1)發(fā)聲音調(diào)可變
(2)發(fā)聲長(zhǎng)度可變

5.2、體驗(yàn)寫(xiě)好的唱歌程序

(1)復(fù)制代碼過(guò)去
(2)修改控制蜂鳴器的IO引腳定義

5.3、代碼理解

(1)按照習(xí)慣去調(diào)好代碼風(fēng)格,然后再看
(2)看的過(guò)程中嘗試修改并調(diào)試

/************************************************************************  
[文件名]  C51音樂(lè)程序(八月桂花)  
[功能]    通過(guò)單片機(jī)演奏音樂(lè)  
  
/**********************************************************************/   
#include <REG51.H>    
//#include <INTRINS.H>    
//本例采用89C52, 晶振為11.0592MHZ    
//關(guān)于如何編制音樂(lè)代碼, 其實(shí)十分簡(jiǎn)單,各位可以看以下代碼.    
//頻率常數(shù)即音樂(lè)術(shù)語(yǔ)中的音調(diào),而節(jié)拍常數(shù)即音樂(lè)術(shù)語(yǔ)中的多少拍;    
//所以拿出譜子, 試探編吧!    

sbit Beep =  P0^0 ;             // 要根據(jù)實(shí)際的接線來(lái)修改
   
unsigned char n = 0;  //n為節(jié)拍常數(shù)變量    
unsigned char code music_tab[] = 
{   
    0x18, 0x30, 0x1C , 0x10, //格式為: 頻率常數(shù), 節(jié)拍常數(shù), 頻率常數(shù), 節(jié)拍常數(shù),    
    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定時(shí)控制的是音樂(lè)的節(jié)拍(某一個(gè)音節(jié)持續(xù)的時(shí)間)而不管音調(diào)(頻率)
 // 音調(diào)是直接使用delay做出來(lái)的。
void int0()  interrupt 1   //采用中斷0 控制節(jié)拍    
{  
    TH0 = 0xd8;   
    TL0 = 0xef;   
    n--;   
}   
   
void delay (unsigned char m)   //控制頻率延時(shí)    
{   
    unsigned i = 3 * m;   
    while (--i);   
}   
   
void delayms(unsigned char a)  //豪秒延時(shí)子程序    
{   
    while (--a);                  //采用while(--a) 不要采用while(a--); 各位可編譯一下看看匯編結(jié)果就知道了!    
}   
   
void main()   
{ 
    unsigned char p, m;   // m為頻率常數(shù)變量    
    unsigned char i = 0;   

    TMOD &= 0x0f;   
    TMOD |= 0x01;       // timer0 工作在模式1,16位定時(shí)器下 
    TH0 = 0xd8;
    TL0 = 0xef;         // 這個(gè)TH和TL的值合起來(lái)定了1個(gè)10ms左右的一個(gè)時(shí)間
    IE = 0x82;   
play:   
    while (1)   
    {   
a:      p = music_tab[i];   
        if (p == 0x00)          // 一遍播放完了,延時(shí)1s后自動(dòng)開(kāi)始下一遍    
        { 
            i=0, delayms(1000); 
            goto play;
        }     //如果碰到結(jié)束符,延時(shí)1秒,回到開(kāi)始再來(lái)一遍    
        else if (p == 0xff)  
        { 
            i = i + 1;
            delayms(100), TR0 = 0; 
            goto a;
        }  //若碰到休止符,延時(shí)100ms,繼續(xù)取下一音符    
        else         
        {
            m = music_tab[i++], n = music_tab[i++];
        }  // m取頻率常數(shù) 和 n取節(jié)拍常數(shù)    
        TR0 = 1;                              //開(kāi)定時(shí)器1    
        while (n != 0)
        { 
            Beep = ~Beep;
            delay(m);           //等待節(jié)拍完成, 通過(guò)P1口輸出音頻(可多聲道哦!)    
        }
        TR0 = 0;                            //關(guān)定時(shí)器1    
    }   
}
  
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容