类型�他广泛应用于计算机、打印机、复印机、报警器、电话机等电子产品中作发声器件。
单片机上面使用的蜂鸣器一般都是无源电磁式的蜂鸣器�如下图所示�。它由振荡器、
电磁线圈、磁铁、振动膜片及外壳等组成。接通电源后�振荡器产生的音频信号电流通过电
磁线圈�使电磁线圈产生磁场�振动膜片在电磁线圈和磁铁的相互作用下�周期性地振动发声。
蜂鸣器发声原理是电流通过电磁线圈�使电磁线圈产生磁场来驱动振动膜发声的�因
此需要一定的电流才能驱动它�单片机IO引脚输出的电流较小�单片机输出的TTL电平基
本上驱动不了蜂鸣器�因此需要增加一个电流放大的电路。单片机与蜂鸣器连接如图
二所示。
图中�蜂鸣器的正极接到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 MOV DPTR,#S_PARA
MOVC A,@A+DPTR
MOV R5,A
NEXTCYC:
ACALL SOUND
DJNZ R5,NEXTCYC
RET
;查表取出1/8拍周期数,保存到R5
;==============================
;===========发声子程序===========
;==============================
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.的意思是低音�。
而对于音长�数值越大�响的越持久。
� 25H �. 19H
� 27H �. 1BH
� 29H �. 1DH
� 2AH �. 1FH
� 2CH �. 20H
� 2EH �. 22H
� 30H �. 24H
如果写出来的歌曲不是很像�多调试一下就可以了。
过单片机控制蜂鸣器唱歌
�1� 掌握单片机对蜂鸣器的控制原理
�2� 掌握定时器的编程方法
�3� 掌握使用单片机控制蜂鸣器发出不同声音的思路
蜂鸣器一端连VCC�另一端接三极管NPN的集电极�而单片机的I/O接NPN的基极�这
样当单片机输出高电平‘0’时�基极为地电平时�三极管导通�有电流从蜂鸣器流过�蜂鸣
器发声。单片机控制蜂鸣器发出不同声音�即控制蜂鸣器发音的频率和控制蜂鸣器发音时间
的长短。�图中的三极管是8550�它是PNP型的低点平导通。图中的符号是错误的�
4� 实验原理图
;WWW.MCUBOOK.COM 为你搜集而来。欢迎浏览其他页。
5�实验源程序
ORG 0000H
LJMP START
ORG 000BH
CLR P2.1
INC 20H ;中断服务,中断计数器加1
MOV TH0,#0D8H
MOV TL0,#0EFH ;12M晶振�形成10毫秒中断
RETI
START:
MOV SP,#50H
MOV TH0,#0D8H
MOV TL0,#0EFH
MOV TMOD,#01H
MOV IE,#82H
MUSIC0:
NOP
MOV DPTR,#DAT ;表头地址送DPTR
MOV 20H,#00H ;中断计数器清0
MOV B,#00H ;表序号清0
MUSIC1:
NOP
CLR A
MOVC A,@A+DPTR ;查表取代码
JZ END0 ;是00H,则结束
CJNE A,#0FFH,MUSIC5
LJMP MUSIC3
MUSIC5:
NOP
MOV R6,A
INC DPTR
MOV A,B
MOVC A,@A+DPTR ;取节拍代码送R7
MOV R7,A
SETB TR0 ;启动计数
MUSIC2:
NOP
CPL P1.1
MOV A,R6
MOV R3,A
LCALL DEL
MOV A,R7
CJNE A,20H,MUSIC2 ;中断计数器(20H)=R7否?
;不等,则继续循环
MOV 20H,#00H ;等于,则取下一代码
INC DPTR
; INC B
LJMP MUSIC1
MUSIC3:
NOP
CLR TR0 ;休止100毫秒
MOV R2,#0DH
MUSIC4:
NOP
MOV R3,#0FFH
LCALL DEL
DJNZ R2,MUSIC4
INC DPTR
LJMP MUSIC1
END0:
NOP
MOV R2,#64H ;歌曲结束,延时1秒后继续
MUSIC6:
MOV R3,#00H
LCALL DEL
DJNZ R2,MUSIC6
LJMP MUSIC0
DEL:
NOP
DEL3:
MOV R4,#02H
DEL4:
NOP
DJNZ R4,DEL4
NOP
DJNZ R3,DEL3
RET
NOP
DAT:
db 26h,20h,20h,20h,20h,20h,26h,10h,20h,10h,20h,80h,26h,20h,30h,20h
db 30h,20h,39h,10h,30h,10h,30h,80h,26h,20h,20h,20h,20h,20h,1ch,20h
db 20h,80h,2bh,20h,26h,20h,20h,20h,2bh,10h,26h,10h,2bh,80h,26h,20h
db 30h,20h,30h,20h,39h,10h,26h,10h,26h,60h,40h,10h,39h,10h,26h,20h
db 30h,20h,30h,20h,39h,10h,26h,10h,26h,80h,26h,20h,2bh,10h,2bh,10h
db 2bh,20h,30h,10h,39h,10h,26h,10h,2bh,10h,2bh,20h,2bh,40h,40h,20h
db 20h,10h,20h,10h,2bh,10h,26h,30h,30h,80h,18h,20h,18h,20h,26h,20h
db 20h,20h,20h,40h,26h,20h,2bh,20h,30h,20h,30h,20h,1ch,20h,20h,20h
db 20h,80h,1ch,20h,1ch,20h,1ch,20h,30h,20h,30h,60h,39h,10h,30h,10h
db 20h,20h,2bh,10h,26h,10h,2bh,10h,26h,10h,26h,10h,2bh,10h,2bh,80h
db 18h,20h,18h,20h,26h,20h,20h,20h,20h,60h,26h,10h,2bh,20h,30h,20h
db 30h,20h,1ch,20h,20h,20h,20h,80h,26h,20h,30h,10h,30h,10h,30h,20h
db 39h,20h,26h,10h,2bh,10h,2bh,20h,2bh,40h,40h,10h,40h,10h,20h,10h
db 20h,10h,2bh,10h,26h,30h,30h,80h,00H
END
因篇幅问题不能全部显示,请点此查看更多更全内容