您的当前位置:首页正文

基于单片机的蜂鸣器唱歌设计(附图)

2020-08-15 来源:钮旅网
 蜂鸣器是一种一体化结构的电子讯响器�主要分为压电式蜂鸣器和电磁式蜂鸣器两种

类型�他广泛应用于计算机、打印机、复印机、报警器、电话机等电子产品中作发声器件。

单片机上面使用的蜂鸣器一般都是无源电磁式的蜂鸣器�如下图所示�。它由振荡器、

电磁线圈、磁铁、振动膜片及外壳等组成。接通电源后�振荡器产生的音频信号电流通过电

磁线圈�使电磁线圈产生磁场�振动膜片在电磁线圈和磁铁的相互作用下�周期性地振动发声。

蜂鸣器发声原理是电流通过电磁线圈�使电磁线圈产生磁场来驱动振动膜发声的�因

此需要一定的电流才能驱动它�单片机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

因篇幅问题不能全部显示,请点此查看更多更全内容