原创 用单片机驱动蜂鸣器唱歌

2009-6-2 22:24 5563 7 7 分类: MCU/ 嵌入式

蜂鸣器是一种一体化结构的电子讯响器,主要分为压电式蜂鸣器和电磁式蜂鸣器两种类型,他广泛应用于计算机、打印机、复印机、报警器、电话机等电子产品中作发声器件。


单片机上面使用的蜂鸣器一般都是无源电磁式的蜂鸣器(如下图所示)。它由振荡器、电磁线圈、磁铁、振动膜片及外壳等组成。接通电源后,振荡器产生的音频信号电流通过电磁线圈,使电磁线圈产生磁场,振动膜片在电磁线圈和磁铁的相互作用下,周期性地振动发声。


 9f07c2db-7734-4c11-9b8c-77097aca3bd0.gif


蜂鸣器发声原理是电流通过电磁线圈,使电磁线圈产生磁场来驱动振动膜发声的,因此需要一定的电流才能驱动它,单片机IO引脚输出的电流较小,单片机输出的TTL电平基本上驱动不了蜂鸣器,因此需要增加一个电流放大的电路。单片机与蜂鸣器连接如图二所示。


8635c227-3aab-4d4d-825b-88f1b4a1c7e7.gif


图中,蜂鸣器的正极接到VCC(+5V)电源上面,蜂鸣器的负极接到三极管的发射极E,三极管的基级B经过限流电阻R1后由单片机的P3.7引脚控制,当P3.7输出高电平时,三极管T1截止,没有电流流过线圈,蜂鸣器不发声;当P3.7输出低电平时,三极管导通,这样蜂鸣器的电流形成回路,发出声音。因此,我们可以通过程序控制P3.7脚的电平来使蜂鸣器发出声音和关闭。


程序中改变单片机P3.7引脚输出波形的频率,就可以调整控制蜂鸣器音调,产生各种不同音色、音调的声音。另外,改变P3.7输出电平的高低电平占空比,则可以控制蜂鸣器的声音大小,这些我们都可以通过编程实验来验证。


  下面就是一个能够发出音乐的单片机程序,示例中所播放的音乐是《两只老虎》。



    SPK EQU P3.7                       ;位定义
    ORG      0000H                       ;伪指令,指定程序从0000H开始存放
    LJMP     START                      ;程序跳转至START处执行
    ORG      0030H                       ;伪指令,指定程序从0030H开始存放
START:      MOV    SP,#60H        ;堆栈初始化
    MOV      R3,#00H                    ;给R3赋值
NEXT:
    MOV       A,R3
    MOV       DPTR,#TABLE         ;查歌曲表
    MOVC     A,@A+DPTR
    JZ           START                    ;为00则循环播放此歌
    MOV       R7,A                       ;R7/R2保存连续相邻的表数据
    INC         R3
    MOV       A,R3
    MOVC     A,@A+DPTR
    MOV       R2,A
    ACALL    SONG
    INC         R3
    SJMP      NEXT
;==============================
;=========歌曲播放子程序==========
;==============================
SONG:
    MOV      A,R2                       ;取出节拍
    RL          A
    JNZ         KEEP                     ;A不等于零则跳
    MOV       A,#01H                   ;A等于零则赋值为1
KEEP:
    MOV       R2,A        ;
REPEAT:
    ACALL    EIGHTH                  ;调用1/8拍延时程序
    DJNZ       R2,REPEAT    ;
    RET
;===============================
;=======产生1/8拍延时子程序=======
;===============================
EIGHTH:
    MOV       A,R7                      ;查表取出延时参数,保存到R4
    MOV       DPTR,#DELAY_T
    MOVC     A,@A+DPTR
    MOV       R4,A
    MOV       A,R7                      ;查表取出1/8拍周期数,保存到R5
    MOV       DPTR,#S_PARA
    MOVC     A,@A+DPTR
    MOV       R5,A
NEXTCYC:
    ACALL   SOUND


    DJNZ      R5,NEXTCYC
    RET
;==============================
;===========发声子程序===========
;==============================
SOUND:
    SETB      SPK
    ACALL    SDELAY
    CLR        SPK
    ACALL    SDELAY
    RET
;==============================
;===========延时子程序===========
;==============================
SDELAY:
    MOV       A,R4                    ;延时值在R4内
    MOV       R0,A
XL2:
    MOV       R1,#03H
DL1:
    NOP
    DJNZ       R1,DL1
    DJNZ       R0,XL2
    RET
;==============================
;===========1/8拍周期表==========
;==============================
S_PARA:
DS    1DH
DB    15H,16H,00
DB    19H,00H,1CH,00H,1FH,21H,00H,25H
DB    00H,29H,2CH,00H,31H,34H,37H,00H
DB    3EH,41H,00H,49H,00H,52H,57H,00H
DB    62H
;==============================
;===========延时参数表===========
;==============================
DELAY_T:
DS    1DH
DB    7EH,77H,00H
DB    6AH,00H,5EH,00H,54H,4FH,00H,46H
DB    00H,3FH,3BH,00H,35H,32H,2FH,00H
DB    2AH,27H,00H,23H,00H,1FH,1DH,0C0H
DB    1AH
;==============================
;============歌曲表=============
;==============================
TABLE:
DW    2504H,2704H,2904H,2504H
DW    2504H,2704H,2904H,2504H
DW    2904H,2A04H,2C08H
DW    2904H,2A04H,2C08H
DW    2C02H,2E02H,2C02H,2A02H,2904H,2504H
DW    2C02H,2E02H,2C02H,2A02H,2904H,2504H
DW    2904H,2004H,2508H
DW    2904H,2004H,2508H
DW    0000H
END


童鞋们可能发现了,数据表TABLE里面的数据才是歌曲数据。也就是说,只要我们改变TABLE表里面的数据,就可以播放不同的歌曲了。比如下面这一首《兰花草》:




;==============================
;============歌曲表=============
;==============================

TABLE:
DW    2202H,2902H,2902H,2902H,2906H,2702H      ;我从山中来
DW    2502H,2702H,2502H,2402H,2208H                ;带着兰花草
DW    2E02H,2E02H,2E02H,2E02H,2E06H,2C02H   ;种在小园中
DW    2902H,2C02H,2D02H,2A02H,2908H               ;祈祷花开早
DW    2902H,2E02H,2E02H,2C02H,2906H,2702H     ;一日看三回
DW    2502H,2702H,2502H,2402H,2206H,1D02H      ;看得花时过
DW    1D02H,2502H,2502H,2402H,2206H,2902H      ;兰花却依然
DW    2702H,2502H,2402H,2002H,2208H                 ;苞也无一个
DW    0000H   
END   


在TABLE表里面的数据都是字类型的,也就是说可以拆分成2个DB数据。前一个DB数据,我们用来存放音色,也就是“dao.rai.mi.fa.sao.la.xi”;后一个DB我们用来存放音长,就是每个音的长度。


对于音色,可以查下面的表,数值越大,频率越高,音色也就越高(X.的意思是低音)。而对于音长,数值越大,响的越持久。



25H1.19H
27H2.1BH
29H3.1DH
2AH4.1FH
2CH5.20H
2EH6.22H
30H7.24H

如果写出来的歌曲不是很像,多调试一下就可以了。

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
7
关闭 站长推荐上一条 /3 下一条