利用单片机播放音乐存放几首歌

利用单片机播放音乐存放几首歌,第1张

利用单片机播放音乐存放三首歌。可以播放储存的三首歌曲,分别为《挥着翅膀的女孩》、《同一首歌》、《两只蝴蝶》,其他歌曲可以通过参考资料中的软件编码后写入单片机中,按键共有两个,一个是复位按键,按下后直接从第一首歌开始播放。另一个是暂停键,按下后暂停,指示灯点亮。

看起来数组应该是音乐数据,其中包括四种数据,就是休止符(每个100毫秒)、歌曲结束符、音阶(给出的是蜂鸣器的震荡周期)、一个音阶持续的时间长度。如果你的晶振是12MHz,按照定时器中断给Count加一来看,音阶持续的时间应该是以10毫秒为单位。 Play_Song函数要求给出参数i我的看法是这个i是指要播放第几段乐曲,i*217表示每段乐曲都是217个字节。本例中95数组只给出217个字节,所以只有一段乐曲,播放时需要给出参数i=0. if ( Temp1 == 0xFF ) //休止符 { TR0 = 0; Delay_xMs(100); } 所以休止符每个固定是100毫秒。 如果读到第一个不是休止符或者结束符的字节那就是音阶,而下一个字节就是这个音阶的长度或者说节拍 while(1) { FMQ = ~FMQ; Delay_xMs(Temp1); if ( Temp2 == Count ) { Count = 0; break; } } 这一段是说,如果当前音阶的时间(Temp2次定时器中断,由Count计时)还没完,就每隔Temp1毫秒震动一次蜂鸣器,就形成一个震动频率,这段时间就发出一定音调的乐音不过我也有疑惑,震荡周期如果以毫秒为单位恐怕只能发出次声波,所以以上对有关Delay_xMs函数时间的估算都可能有问题907还得看Delay_xMs函数的具体定义才行。

一般而言音乐的播放是用定时器来控制的,比如用外部中断0来控制音乐的启停,定时器0控制的是音乐频率,那么大概程序如下:

#include

sbit

p32=p3^2;

void

ext0()

interrupt

0

{

while(p32==0);

tr0=~tr0;

}

main()

{

initt0();//定时器初始化

ex0=1;

ea=1;

it0=1;

}

NUM EQU 30H

UP EQU P36

DN EQU P37

ORG     0000H

AJMP    START           ;Fosc=12MHz

ORG     000BH           ;T0 中断入口地址

AJMP    INT_T0

ORG     001BH           ;T1 中断入口地址

AJMP    INT_T1

START:

MOV  SP, #60H

MOV TMOD, #11H

MOV IE, #8AH 

MOV IP, #08H          ;T1中断优先于T0中断

MOV TH1, #3CH

MOV TL1, #0BH        ;以上为系统初始化,T=60ms

W1: MOV P2, #01110001B    ;等待提示"F" ,01110001

LCALL GETKEY

CJNE  A, #0FFH, W1  

MOV  A, B

CJNE    A, #0AH, W2

LCALL   KEY_A            ;输入键是'A',转KEY_A

SJMP W1

W2: CJNE A, #0BH, W3

LCALL   KEY_B           ;输入键是'B',转KEY_B

W3: CJNE A, #0CH, W4

LCALL   KEY_C           ;输入键是'C',转KEY_C

W4: CJNE A, #0DH, W5

LCALL   KEY_D

    SJMP W1                ;输入键是'D',转KEY_D

W5: CJNE A,#0EH,W6 ;下一首

INC NUM

MOV A,NUM

CJNE A,#4,W51

W51:

JC W52

MOV NUM,#0

W52:

MOV A,NUM

SJMP D0

W6: CJNE A,#0FH,W7 ;上一首

MOV A,NUM

JNZ W61

MOV NUM,#4

W61:

DEC NUM

MOV A,NUM

SJMP D0

W7:

SJMP W1

KEY_A:                        ;从1~4按顺序播放

LCALL MUSIC1      ;乐曲《我和你》

LCALL MUSIC2       ;乐曲《万水千山总是情》

LCALL MUSIC3               ;乐曲《送别》

LCALL MUSIC4               ;乐曲《北京欢迎您》

RET

KEY_B:                         ;从1~4循环播放

T11: LCALL KEY_A

SJMP T11

RET

KEY_C:                        ;循环播放某一乐曲

T3: LCALL GETWORD

CJNE A, #0FFH, T3

MOV A, B

D0:

JNZ D1

SJMP E0

D1: DEC A

JNZ D2

SJMP E1

D2: DEC A

JNZ E3

SJMP E2

E0: LCALL MUSIC1            ;乐曲《我和你》

SJMP E0

E1: LCALL MUSIC2           ;乐曲《万水千山总是情》

SJMP E1

E2: LCALL MUSIC3           ;乐曲《送别》

SJMP E2

E3: LCALL MUSIC4           ;乐曲《北京欢迎您》

SJMP E3

RET

KEY_D:                      ;从某一乐曲开始播放,播放完后停止

T2: LCALL GETWORD

CJNE A, #0FFH, T2

MOV A, B

CJNE A, #00H, B1

SJMP C0

B1: CJNE A, #01H, B2

SJMP C1

B2: CJNE A, #02H, C3

SJMP C2

C0: LCALL MUSIC1               ;乐曲《我和你》

C1: LCALL MUSIC2               ;乐曲  《万水千山总是情》 

C2: LCALL MUSIC3               ;乐曲《送别》

C3: LCALL MUSIC4               ;乐曲《北京欢迎您》

RET

MUSIC1:                         ;第一首《我和你》

MOV  P2, #00000110B  ;显示1,00000110

MOV  R5, #11111001B

MOV  52H, #HIGH TABLE10

    MOV  53H, #LOW TABLE10

MOV NUM,#0

LCALL  music

RET

MUSIC2:     ;第二首《万水千山总是情》

MOV P2, #01011011B           ;显示2,01011011

MOV R5, #10100100B

MOV  52H, #HIGH TABLE20

    MOV  53H, #LOW TABLE20 

MOV NUM,#1

    LCALL  music

RET

MUSIC3:                   ;第三首《送别》

MOV P2, #01001111B   ;显示3,01001111

MOV R5, #10110000B

MOV  52H, #HIGH TABLE30

    MOV  53H, #LOW TABLE30 

MOV NUM,#2

    LCALL  music

RET

MUSIC4:                         ;第四首《北京欢迎您》

MOV P2, #01100110B     ;显示4,01100110

MOV R5, #10011001B

MOV  52H, #HIGH TABLE40

    MOV  53H, #LOW TABLE40 

MOV NUM,#3

    LCALL  music

RET 

music: MOV R3,#00H           ;音乐解码器

NEXT20:

MOV A,P3

ORL A,#0C0H

MOV P3,A

MOV A,P3

CPL A

ANL A,#0C0H

JZ NEXT21

POP ACC

POP ACC

LJMP W1

RET

NEXT21:

     MOV   A, R3

 MOV  DPH, 52H

 MOV  DPL, 53H

 MOVC A, @A+DPTR

 MOV  R2, A

 JZ  STOP

 ANL  A, #0FH

 MOV  R1, A

 MOV  A, R2

 SWAP  A

 ANL  A, #0FH

 JNZ  SING

 CLR  TR0

 JMP  W11

;----------------------------------------------------------

SING:

DEC  A

MOV  22H, A

RL   A

MOV  DPTR, #TABLE00

MOVC  A, @A+DPTR

MOV  TH0, A

MOV  21H, A

MOV  A, 22H

RL  A

INC  A

MOVC  A, @A+DPTR

MOV  TL0, A

MOV  20H, A

SETB  TR0

SETB   TR1

W11: 

LCALL  DELAY3

INC  R3

LJMP  NEXT20

;-----------------------------------------------------------

STOP:

CLR  TR0

CLR  TR1

    RET

;

;定时器0中断子程序

;

INT_T0: 

CLR  TR0

MOV  TL0, 20H

MOV  TH0, 21H

CPL  P30

SETB TR0

RETI

;

;定时器1中断子程序

;

INT_T1: 

CLR  TR1

CLR  TR0

LCALL KEY_E

MOV  TH1, #3CH

  MOV  TL1, #0BH

DJNZ  60H, OUT

    MOV  60H, #20

OUT:

SETB TR1

RETI                      

KEY_E:

JB P31, L2              ;中断键盘检测

LCALL DELAY2           ;消除抖动

JB  P31, L2           ;如果是高电平就跳到L2

JNB   P31, $           ;如果仍然是低电平就执行中断程序

MOV P2, #0111100B        ;让LED显示E,01111001

L3: JB P31, $           ;检测低电平,直到低电平时才跳出该指令

LCALL DELAY2

JB P31, L3

JNB  P31, $           ;如果再来一个高电平才跳出中断

MOV P2,R5

L2: SETB  TR0

RET

GETKEY:                ;读A B C D键盘子程序 

SA: JB P10, SB            ;读A,是高电平表示没有按键,跳转到SB

LCALL DELAY2

JB P10, SA

JNB  P10, $

MOV P2, #01110111B     ;显示A,01110111

MOV R5, #10001000B

MOV A, #0FFH

MOV B, #0AH

RET

SB: JB P11, C11              ;读B,是高电平表示没有按键按下,跳转到C11

LCALL DELAY2

JB P11, SB

JNB P11, $

MOV P2, #01111100B        ;显示B,01111100

MOV R5, #10000011B

MOV A, #0FFH

MOV B, #0BH

RET

C11:JB P12, ED1        ;读C

LCALL DELAY2

JB  P12, C11

JNB  P12, $

MOV P2, #00111001B ;显示C,00111001

MOV R5, #11000110B

MOV A, #0FFH

MOV B, #0CH

RET

ED1:

JB P13, L0             ;读D

LCALL DELAY2

JB  P13, ED1

JNB   P13, $

MOV P2, #01011110B   ;显示D,01011110

MOV R5, #10100001B

MOV A, #0FFH

MOV B,  #0DH

L0: JB UP,L01

LCALL DELAY2

JB UP,L01

JNB UP,$

MOV A,#0FFH

MOV B,#0EH

RET

L01:

JB DN,L02

LCALL DELAY2

JB DN,L02

JNB DN,$

MOV A,#0FFH

MOV B,#0FH

L02:

RET

GETWORD:                     ;读音乐序号子程序

S1: JB P14, S2         ;读1键

LCALL DELAY2

JB P14, S1

JNB P14, $

MOV P2, #00000110B    ;显示1

MOV R5, #11111001B

MOV A, #0FFH

MOV B, #00H

RET

S2: JB P15, S3            ;读2键

LCALL DELAY2

JB P15, S2

JNB P15, $

MOV P2, #01011011B    ;显示2

MOV R5, #10100100B

MOV A, #0FFH

MOV B, #01H

RET

S3: JB P16,S4           ;读3键

LCALL DELAY2

JB P16,S3

JNB P16,$

MOV P2,#01001111B    ;显示3

MOV R5,#10110000B

MOV A,#0FFH

MOV B,#02H

RET

S4: JB P17, L1           ;读4键

LCALL DELAY2

JB P17, S1

JNB P17, $

MOV P2, #01100110B ;显示4

MOV R5, #10011001B

MOV A, #0FFH

MOV B, #03H

L1: RET

DELAY:                          ;延时子程序

        PUSH    0               ;保存现场

        PUSH    1

        MOV     0, #0H

DELAY1: MOV     1, #0H

        DJNZ    1, $

        DJNZ    0, DELAY1

        POP     1               ;恢复现场

        POP     0

        RET

DELAY2: MOV 41H, #100        ;延时子程序2

F1: MOV 42H, #250

DJNZ 42H, $

DJNZ 41H, F1

RET

DELAY3:           ;延时子程序3 

MOV  R7, #2

W22: MOV  R4, #125

W33: MOV  R0, 248

DJNZ  R0, $

DJNZ  R4, W33

DJNZ  R7, W22

DJNZ  R1, DELAY3

RET

TABLE00:                       ;频率表

DW 64260,64400,64524,64580          ;简码值 低音5, 低音6, 低音7,1

DW 64684,64777,64820,64898          ; 简码值 2,3,4,5

DW 64968,65030,65058,65110          ; 简码值 6,7,高音1,高音

        DW 65157,65178,65217            ;简码值 高音3,高音4,高音5

;--------------------------------------------------------------------

;第一首《我和你》

;--------------------------------------------------------------------

TABLE10: DB 64H,82H,42H,48H

DB 54H,64H,18H

DB 44H,54H,64H,84H

DB 5CH

DB 64H,84H,44H,04H,42H

DB 54H,64H,28H

DB 54H,14H,54H,64H

DB 4CH

DB 98H,88H

DB 98H,48H

DB 64H,24H,64H,84H

DB 5CH

DB 64H,82H,42H,48H

DB 54H,64H, 28H

DB 54H,14H,54H,34H

DB 4CH

DB 00H

;--------------------------------------------------------------------

;第二首《万水千山总是情》

;--------------------------------------------------------------------

TABLE20: DB 64H,74H,84H,04H,82H,94H,84H,6CH

DB 54H,44H,04H,62H,54H,44H,2CH

DB 24H,18H, 44H,54H,64H,84H,94H,64H,5CH

DB 64H,74H,84H,04H,82H,94H,84H,6CH

DB 54H,44H,04H,62H,54H,44H,2CH

DB 24H,18H, 44H,64H,54H,04H,42H,24H,44H,4CH

DB 64H,84H,9CH,0A4H,94H,74H,84H,04H,92H,8CH,64H,88H

DB 64H,84H,9CH,0A4H,0A4H,94H,84H,64H,5CH

DB 64H,74H, 84H,04H,82H,94H,84H,6CH

DB 54H,44H,04H,62H,54H,44H,2CH

DB 24H,18H,44H,64H,54H,42H,24,44H,4CH

DB 00H

;--------------------------------------------------------------------

;第三首《送别》

;--------------------------------------------------------------------

TABLE30:   DB 84H,62H,82H,0B8H

DB 94H,0B2H,92H,88H

DB 84H,42H,52H,64H,52H,44H

        DB 5CH

        DB 84H,62H,82H,0B4H,04H,82H

DB 94H,0B4H, 88H

DB 84H,52H,62H,74H,04H,32H

DB 4CH

DB 94H,0B4H,0B8H

DB 0A4H,92H,0A2H,0B8H

DB 92H,0A2H,0B2H,92H,92H,82H,62H,42H

DB 5CH

DB 84H,62H,82H,0B4H,04H,0A2H

DB 94H,0B4H,88H

DB 84H,52H,62H,74H,04H,32H

DB 4CH

DB 00H

;--------------------------------------------------------------------

;第四首《北京欢迎您》

;--------------------------------------------------------------------

TABLE40:    DB 62H,82H,62H,52H,12H

DB 62H,52H,12H,64H

DB 62H,52H,22H,42H 

DB 62H,54H

DB 52H,42H,22H,42H

DB 52H,62H,82H,52H

DB 62H,92H,82H,12H

DB 52H,44H

DB 52H,42H,22H,42H

DB 52H,62H,82H,52H

DB 62H,92H,82H,82H

DB 68H

DB 52H,62H,52H,42H

DB 82H,92H,64H

DB 22H,62H,64H

DB 54H,64H

DB 64H,84H

DB 0B2H,82H,94H

DB 02H,92H,82H,62H

DB 62H, 82H,88H

DB 00H

END

单片机发音原理:利用定时器或PWM功能,输出PWM,经一级有源滤波后放大驱动扬声器。

单片机演奏音乐基本是单音频率,它不包含相应幅度的谐波频率,

也就是说不能象电子琴那样能奏出多种音色的声音,但一定要弄清楚两个概念即可,也就是“音调”和“节拍” 。音调 表示一个音符唱多高的频率。节拍 表示一个音符唱多长的时间

1要生产音频脉冲,只要算出某一音频的周期(1/频率),然后将此周期除以2,即为半周期的时间利用定时器计时这个半周期时间,每当计时到后就将输出脉冲的I/O反相,然后重复计时此半周期时间再对I/O反相,就可在I/O脚上得到此频率的脉冲。

2 利用8051的内部定时器使用其工作在计数器模式MODE1下,改变计数值THO及TLO以产生不同频率的方法。

#include "reg51h"

#define uint unsigned int

#define uchar unsigned char

uchar TABLE ;

code uint TABLE1 [15]={64260,64400,64524,64580,

64684,64777,64820,64898,

64968,65030,65058,65110,

65157,65178,65217};

code uchar SONG [ ]={

//1 迟来的爱

};

code uchar SONG1 [ ]={

//2两只蝴蝶

};

code uchar SONG3 [ ]={

//4一个师傅三个徒弟

};

uchar hjsz;

uchar ljsz;

uchar jpm;

uchar yfm;

uchar t0 =0;

uint i=0;

sbit Speaker =P1^0;

uint k;

void Delay1()

{

for ( k=0;k<20000;k++);

}

void Lignt( )

{ uchar t;

for(t=0;t<10;t++)

{

P2=0xff;

Delay1();

P2=0x00;

Delay1();

}

}

void Lignt1( )

{

P2=0xaa;

Delay1();

P2=0x55;

Delay1();

}

void Delay(uchar t0)//延时

{

while(t0--) //决定节拍

Lignt1();

}

void Delay2(uchar w0)//延时

{

while(w0--) //决定节拍

Lignt();

}

void T0Int() interrupt 1//TIMER0

{

TL0 = ljsz;

TH0 = hjsz;

Speaker=!Speaker;

}

void ExtInt0() interrupt 0//INT0

{

if(t0>10)

t0=0;

i=0; // 全局变量,指向歌谱的第1个

switch(t0++)

{

case 0 : TABLE=SONG;break; //选择第1首

case 1 : TABLE=SONG1;break;//选择第2首

case 2 : TABLE=SONG2;break;//选择第3首

case 3 : TABLE=SONG3;break;//选择第4首

case 4 : TABLE=SONG4;break;//选择第5首

case 5 : TABLE=SONG5;break;//选择第6首

case 6 : TABLE=SONG6;break;//选择第7首

case 7 : TABLE=SONG7;break;//选择第8首

case 8 : TABLE=SONG8;break;//选择第9首

case 9 : TABLE=SONG9;break;//选择第10首

}

}

void songsing()//发音程序

{

i=0;

while(TABLE[i])

{

jpm=TABLE[i]&0x0f; //节拍值

yfm=(TABLE[i]>>0x04)&0x0f;//简谱值

if(yfm) //简谱为1,取计数值

{

yfm=yfm-1;

hjsz=(uchar)(TABLE1[yfm]>>0x08);//取计数值高字节

TH0 = hjsz;

ljsz=(uchar)(TABLE1[yfm]); //取计数值低字节

TL0 = ljsz;

TR0 = 1; //启动TIMER0

}

else TR0 = 0; //简谱为0,不发音

Delay(jpm); //节拍延时

i++;

}

}

void main(void)

{

TMOD =0X01;//设TIMER0在MODE1

TCON =0X01;//外部中断INT0,下降沿触发

IE =0x83;//开中断(INT0,TIMER0)

IP =0x00;//设置中断优先级

TABLE=SONG0;

while(1)

{

Lignt( );

songsing();//调用发音程序

TR0 = 0;//停止TIMER0

Delay2(1);

TABLE=SONG0;// 更改歌曲0

songsing();

}

}

以上就是关于利用单片机播放音乐存放几首歌全部的内容,包括:利用单片机播放音乐存放几首歌、msp430g2553单片机控制蜂鸣器发出音乐的程序、单片机怎么用C语言实现音乐暂停和播放功能等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zz/9307881.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-27
下一篇2023-04-27

发表评论

登录后才能评论

评论列表(0条)

    保存