打包发给你
图片地址:
#include
#include
#include
#ifndef __SOUNDPLAY_H_REVISION_FIRST__ //音乐相关
#define __SOUNDPLAY_H_REVISION_FIRST__ //音乐相关
#define uint unsigned int
#define uchar unsigned char
void nl(); //农历
/*定义全局变量---------------------------------------------------------------*/
uchar sec,min,hour, day, date, month,year,cen,r1_h,r1_m,r1_of,r2_h,r2_m,r2_of;
data uchar year_moon,month_moon,date_moon,cen_m,week;
uint bt,rt,rr,rtt,rrt;
bit c_moon; //农历 世纪
bit c; //公历 世纪
bit w = 0; //调时标志位
bit r = 0; //调整闹铃
/*定义12864液晶屏数据线------------------------------------------------------*/
sbit LCM_RS = P1^6; //模式位,为0输入指令,为1输入数据
sbit LCM_RW = P1^7; //读写位,为0读,为1写
sbit LCM_EN = P3^3; //使能位
sbit LCM_BLA = P1^5;
#define Lcd_Bus P0 //LCM12864数据总线
/*定义DS12CR887数据线--------------------------------------------------------*/
sbit DS_CS = P3^5;
sbit DS_AS = P3^4;
sbit DS_RW = P3^6;
sbit DS_DS = P3^7;
#define Ds_Bus P2 //DS12CR887数据总线
/*定义按键-------------------------------------------------------------------*/
sbit K1 = P1^3; //K1-设置
sbit K2 = P1^0; //K2-确认
sbit K3 = P1^2; //K3-加
sbit K4 = P1^1; //K4-减
/*定义DS18B20数据线----------------------------------------------------------*/
sbit DQ = P3^0;
/*定义蜂鸣器-----------------------------------------------------------------*/
sbit beep = P3^1;
/*定义累加器A中的各位--------------------------------------------------------*/
sbit a0 = ACC ^ 0;
sbit a1 = ACC ^ 1;
sbit a2 = ACC ^ 2;
sbit a3 = ACC ^ 3;
sbit a4 = ACC ^ 4;
sbit a5 = ACC ^ 5;
sbit a6 = ACC ^ 6;
sbit a7 = ACC ^ 7;
/* */
#define SYSTEM_OSC 12000000 //定义晶振频率12000000HZ
#define SOUND_SPACE 4/5 //定义普通音符演奏的长度分率,//每4分音符间隔
unsigned int code FreTab[12] = ; //原始频率表
unsigned char code SignTab[7] = ; //1~7在频率表中的位置
unsigned char code LengthTab[7]= ;
unsigned char Sound_Temp_TH0,Sound_Temp_TL0; //音符定时器初值暂存
unsigned char Sound_Temp_TH1,Sound_Temp_TL1; //音长定时器初值暂存
/*延时程序-------------------------------------------------------------------*/
//延时函数 1MS/次
void DelayM(uint a)
{
uchar i;
while( --a != 0)
{
for(i = 0; i < 125; i++); //一个 ; 表示空语句,CPU空转。
} //i 从0加到125,CPU大概就耗时1毫秒
}
//延时函数
void Delay(int num)
{
while(num--);
}
void InitialSound(void) //音乐相关
{
beep = 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 //音符发生中断
{
beep = !beep;
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;
//Point 指针索引值
//LDiv 音音符演奏的长度(多少个10ms)
//LDiv0 1分音符的长度(几个10ms)即一个节拍
//LDiv4 4分音符的长度
//CurrentFre 查出对应音符的频率
//SoundLength歌曲长度
//Temp_T计算计数器初值
unsigned char Tone,Length,SL,SH,SM,SLen,XG,FD;
//Tone音调
//Length音长
//SL音符
//SM高低音
//SH是否升半
//XG音符类型(0普通1连音2顿音)
for(i=0;i<12;i++) // 根据调号及升降八度来生成新的频率表
{
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=LDiv1;i>0;i--) //发规定长度的音
{
while(TF1==0);
TH1 = Sound_Temp_TH1;
TL1 = Sound_Temp_TL1;
TF1=0;
}
}
if(LDiv2!=0)
{
TR0=0; beep=0;
for(i=LDiv2;i>0;i--) //音符间的间隔
{
while(TF1==0);
TH1 = Sound_Temp_TH1;
TL1 = Sound_Temp_TL1;
TF1=0;
}
}
Point+=2;
Tone=Sound[Point];
Length=Sound[Point+1];
你用什么显示时间的,我用的是12864,当时也有这种情况,后来发现问题是刷屏时间太短了,稍微增大些时间就行了。 在做单片机系统的时候,特别是用万用版焊接的时候,一定要保证,没有短路情况发生,我在做的时候,找问题找了一个星期,最终还是确定为电路问题,用万用表测不出来,必须可以清晰的看到没有短路,线路隔离好