用51单片机实现音乐播放的原理是什么

用51单片机实现音乐播放的原理是什么,第1张

需要写一段程序。

如果是简单的音乐,编乐谱推蜂鸣器就可以;如果是mp3/wav之类的音乐,需要芯片自带解码模块,或者使用外部解码芯片,还需要dac将声音推出来。

声音的频谱范围约在几十到几千赫兹,若能利用程序来控制单处机某个口线的“高”电平或低电平,则在该口线上就能产生一定频率的矩形波,接上喇叭就能发出一定频率的声音,若再利用延时程序控制“高”“低”电平的持续时间,就能改变输出频率,从而改变音调。要准确奏出一首曲子,必须准确地控制乐曲节奏,即一音符的持续时间。音符的节拍我们可以用定时器T0来控制,送入不同的初值,就可以产生不同的定时时间。便如某歌曲的节奏为每分钟94拍,即一拍为064秒。

程序名: MCS51U实验板配套程序-歌曲:兰花草

;电路介绍:蜂鸣器接P20;实验前要连接J12

;

OUT BIT P20

ORG 0

AJMP START

ORG 0BH

AJMP TIM0

START: MOV TMOD,#1

MOV IE,#10000010B

START0: MOV 30H,#0

NEXT: MOV A,30H

MOV DPTR,#TABLE

MOVC A,@A+DPTR

MOV R2,A

JZ END0

ANL A,#0FH

MOV R5,A

MOV A,R2

SWAP A

ANL A,#0FH

JNZ SING

CLR TR0

AJMP D1

SING: DEC A

MOV 22H,A

RL A

MOV DPTR,#TABLE1

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

D1: CALL DELAY

INC 30H

AJMP NEXT

END0: CLR TR0

AJMP START0

TIM0: PUSH ACC

PUSH PSW

MOV TL0,20H

MOV TH0,21H

CPL OUT

POP PSW

POP ACC

RETI

DELAY: MOV R7,#2

D2: MOV R4,#125

D3: MOV R3,#248

DJNZ R3,$

DJNZ R4,D3

DJNZ R7,D2

DJNZ R5,DELAY

RET

;====================================

TABLE1: DW 64021,64103,64260,64400

DW 64524,64580,64684,64777

DW 64820,64898,64968,65030

DW 64934

TABLE: ;1

DB 42H,82H,82H,82H,84H,02H,72H

DB 62H,72H,62H,52H,48H

DB 0B2H,0B2H,0B2H,0B2H,0B4H,02H,0A2H

;2

DB 12H,0A2H,0D2H,92H,88H

DB 82H,0B2H,0B2H,0A2H,84H,02H,72H

DB 62H,72H,62H,52H,44H,02H,12H

;3

DB 12H,62H,62H,52H,44H,02H,82H

DB 72H,62H,52H,32H,48H

DB 00H

END

我自己理解:

1,可能是通过C51单片机的 一个IO口或者几个IO口控制LED闪,达到闪的频率控制;

2,可能是通过C51单片机的 一个IO口或者几个IO口控制输出一串音乐曲谱,并接入LED提示;

以上第二种可能高,但不可能是楼所说还要什么AD,没有必要。

将51单片机的P12口连接到蜂鸣器的一个管脚上,另外一个管脚接地。若声音小,则添加一个三级管放大电路或直接串一个UL2003

/------------------------------------------------/

includelt;reg52h; //包含头文件,一般情况不需要改动

//头文件包含特殊功能寄存器的定义

/------------------------------------------------

硬件端口定义

------------------------------------------------/

sbit SPK=P1^2; //定义音乐输出端口

unsigned char Timer0_H,Timer0_L,Time;

//世上只有妈妈好数据表

code unsigned char MUSIC[]={ 6,2,3, 5,2,1, 3,2,2, 5,2,2, 1,3,2, 6,2,1, 5,2,1,

6,2,4, 3,2,2, 5,2,1, 6,2,1, 5,2,2, 3,2,2, 1,2,1,

6,1,1, 5,2,1, 3,2,1, 2,2,4, 2,2,3, 3,2,1, 5,2,2,

5,2,1, 6,2,1, 3,2,2, 2,2,2, 1,2,4, 5,2,3, 3,2,1,

2,2,1, 1,2,1, 6,1,1, 1,2,1, 5,1,6, 0,0,0

};

// 音阶频率表 定时器高八位

code unsigned char FREQH[]={

0xF2,0xF3,0xF5,0xF5,0xF6,0xF7,0xF8,

0xF9,0xF9,0xFA,0xFA,0xFB,0xFB,0xFC,0xFC, //1,2,3,4,5,6,7,8,i

0xFC,0xFD,0xFD,0xFD,0xFD,0xFE,

0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFF,

} ;

// 音阶频率表 定时器低八位

code unsigned char FREQL[]={

0x42,0xC1,0x17,0xB6,0xD0,0xD1,0xB6,

0x21,0xE1,0x8C,0xD8,0x68,0xE9,0x5B,0x8F, //1,2,3,4,5,6,7,8,i

0xEE,0x44, 0x6B,0xB4,0xF4,0x2D,

0x47,0x77,0xA2,0xB6,0xDA,0xFA,0x16,

};

/------------------------------------------------

uS延时函数,含有输入参数 unsigned char t,无返回值

unsigned char 是定义无符号字符变量,其值的范围是

0~255 这里使用晶振12M,精确延时请使用汇编,大致延时

长度如下 T=tx2+5 uS

------------------------------------------------/

void DelayUs2x(unsigned char t)

{

while(--t);

}

/------------------------------------------------

mS延时函数,含有输入参数 unsigned char t,无返回值

unsigned char 是定义无符号字符变量,其值的范围是

0~255 这里使用晶振12M,精确延时请使用汇编

------------------------------------------------/

void DelayMs(unsigned char t)

{

while(t--)

{

//大致延时1mS

DelayUs2x(245);

DelayUs2x(245);

}

}

/------------------------------------------------

节拍延时函数

各调1/4节拍时间:

调4/4 125ms

调2/4 250ms

调3/4 187ms

------------------------------------------------/

void delay(unsigned char t)

{

unsigned char i;

for(i=0;ilt;t;i++)

DelayMs(250);

TR0=0;

}

/------------------------------------------------

定时器0中断

------------------------------------------------/

void TIM0_ISR() interrupt 1

{

TR0=0;

SPK=!SPK;

TH0=Timer0_H;

TL0=Timer0_L;

TR0=1;

}

/------------------------------------------------

歌曲处理函数

------------------------------------------------/

void Song()

{

TH0=Timer0_H;//赋值定时器时间,决定频率

TL0=Timer0_L;

TR0=1; //打开定时器

delay(Time); //延时所需要的节拍

}

/------------------------------------------------

主函数

------------------------------------------------/

void main(void)

{

unsigned char k,i;

TMOD=0x01; //置定时器0工作方式1

EA=1; //打开全局中断

ET0=1; //打开定时0中断

while(1)

{

i=0;

while(ilt;100)

{ //音乐数组长度 ,唱完从头再来

k=MUSIC[i]+7MUSIC[i+1]-1;//去音符振荡频率所需数据

Timer0_H=FREQH[k];

Timer0_L=FREQL[k];

Time=MUSIC[i+2]; //节拍时长

i=i+3;

Song();

}

}

}

1、音乐频谱程序不通用,不同的音乐对应不同的编码,所以给你你也没法改造!

2、告诉你最快捷的方法就是百度上下载一个单片机音乐代码生成器,把你想要的音乐对照的乐谱输到软件里面,然后生成就出来代码,输入的是音符,输出的是完整代码,直接下载到单片机就可以使用。

3、还可以自己编写,找到低中高的dao,ran,mi,fa,sao,la,xi的频率,自己在定时器写个不断改变频率的定时,输出不同的频率就可以了!

希望可以帮到你,如果满意,请采纳!

这是我写的一段,不用照抄,知道方法改造很快!

#include <reg52h>

#define uchar unsigned char

#define uint unsigned int

sbit BEEP = P3^7;

uchar code SONG_TONE[]=

{

212,212,190,212,159,169,212,212,190,212,142,159,212,212,106,126,129,169,190,119,119,126,159,142,159,0

};

uchar code SONG_LONG[]=

{

9,3,12,12,12,24,9,3,12,12,12,24,9,3,12,12,12,12,12,9,3,12,12,12,24,0

};

void DelayMS(uint ms)

{

uchar t;

while(ms--)

{

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

}

}

void PlayMusic()

{

uint i =0,j,k;

while(SONG_LONG[i]!=0||SONG_TONE[i]!=0)

{

for(j=0;j<SONG_LONG[i]20;j++)

{

BEEP = ~BEEP;

for(k=0;k<SONG_TONE[i]/3;k++);

}

DelayMS(10);

i++;

}

}

void main()

{

while(1)

{

PlayMusic();

DelayMS(500);

}

}

以上就是关于用51单片机实现音乐播放的原理是什么全部的内容,包括:用51单片机实现音乐播放的原理是什么、单片机蜂鸣器c语言《兰花草》音乐代码、C51单片机关于如何制作LED频谱问题等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

原文地址: https://outofmemory.cn/zz/9347854.html

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

发表评论

登录后才能评论

评论列表(0条)

保存