单片机音乐程序代码

单片机音乐程序代码,第1张

T0H EQU 30H

T0L EQU 31H

ORG 0000H

LJMP MAIN

ORG 000BH

LJMP T0ISR

ORG 0030H

MAIN:

MOV SP,#5FH

MOV TMOD,#01H

SETB ET0

SETB EA

LOOP:

MOV DPTR,#FREQ

MOV A,P2 控制高中低音

MOV R1,#0

ANL A,#03H

JB ACC.0,LOOP01

MOV R1,#14

SJMP LOOP0

LOOP01:

JB ACC.1,LOOP0

MOV R1,#28

LOOP0:

JB P0.0,LOOP1 控制音频1234567

MOV A,R1

MOVC A,@A+DPTR

MOV T0H,A

INC DPTR

MOV A,R1

MOVC A,@A+DPTR

MOV T0L,A

LJMP LOOP

LOOP1:

JB P0.1,LOOP2

MOV A,R1

ADD A,#2

MOVC A,@A+DPTR

MOV T0H,A

INC DPTR

MOV A,R1

ADD A,#2

MOVC A,@A+DPTR

MOV T0L,A

LJMP LOOP

LOOP2:

JB P0.2,LOOP3

MOV A,R1

ADD A,#4

MOVC A,@A+DPTR

MOV T0H,A

INC DPTR

MOV A,R1

ADD A,#4

MOVC A,@A+DPTR

MOV T0L,A

LJMP LOOP

LOOP3:

JB P0.3,LOOP4

MOV A,R1

ADD A,#6

MOVC A,@A+DPTR

MOV T0H,A

INC DPTR

MOV A,R1

ADD A,#6

MOVC A,@A+DPTR

MOV T0L,A

LJMP LOOP

LOOP4:

JB P0.4,LOOP5

MOV A,R1

ADD A,#8

MOVC A,@A+DPTR

MOV T0H,A

INC DPTR

MOV A,R1

ADD A,#8

MOVC A,@A+DPTR

MOV T0L,A

LJMP LOOP

LOOP5:

JB P0.5,LOOP6

MOV A,R1

ADD A,#10

MOVC A,@A+DPTR

MOV T0H,A

INC DPTR

MOV A,R1

ADD A,#10

MOVC A,@A+DPTR

MOV T0L,A

LJMP LOOP

LOOP6:

JB P0.6,LOOP7

MOV A,R1

ADD A,#12

MOVC A,@A+DPTR

MOV T0H,A

INC DPTR

MOV A,R1

ADD A,#12

MOVC A,@A+DPTR

MOV T0L,A

LJMP LOOP

LOOP7:

CLR TR0

LJMP LOOP

-----------------------------

T0ISR:

CLR TR0

MOV TH0,T0H

MOV TL0,T0L

SETB TR0

CPL P3.0

RETI

-----------------------------

FREQ:

DB 0F2H,03DH 低音1

DB 0F3H,0BDH 低音2

DB 0F5H,014H 低音3

DB 0F5H,0B1H 低音4

DB 0F6H,0D0H 低音5

DB 0F7H,0D1H 低音6

DB 0F8H,0B5H 低音7

DB 0F9H,01EH 中音1

DB 0F9H,0DEH 中音2

DB 0FAH,08AH 中音3

DB 0FAH,0D8H 中音4

DB 0FBH,068H 中音5

DB 0FBH,0E8H 中音6

DB 0FCH,05AH 中音7

 

DB 0FCH,08FH 高音1

DB 0FCH,0EFH 高音2

DB 0FDH,045H 高音3

DB 0FDH,06CH 高音4

DB 0FDH,0B4H 高音5

DB 0FDH,0F4H 高音6

DB 0FEH,029H 高音7

-----------------------------

END

//此程序在硬件上调试通过

//本程序的单片机晶振采用11.0592M

#include <reg51.h>

sbit speaker=P1^2

unsigned char timer0h,timer0l,time

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

code unsigned char sszymmh[]={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,

}

void delay(unsigned char t)

{

unsigned char t1

unsigned long t2

for(t1=0t1<tt1++)

{

for(t2=0t2<8000t2++)

{

}

}

TR0=0

}

void t0int() interrupt 1

{

TR0=0

speaker=!speaker

TH0=timer0h

TL0=timer0l

TR0=1

}

void song()

{

TH0=timer0h

TL0=timer0l

TR0=1

delay(time)

}

void main(void)

{

unsigned char k,i

TMOD=1//置CT0定时工作方式1

EA=1

ET0=1//IE=0x82 //CPU开中断,CT0开中断

while(1)

{

i=0

while(i<100){ //音乐数组长度 ,唱完从头再来

k=sszymmh[i]+7*sszymmh[i+1]-1

timer0h=FREQH[k]

timer0l=FREQL[k]

time=sszymmh[i+2]

i=i+3

song()

}

}

}

#include <REG52.H>

#include "SoundPlay.h"

void Delay1ms(unsigned int count)

{

unsigned int i,j

for(i=0i<counti++)

for(j=0j<120j++)

}

unsigned char code Music_Two[] ={ 0x17,0x03, 0x16,0x03, 0x17,0x01, 0x16,0x03, 0x17,0x03,

0x16,0x03, 0x15,0x01, 0x10,0x03, 0x15,0x03, 0x16,0x02,

0x16,0x0D, 0x17,0x03, 0x16,0x03, 0x15,0x03, 0x10,0x03,

0x10,0x0E, 0x15,0x04, 0x0F,0x01, 0x17,0x03, 0x16,0x03,

0x17,0x01, 0x16,0x03, 0x17,0x03, 0x16,0x03, 0x15,0x01,

0x10,0x03, 0x15,0x03, 0x16,0x02, 0x16,0x0D, 0x17,0x03,

0x16,0x03, 0x15,0x03, 0x10,0x03, 0x15,0x03, 0x16,0x01,

0x17,0x03, 0x16,0x03, 0x17,0x01, 0x16,0x03, 0x17,0x03,

0x16,0x03, 0x15,0x01, 0x10,0x03, 0x15,0x03, 0x16,0x02,

0x16,0x0D, 0x17,0x03, 0x16,0x03, 0x15,0x03, 0x10,0x03,

0x10,0x0E, 0x15,0x04, 0x0F,0x01, 0x17,0x03, 0x19,0x03,

0x19,0x01, 0x19,0x03, 0x1A,0x03, 0x19,0x03, 0x17,0x01,

0x16,0x03, 0x16,0x03, 0x16,0x02, 0x16,0x0D, 0x17,0x03,

0x16,0x03, 0x15,0x03, 0x10,0x03, 0x10,0x0D, 0x15,0x00,

0x19,0x03, 0x19,0x03, 0x1A,0x03, 0x1F,0x03, 0x1B,0x03,

0x1B,0x03, 0x1A,0x03, 0x17,0x0D, 0x16,0x03, 0x16,0x03,

0x16,0x0D, 0x17,0x01, 0x17,0x03, 0x17,0x03, 0x19,0x03,

0x1A,0x02, 0x1A,0x02, 0x10,0x03, 0x17,0x0D, 0x16,0x03,

0x16,0x01, 0x17,0x03, 0x19,0x03, 0x19,0x03, 0x17,0x03,

0x19,0x02, 0x1F,0x02, 0x1B,0x03, 0x1A,0x03, 0x1A,0x0E,

0x1B,0x04, 0x17,0x02, 0x1A,0x03, 0x1A,0x03, 0x1A,0x0E,

0x1B,0x04, 0x1A,0x03, 0x19,0x03, 0x17,0x03, 0x16,0x03,

0x17,0x0D, 0x16,0x03, 0x17,0x03, 0x19,0x01, 0x19,0x03,

0x19,0x03, 0x1A,0x03, 0x1F,0x03, 0x1B,0x03, 0x1B,0x03,

0x1A,0x03, 0x17,0x0D, 0x16,0x03, 0x16,0x03, 0x16,0x03,

0x17,0x01, 0x17,0x03, 0x17,0x03, 0x19,0x03, 0x1A,0x02,

0x1A,0x02, 0x10,0x03, 0x17,0x0D, 0x16,0x03, 0x16,0x01,

0x17,0x03, 0x19,0x03, 0x19,0x03, 0x17,0x03, 0x19,0x03,

0x1F,0x02, 0x1B,0x03, 0x1A,0x03, 0x1A,0x0E, 0x1B,0x04,

0x17,0x02, 0x1A,0x03, 0x1A,0x03, 0x1A,0x0E, 0x1B,0x04,

0x17,0x16, 0x1A,0x03, 0x1A,0x03, 0x1A,0x0E, 0x1B,0x04,

0x1A,0x03, 0x19,0x03, 0x17,0x03, 0x16,0x03, 0x0F,0x02,

0x10,0x03, 0x15,0x00, 0x00,0x00 }

//***********************************************************************************

main()

{

InitialSound()

while(1)

{

Play(Music_Girl,0,3,360)

Delay1ms(500)

Play(Music_Same,0,3,360)

Delay1ms(500)

Play(Music_Two,0,3,360)

Delay1ms(500)

}

}

/**************************************************************************

SOUND PLAY FOR 51MCU

COPYRIGHT (c) 2005 BY JJJ.

-- ALL RIGHTS RESERVED --

File Name: SoundPlay.h

Author: Jiang Jian Jun

Created: 2005/5/16

Modified: NO

Revision: 1.0

*******************************************************************************/

/*说明**************************************************************************

曲谱存贮格式 unsigned char code MusicName{音高,音长,音高,音长...., 0,0}末尾:0,0 表示结束(Important)

音高由三位数字组成:

个位是表示 1~7 这七个音符

十位是表示音符所在的音区:1-低音,2-中音,3-高音

百位表示这个音符是否要升半音: 0-不升,1-升半音。

音长最多由三位数字组成:

个位表示音符的时值,其对应关系是:

|数值(n): |0 |1 |2 |3 | 4 | 5 | 6

|几分音符: |1 |2 |4 |8 |16 |32 |64 音符=2^n

十位表示音符的演奏效果(0-2): 0-普通,1-连音,2-顿音

百位是符点位: 0-无符点,1-有符点

调用演奏子程序的格式

Play(乐曲名,调号,升降八度,演奏速度)

|乐曲名 : 要播放的乐曲指针,结尾以(0,0)结束

|调号(0-11) : 是指乐曲升多少个半音演奏

|升降八度(1-3) : 1:降八度, 2:不升不降, 3:升八度

|演奏速度(1-12000): 值越大速度越快

***************************************************************************/

#ifndef __SOUNDPLAY_H_REVISION_FIRST__

#define __SOUNDPLAY_H_REVISION_FIRST__

//**************************************************************************

#define SYSTEM_OSC 12000000 //定义晶振频率12000000HZ

#define SOUND_SPACE 4/5 //定义普通音符演奏的长度分率,//每4分音符间隔

sbitBeepIO=P3^7 //定义输出管脚

unsigned int code FreTab[12] = { 262,277,294,311,330,349,369,392,415,440,466,494 }//原始频率表

unsigned char code SignTab[7] = { 0,2,4,5,7,9,11 } //1~7在频率表中的位置

unsigned char code LengthTab[7]= { 1,2,4,8,16,32,64 }

unsigned char Sound_Temp_TH0,Sound_Temp_TL0//音符定时器初值暂存

unsigned char Sound_Temp_TH1,Sound_Temp_TL1//音长定时器初值暂存

//**************************************************************************

void InitialSound(void)

{

BeepIO = 0

Sound_Temp_TH1 = (65535-(1/1200)*SYSTEM_OSC)/256// 计算TL1应装入的初值 (10ms的初装值)

Sound_Temp_TL1 = (65535-(1/1200)*SYSTEM_OSC)%256// 计算TH1应装入的初值

TH1 = Sound_Temp_TH1

TL1 = Sound_Temp_TL1

TMOD |= 0x11

ET0= 1

ET1= 0

TR0= 0

TR1= 0

EA = 1

}

void BeepTimer0(void) interrupt 1 //音符发生中断

{

BeepIO = !BeepIO

TH0= Sound_Temp_TH0

TL0= Sound_Temp_TL0

}

//**************************************************************************

void Play(unsigned char *Sound,unsigned char Signature,unsigned Octachord,unsigned int Speed)

{

unsigned int NewFreTab[12] //新的频率表

unsigned char i,j

unsigned int Point,LDiv,LDiv0,LDiv1,LDiv2,LDiv4,CurrentFre,Temp_T,SoundLength

unsigned char Tone,Length,SL,SH,SM,SLen,XG,FD

for(i=0i<12i++) // 根据调号及升降八度来生成新的频率表

{

j = i + Signature

if(j >11)

{

j = j-12

NewFreTab[i] = FreTab[j]*2

}

else

NewFreTab[i] = FreTab[j]

if(Octachord == 1)

NewFreTab[i]>>=2

else if(Octachord == 3)

NewFreTab[i]<<=2

}

SoundLength = 0

while(Sound[SoundLength] != 0x00) //计算歌曲长度

{

SoundLength+=2

}

Point = 0

Tone = Sound[Point]

Length = Sound[Point+1] // 读出第一个音符和它时时值

LDiv0 = 12000/Speed // 算出1分音符的长度(几个10ms)

LDiv4 = LDiv0/4 // 算出4分音符的长度

LDiv4 = LDiv4-LDiv4*SOUND_SPACE // 普通音最长间隔标准

TR0 = 0

TR1 = 1

while(Point <SoundLength)

{

SL=Tone%10//计算出音符

SM=Tone/10%10//计算出高低音

SH=Tone/100//计算出是否升半

CurrentFre = NewFreTab[SignTab[SL-1]+SH] //查出对应音符的频率

if(SL!=0)

{

if (SM==1) CurrentFre >>= 2 //低音

if (SM==3) CurrentFre <<= 2 //高音

Temp_T = 65536-(50000/CurrentFre)*10/(12000000/SYSTEM_OSC)//计算计数器初值

Sound_Temp_TH0 = Temp_T/256

Sound_Temp_TL0 = Temp_T%256

TH0 = Sound_Temp_TH0

TL0 = Sound_Temp_TL0 + 12//加12是对中断延时的补偿

}

SLen=LengthTab[Length%10] //算出是几分音符

XG=Length/10%10 //算出音符类型(0普通1连音2顿音)

FD=Length/100

LDiv=LDiv0/SLen //算出连音音符演奏的长度(多少个10ms)

if (FD==1)

LDiv=LDiv+LDiv/2

if(XG!=1)

if(XG==0) //算出普通音符的演奏长度

if (SLen<=4)

LDiv1=LDiv-LDiv4

else

LDiv1=LDiv*SOUND_SPACE

else

LDiv1=LDiv/2 //算出顿音的演奏长度

else

LDiv1=LDiv

if(SL==0) LDiv1=0

LDiv2=LDiv-LDiv1 //算出不发音的长度

if (SL!=0)

{

TR0=1

for(i=LDiv1i>0i--) //发规定长度的音

{

while(TF1==0)

TH1 = Sound_Temp_TH1

TL1 = Sound_Temp_TL1

TF1=0

}

}

if(LDiv2!=0)

{

TR0=0BeepIO=0

for(i=LDiv2i>0i--) //音符间的间隔

{

while(TF1==0)

TH1 = Sound_Temp_TH1

TL1 = Sound_Temp_TL1

TF1=0

}

}

Point+=2

Tone=Sound[Point]

Length=Sound[Point+1]

}

BeepIO = 0

}

//**************************************************************************

#endif


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

原文地址: http://outofmemory.cn/yw/11155453.html

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

发表评论

登录后才能评论

评论列表(0条)

保存