基於金沙灘51單片機的蜂鳴器音樂 - 克羅地亞狂想曲
當年剛學單片機蜂鳴器不久做的一個小項目,能用蜂鳴器播放音樂,之前的網站掛了,在這里重新發一下。
下面是原文:
當溫度超過設置值時,怎么設置使蜂鳴器發出某首音樂聲?
敲黑板畫重點啦!!!這里的重點是音樂聲!而不是溫度超過設置值!
於是去參考了下宋老師的代碼:
蜂鳴器音樂實例代碼
#include <reg52.h>
sbit BUZZ = P1^6; //蜂鳴器控制引腳
unsigned int code NoteFrequ[] = { //中音1-7和高音1-7對應頻率列表
523, 587, 659, 698, 784, 880, 988, //中音1-7
1047, 1175, 1319, 1397, 1568, 1760, 1976 //高音1-7
};
unsigned int code NoteReload[] = { //中音1-7和高音1-7對應的定時器重載值
65536 - (11059200/12) / (523*2), //中音1
65536 - (11059200/12) / (587*2), //2
65536 - (11059200/12) / (659*2), //3
65536 - (11059200/12) / (698*2), //4
65536 - (11059200/12) / (784*2), //5
65536 - (11059200/12) / (880*2), //6
65536 - (11059200/12) / (988*2), //7
65536 - (11059200/12) / (1047*2), //高音1
65536 - (11059200/12) / (1175*2), //2
65536 - (11059200/12) / (1319*2), //3
65536 - (11059200/12) / (1397*2), //4
65536 - (11059200/12) / (1568*2), //5
65536 - (11059200/12) / (1760*2), //6
65536 - (11059200/12) / (1976*2), //7
};
bit enable = 1; //蜂鳴器發聲使能標志
bit tmrflag = 0; //定時器中斷完成標志
unsigned char T0RH = 0xFF; //T0重載值的高字節
unsigned char T0RL = 0x00; //T0重載值的低字節
void PlayTwoTiger();
void main()
{
unsigned int i;
EA = 1; //使能全局中斷
TMOD = 0x01; //配置T0工作在模式1
TH0 = T0RH;
TL0 = T0RL;
ET0 = 1; //使能T0中斷
TR0 = 1; //啟動T0
while (1)
{
PlayTwoTiger(); //播放樂曲--兩支老虎
for (i=0; i<40000; i++); //停止一段時間
}
}
/* 兩只老虎樂曲播放函數 */
void PlayTwoTiger()
{
unsigned char beat; //當前節拍索引
unsigned char note; //當前節拍對應的音符
unsigned int time = 0; //當前節拍計時
unsigned int beatTime = 0; //當前節拍總時間
unsigned int soundTime = 0; //當前節拍需發聲時間
//兩只老虎音符表
unsigned char code TwoTigerNote[] = {
1, 2, 3, 1, 1, 2, 3, 1, 3, 4, 5, 3, 4, 5,
5,6, 5,4, 3, 1, 5,6, 5,4, 3, 1, 1, 5, 1, 1, 5, 1,
};
//兩只老虎節拍表,4表示一拍,1就是1/4拍,8就是2拍
unsigned char code TwoTigerBeat[] = {
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 4, 4, 8,
3,1, 3,1, 4, 4, 3,1, 3,1, 4, 4, 4, 4, 8, 4, 4, 8,
};
for (beat=0; beat<sizeof(TwoTigerNote); ) //用節拍索引作為循環變量
{
while (!tmrflag); //每次定時器中斷完成后,檢測並處理節拍
tmrflag = 0;
if (time == 0) //當前節拍播完則啟動一個新節拍
{
note = TwoTigerNote[beat] - 1;
T0RH = NoteReload[note] >> 8;
T0RL = NoteReload[note];
//計算節拍總時間,右移2位相當於除4,移位代替除法可以加快執行速度
beatTime = (TwoTigerBeat[beat] * NoteFrequ[note]) >> 2;
//計算發聲時間,為總時間的0.75,移位原理同上
soundTime = beatTime - (beatTime >> 2);
enable = 1; //指示蜂鳴器開始發聲
time++;
}
else //當前節拍未播完則處理當前節拍
{
if (time >= beatTime) //當前持續時間到達節拍總時間時歸零,
{ //並遞增節拍索引,以准備啟動新節拍
time = 0;
beat++;
}
else //當前持續時間未達到總時間時,
{
time++; //累加時間計數
if (time == soundTime) //到達發聲時間后,指示關閉蜂鳴器,
{ //插入0.25*總時間的靜音間隔,
enable = 0; //用以區分連續的兩個節拍
}
}
}
}
}
/* T0中斷服務函數,用於控制蜂鳴器發聲 */
void InterruptTimer0() interrupt 1
{
TH0 = T0RH; //重新加載重載值
TL0 = T0RL;
tmrflag = 1;
if (enable) //使能時反轉蜂鳴器控制電平
BUZZ = ~BUZZ;
else //未使能時關閉蜂鳴器
BUZZ = 1;
}
下載到單片機后,傳來了美妙的“兩只老虎” ✧٩(ˊωˋ*)و✧
然而我並不喜歡把兩只老虎作為報警音樂.......
宋老師的代碼主要由數據和控制組成,而數據分為節拍數據和音調數據,那我們要換一首歌不就是換音調和節拍。
於是去百度“單片機蜂鳴器音樂代碼”,得到如下結果:
都是些八月桂花,生日快樂,兩只蝴蝶,祝你平安這些經典音樂,沒有POP嗎?
那就自己動手吧,只要得到節拍數據和音調數據就好了,應該有轉換工具的,就像LED點陣一樣有點陣圖形轉換工具,於是百度:
還真有 (*≧▽≦) , 叫 music encode
於是下載,解包
還有Dome和說明,太好了。於是下載了Dome。是八月桂花....
然而我不喜歡這個,翻了翻音樂列表,就設置為“克羅地亞狂想曲”吧
٩(●´৺`●)૭٩(●´৺'●)و
於是去問度娘要樂譜,好不容易找到了由玉面小嫣然改編的古箏簡譜,其他的都是五線譜,原諒我看不懂五線譜 ( •̩̩̩̩_•̩̩̩̩ )
找到樂譜后就開始輸樂譜........ (つд⊂) , 一個漫長的過程.........
終於輸好了,生成代碼下載進去...... ٩(●´৺`●)૭٩(●´৺'●)و
克羅地亞狂想曲樂譜
樂譜
0, 0, 0, 0,| 7__, .1__, 6_, 0, 3__, 4__, 2_, 0,| #, 4__, #, 5__, 3_, 3_, 7.__, 1__, 6._, 7.__, 1__, 6.,| 7__, .1__, 6_, 0, .3__, 6__, 3__, 4__, 2_, 0, 6__, 2__,|
#, 4__, #, 5__, 3_, 3_, 7.__, 1__, 6._, 7.__, 1__, 6.,| 7__, .1__, 6_, 0, .3__, 6__, 7__, .1__, 6_, 0, .3__, 6__,| 7__, .1__, 6_, 6_, #, 5__, 6__, 0, 7__, .1__, 6,| 7__, .1__, 6_, 0, .3__, 6__, 7__, .1__, 6_, 0, .3__, 6__,|
7__, .1__, 6_, 6_, #, 5__, 6__, 0, 7__, .1__, 6,| 7__, .1__, 6_, 0, .3__, 6__, 3__, 4__, 2_, 0,| #, 4__, #, 5__, 3_, 3_, 7.__, 1__, 6._, 7.__, 1__, 6.,| 7__, .1__, 6_, 0, .3__, 6__, 3__, 4__, 2_, 0,|
#, 4__, #, 5__, 3_, 3_, 7.__, 1__, 6._, 7.__, 1__, 6.,| 7__, .1__, 6_, 0, .3__, 6__, 7__, .1__, 6_, 0, .3__, 6__,| 7__, .1__, 6_, 6_, #, 5__, 6__, 0, 7__, .1__, 6,| 7__, .1__, 6_, 0, .3__, 6__, 7__, .1__, 6_, 0, .3__, 6__,|
7__, .1__, 6_, 6_, #, 5__, 6__, 0, 7__, .1__, 6,||| .1__, 3__, 6__, 7__, .1__, 3__, 6__, .1__, .2__, 3__, .1__, 3__, 7__, 3__, 6__, 3__,| 7__, 3__, #, 5__, 6__, 7__, 3__, 5__, 7__, .1__, 3__, 7__, 3__, 6__, 3__, .3__, 3__,| .1__, 3__, 6__, 7__, .1__, 3__, 6__, .1__, .2__, 3__, .1__, 3__, 7__, 3__, 6__, 3__,|
.3__, 3__, #, 5__, 3__, .1__, 3__, 7__, 3__, 6__, 3__, .3__, 3__, 6,||| .1__, 3__, 6__, 7__, .1__, 3__, 6__, .1__, .2__, 3__, .1__, 3__, 7__, 3__, 6__, 3__,| 7__, 3__, #, 5__, 6__, 7__, 3__, 5__, 7__, .1__, 3__, 7__, 3__, 6__, 3__, .3__, 3__,| .1__, 3__, 6__, 7__, .1__, 3__, 6__, .1__, .2__, 3__, .1__, 3__, 7__, 3__, 6__, 3__,|
.3__, 3__, #, 5__, 3__, .1__, 3__, 7__, 3__, 6__, 3__, .3__, 3__, 6,|| .3__, 6__, .1__, .2__, .3__, 6__, .1__, .5__, .4__, 6__, .3__, 6__, .2__, 6__, .1__, 6__,| .2__, 5__, 7__, .1__, .2__, 5__, 7__, .4__, .3__, 5__, .2__, 5__, .1__, 5__, 7__, 5__,| .1__, 3__, 6__, 7__, .1__, 3__, 6__, .1__, .2__, 3__, .1__, 3__, 7__, 3__, 6__, 3__,|
7_, 3_, .1_, 7_, 6_, .3_, .6,| 7_, 3_, .1_, 7_, 6._, 6_, 6,| .3__, 6__, .1__, .2__, .3__, 6__, .1__, .5__, .4__, 6__, .3__, 6__, .4__, 6__, .6__, 6__,| .5__, 7__, .2__, .6__, .5__, 7__, .4__, 7__, .3__, 3__, .2__, 3__, .1__, 3__, 7__, 3__,| .1__, 3__, 6__, 7__, .1__, 3__, 6__, .1__, .2__, 3__, .1__, 3__, 7__, 3__, 6__, 3__,|
7__, 3__, #, 5__, 7__, .2__, 5__, 7__, .2__, .3__, 7__, .2__, .3__, #, .5__, .2__, .3__, .5__,| 7__, 3__, #, 5__, 7__, .2__, 5__, 7__, .2__, .3__, 7__, .2__, .3__, #, .5__, .2__, .3__, .5__,| .6, -, -, -,| 6.__, 1_, 3__, 2__, 6.__, 1__, 5.__, 6.__, 1_, 3__, 2__, 6.__, 1_,|
0, 6__, 1__, 3__, 6.__, 1__, 6._, 0, #, 2.__, 3.__, 6.__, 1__, 2__, 1_,| 3.__, 5._, 3.__, 6.__, 3.__, 5.__, 2.__, 3.__, 5._, 3.__, 6.__, 3.__, 5._,| 7__, .1__, 6_, 0, .3__, 6__, 3__, 4__, 2_, 0,| #, 4__, #, 5__, 3_, 3_, 7.__, 1__, 6._, 7.__, 1__, 6.,|
7__, .1__, 6_, 0, .3__, 6__, 3__, 4__, 2_, 0,| #, 4__, #, 5__, 3_, 3_, 7.__, 1__, 6._, 7.__, 1__, 6.,| 7__, .1__, 6_, 0, .3__, 6__, 7__, .1__, 6_, 0, .3__, 6__,| 7__, .1__, 6_, 6_, #, 5__, 6__, 0, 7__, .1__, 6,|
7__, .1__, 6_, 0, .3__, 6__, 7__, .1__, 6_, 0, .3__, 6__,| 7__, .1__, 6_, 6_, #, 5__, 6__, 0, 7__, .1__, 6,| .1__, 3__, 6__, 7__, .1__, 3__, 6__, .1__, .2__, 3__, .1__, 3__, 7__, 3__, 6__, 3__,| 7__, 3__, #, 5__, 6__, 7__, 3__, 5__, 7__, .1__, 3__, 7__, 3__, 6__, 3__, .3__, 3__,|
.1__, 3__, 6__, 7__, .1__, 3__, 6__, .1__, .2__, 3__, .1__, 3__, 7__, 3__, 6__, 3__,| .3__, 3__, #, 5__, 3__, .1__, 3__, 7__, 3__, 6__, 3__, .3__, 3__, 6,| .3__, 6__, .1__, .2__, .3__, 6__, .1__, .5__, .4__, 6__, .3__, 6__, .4__, 6__, .6__, 6__,| .5__, 7__, .2__, .6__, .5__, 7__, .4__, 7__, .3__, 3__, .2__, 3__, .1__, 3__, 7__, 3__,|
.1__, 3__, 6__, 7__, .1__, 3__, 6__, .1__, .2__, 3__, .1__, 3__, 7__, 3__, 6__, 3__,| 7__, 3__, #, 5__, 7__, .2__, 5__, 7__, .2__, .3__, 7__, .2__, .3__, #, .5__, .3__, .2__, .1__,| 7, -, .3, -,| 7__, .1__, 6_, 7__, .1__, 6_, 3__, 4__, 2_, 3__, 4__, 2_,|
#, 4__, #, 5__, 3_, 3_, 7.__, 1__, 6._, 7.__, 1__, 6.,| 7__, .1__, 6_, 7__, .1__, 6_, 3__, 4__, 2_, 3__, 4__, 2_,| #, 4__, #, 5__, 3_, 3_, 7.__, 1__, 6._, 7.__, 1__, 6.,| 7__, .1__, 6_, 0, .3__, 6__, 7__, .1__, 6_, 0, .3__, 6__,|
7__, .1__, 6_, 6_, #, 5__, 6__, 0, 7__, .1__, 6,| 7__, .1__, 6_, 0, .3__, 6__, 7__, .1__, 6_, 0, .3__, 6__,| 7__, .1__, 6_, 6_, #, 5__, 6__, 0, 7__, .1__, 6,| .1__, 3__, 6__, 7__, .1__, 3__, 6__, .1__, .2__, 3__, .1__, 3__, 7__, 3__, 6__, 3__,|
7__, 3__, #, 5__, 6__, 7__, 3__, 5__, 7__, .1__, 3__, 7__, 3__, 6__, 3__, .3__, 3__,| .1__, 3__, 6__, 7__, .1__, 3__, 6__, .1__, .2__, 3__, .1__, 3__, 7__, 3__, 6__, 3__,| .3__, 3__, #, 5__, 3__, .1__, 3__, 7__, 3__, 6__, 3__, .3__, 3__, 6,| .3__, 6__, .1__, .2__, .3__, 6__, .1__, .5__, .4__, 6__, .3__, 6__, .4__, 6__, .6__, 6__,|
.5__, 7__, .2__, .6__, .5__, 7__, .4__, 7__, .3__, 3__, .2__, 3__, .1__, 3__, 7__, 3__,| .1__, 3__, 6__, 7__, .1__, 3__, 6__, .1__, .2__, 3__, .1__, 3__, 7__, 3__, 6__, 3__,| 7__, 3__, #, 5__, 7__, .2__, 5__, 7__, .2__, .3__, 7__, .2__, .3__, #, .5__, .3__, .2__, .1__,| 7__, .1__, 6_, 7__, .1__, 6_, 3__, 4__, 2_, 3__, 4__, 2_,|
#, 4__, #, 5__, 3_, 3_, 7.__, 1__, 6._, 7.__, 1__, 6.,| 7__, .1__, 6_, 7__, .1__, 6_, 3__, 4__, 2_, 3__, 4__, 2_,| #, 4__, #, 5__, 3_, 3_, 7.__, 1__, 6._, 7.__, 1__, 6.,| 7__, .1__, 6_, 0, .3__, 6__, 7__, .1__, 6_, 0, .3__, 6__,|
7__, .1__, 6_, 6_, #, 5__, 6__, 0, 7__, .1__, 6,| 7__, .1__, 6_, 0, .3__, 6__, 7__, .1__, 6_, 0, .3__, 6__,| 7__, .1__, 6_, 6_, #, 5__, 6__, 0, 7__, .1__, 6,| 7__, .1__, 6_, 7__, .1__, 6_, 3__, 4__, 2_, 3__, 4__, 2_,|
#, 4__, #, 5__, 3_, 3_, 7.__, 1__, 6._, 7.__, 1__, 6.,| 7__, .1__, 6_, 7__, .1__, 6_, 3__, 4__, 2_, 3__, 4__, 2_,| #, 4__, #, 5__, 3_, 3_, 7_, 6_, .3_, .6,| #, 4__, #, 5__, 3_, 3_, 7_, 3_, 6_, .3,| #, 4__, #, 5__, 3_, 3_, 7_, 3_, 6_, 6,|
此處應有視頻......
Nice!
需要用到的原理圖和軟件
DS18B20讀寫時序:
源代碼和解釋:
只播放音樂的代碼:(按K1可以暫停哦......)
#include <reg52.h>
sbit keyin = P2^4;
sbit keyout = P2^3;
/*----------------音樂函數申明------------------------------*/
void Play();
void InitialSound(unsigned char *Sound0,unsigned char Signature0,
unsigned char Octachord0,unsigned int Speed0);
/*----------------音樂數據申明------------------------------*/
extern unsigned char code Music_Croatian_Rhapsody[];
//數據太大,放后面了,所以加extern以說明
void delay10ms(void) //誤差 0us
{
unsigned char a,b,c;
for(c=1;c>0;c--)
for(b=38;b>0;b--)
for(a=130;a>0;a--);
}
void main()
{
unsigned int cnt = 0;
InitialSound(Music_Croatian_Rhapsody,0,2,360); //蜂鳴器初始化
keyout = 0;
while(1)
{
if(keyin == 0)
{
delay10ms();
if(keyin == 0)
{
if(cnt<40)cnt = 200;
else cnt = 20;
while(keyin == 0);
}
}
if(cnt < 40)
{
Play(); //蜂鳴器
}
}
}
/*-----------------------以下是蜂鳴器演奏------------------*/
#define SYSTEM_OSC 11059200 //12000000 //定義晶振頻率12000000HZ
#define SOUND_SPACE 4/5 //定義普通音符演奏的長度分率,//每4分音符間隔
sbit BeepIO = P1^6; //定義輸出管腳
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; //音長定時器初值暫存
unsigned char Signature;
unsigned char Octachord;
unsigned int Speed;
unsigned char *Sound;
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;
void InitialSound(unsigned char *Sound0,unsigned char Signature0,unsigned char Octachord0,unsigned int Speed0)
{
Signature = Signature0;
Octachord = Octachord0;
Speed = Speed0;
Sound = Sound0;
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 = 1;
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; // 普通音最長間隔標准
BeepIO = 1;
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()
{
EA = 1;
TR0 = 0;
TR1 = 1;
if(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; BeepIO=1;
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];
}
else
{
/*SoundLength = len;
Point = poi;*/
InitialSound(Music_Croatian_Rhapsody,0,2,360);
}
BeepIO = 1;
TR0 = 0;
TR1 = 0;
}
//這里放生成的音樂數據
unsigned char code Music_Croatian_Rhapsody[]={
0x1B,0x04, 0x1F,0x04, 0x1A,0x17, 0x17,0x04, 0x18,0x04,
0x16,0x7B, 0x18,0x68, 0x19,0x04, 0x17,0x03, 0x17,0x03,
0x11,0x04, 0x15,0x04, 0x10,0x03, 0x11,0x04, 0x15,0x04,
0x10,0x02, 0x1B,0x04, 0x1F,0x04, 0x1A,0x17, 0x21,0x04,
0x1A,0x04, 0x17,0x04, 0x18,0x04, 0x16,0x17, 0x1A,0x04,
0x16,0x68, 0x18,0x68, 0x19,0x04, 0x17,0x03, 0x17,0x03,
0x11,0x04, 0x15,0x04, 0x10,0x03, 0x11,0x04, 0x15,0x04,
0x10,0x02, 0x1B,0x04, 0x1F,0x04, 0x1A,0x17, 0x21,0x04,
0x1A,0x04, 0x1B,0x04, 0x1F,0x04, 0x1A,0x17, 0x21,0x04,
0x1A,0x04, 0x1B,0x04, 0x1F,0x04, 0x1A,0x03, 0x1A,0x67,
0x19,0x04, 0x1A,0x18, 0x1B,0x04, 0x1F,0x04, 0x1A,0x02,
0x1B,0x04, 0x1F,0x04, 0x1A,0x17, 0x21,0x04, 0x1A,0x04,
0x1B,0x04, 0x1F,0x04, 0x1A,0x17, 0x21,0x04, 0x1A,0x04,
0x1B,0x04, 0x1F,0x04, 0x1A,0x03, 0x1A,0x67, 0x19,0x04,
0x1A,0x18, 0x1B,0x04, 0x1F,0x04, 0x1A,0x02, 0x1B,0x04,
0x1F,0x04, 0x1A,0x17, 0x21,0x04, 0x1A,0x04, 0x17,0x04,
0x18,0x04, 0x16,0x7B, 0x18,0x68, 0x19,0x04, 0x17,0x03,
0x17,0x03, 0x11,0x04, 0x15,0x04, 0x10,0x03, 0x11,0x04,
0x15,0x04, 0x10,0x02, 0x1B,0x04, 0x1F,0x04, 0x1A,0x17,
0x21,0x04, 0x1A,0x04, 0x17,0x04, 0x18,0x04, 0x16,0x7B,
0x18,0x68, 0x19,0x04, 0x17,0x03, 0x17,0x03, 0x11,0x04,
0x15,0x04, 0x10,0x03, 0x11,0x04, 0x15,0x04, 0x10,0x02,
0x1B,0x04, 0x1F,0x04, 0x1A,0x17, 0x21,0x04, 0x1A,0x04,
0x1B,0x04, 0x1F,0x04, 0x1A,0x17, 0x21,0x04, 0x1A,0x04,
0x1B,0x04, 0x1F,0x04, 0x1A,0x03, 0x1A,0x67, 0x19,0x04,
0x1A,0x18, 0x1B,0x04, 0x1F,0x04, 0x1A,0x02, 0x1B,0x04,
0x1F,0x04, 0x1A,0x17, 0x21,0x04, 0x1A,0x04, 0x1B,0x04,
0x1F,0x04, 0x1A,0x17, 0x21,0x04, 0x1A,0x04, 0x1B,0x04,
0x1F,0x04, 0x1A,0x03, 0x1A,0x67, 0x19,0x04, 0x1A,0x18,
0x1B,0x04, 0x1F,0x04, 0x1A,0x02, 0x1F,0x04, 0x17,0x04,
0x1A,0x04, 0x1B,0x04, 0x1F,0x04, 0x17,0x04, 0x1A,0x04,
0x1F,0x04, 0x20,0x04, 0x17,0x04, 0x1F,0x04, 0x17,0x04,
0x1B,0x04, 0x17,0x04, 0x1A,0x04, 0x17,0x04, 0x1B,0x04,
0x17,0x68, 0x19,0x04, 0x1A,0x04, 0x1B,0x04, 0x17,0x04,
0x19,0x04, 0x1B,0x04, 0x1F,0x04, 0x17,0x04, 0x1B,0x04,
0x17,0x04, 0x1A,0x04, 0x17,0x04, 0x21,0x04, 0x17,0x04,
0x1F,0x04, 0x17,0x04, 0x1A,0x04, 0x1B,0x04, 0x1F,0x04,
0x17,0x04, 0x1A,0x04, 0x1F,0x04, 0x20,0x04, 0x17,0x04,
0x1F,0x04, 0x17,0x04, 0x1B,0x04, 0x17,0x04, 0x1A,0x04,
0x17,0x04, 0x21,0x04, 0x17,0x68, 0x19,0x04, 0x17,0x04,
0x1F,0x04, 0x17,0x04, 0x1B,0x04, 0x17,0x04, 0x1A,0x04,
0x17,0x04, 0x21,0x04, 0x17,0x04, 0x1A,0x02, 0x1F,0x04,
0x17,0x04, 0x1A,0x04, 0x1B,0x04, 0x1F,0x04, 0x17,0x04,
0x1A,0x04, 0x1F,0x04, 0x20,0x04, 0x17,0x04, 0x1F,0x04,
0x17,0x04, 0x1B,0x04, 0x17,0x04, 0x1A,0x04, 0x17,0x04,
0x1B,0x04, 0x17,0x68, 0x19,0x04, 0x1A,0x04, 0x1B,0x04,
0x17,0x04, 0x19,0x04, 0x1B,0x04, 0x1F,0x04, 0x17,0x04,
0x1B,0x04, 0x17,0x04, 0x1A,0x04, 0x17,0x04, 0x21,0x04,
0x17,0x04, 0x1F,0x04, 0x17,0x04, 0x1A,0x04, 0x1B,0x04,
0x1F,0x04, 0x17,0x04, 0x1A,0x04, 0x1F,0x04, 0x20,0x04,
0x17,0x04, 0x1F,0x04, 0x17,0x04, 0x1B,0x04, 0x17,0x04,
0x1A,0x04, 0x17,0x04, 0x21,0x04, 0x17,0x68, 0x19,0x04,
0x17,0x04, 0x1F,0x04, 0x17,0x04, 0x1B,0x04, 0x17,0x04,
0x1A,0x04, 0x17,0x04, 0x21,0x04, 0x17,0x04, 0x1A,0x02,
0x21,0x04, 0x1A,0x04, 0x1F,0x04, 0x20,0x04, 0x21,0x04,
0x1A,0x04, 0x1F,0x04, 0x23,0x04, 0x22,0x04, 0x1A,0x04,
0x21,0x04, 0x1A,0x04, 0x20,0x04, 0x1A,0x04, 0x1F,0x04,
0x1A,0x04, 0x20,0x04, 0x19,0x04, 0x1B,0x04, 0x1F,0x04,
0x20,0x04, 0x19,0x04, 0x1B,0x04, 0x22,0x04, 0x21,0x04,
0x19,0x04, 0x20,0x04, 0x19,0x04, 0x1F,0x04, 0x19,0x04,
0x1B,0x04, 0x19,0x04, 0x1F,0x04, 0x17,0x04, 0x1A,0x04,
0x1B,0x04, 0x1F,0x04, 0x17,0x04, 0x1A,0x04, 0x1F,0x04,
0x20,0x04, 0x17,0x04, 0x1F,0x04, 0x17,0x04, 0x1B,0x04,
0x17,0x04, 0x1A,0x04, 0x17,0x04, 0x1B,0x03, 0x17,0x03,
0x1F,0x03, 0x1B,0x03, 0x1A,0x03, 0x21,0x03, 0x24,0x02,
0x1B,0x03, 0x17,0x03, 0x1F,0x03, 0x1B,0x03, 0x10,0x03,
0x1A,0x03, 0x1A,0x02, 0x21,0x04, 0x1A,0x04, 0x1F,0x04,
0x20,0x04, 0x21,0x04, 0x1A,0x04, 0x1F,0x04, 0x23,0x04,
0x22,0x04, 0x1A,0x04, 0x21,0x04, 0x1A,0x04, 0x22,0x04,
0x1A,0x04, 0x24,0x04, 0x1A,0x04, 0x23,0x04, 0x1B,0x04,
0x20,0x04, 0x24,0x04, 0x23,0x04, 0x1B,0x04, 0x22,0x04,
0x1B,0x04, 0x21,0x04, 0x17,0x04, 0x20,0x04, 0x17,0x04,
0x1F,0x04, 0x17,0x04, 0x1B,0x04, 0x17,0x04, 0x1F,0x04,
0x17,0x04, 0x1A,0x04, 0x1B,0x04, 0x1F,0x04, 0x17,0x04,
0x1A,0x04, 0x1F,0x04, 0x20,0x04, 0x17,0x04, 0x1F,0x04,
0x17,0x04, 0x1B,0x04, 0x17,0x04, 0x1A,0x04, 0x17,0x04,
0x1B,0x04, 0x17,0x68, 0x19,0x04, 0x1B,0x04, 0x20,0x04,
0x19,0x04, 0x1B,0x04, 0x20,0x04, 0x21,0x04, 0x1B,0x04,
0x20,0x04, 0x21,0x68, 0x23,0x04, 0x20,0x04, 0x21,0x04,
0x23,0x04, 0x1B,0x04, 0x17,0x68, 0x19,0x04, 0x1B,0x04,
0x20,0x04, 0x19,0x04, 0x1B,0x04, 0x20,0x04, 0x21,0x04,
0x1B,0x04, 0x20,0x04, 0x21,0x68, 0x23,0x04, 0x20,0x04,
0x21,0x04, 0x23,0x04, 0x24,0x00, 0x10,0x04, 0x15,0x03,
0x17,0x04, 0x16,0x04, 0x10,0x04, 0x15,0x04, 0x0F,0x04,
0x10,0x04, 0x15,0x03, 0x17,0x04, 0x16,0x04, 0x10,0x04,
0x15,0x17, 0x1A,0x04, 0x15,0x04, 0x17,0x04, 0x10,0x04,
0x15,0x04, 0x10,0x7B, 0x0C,0x04, 0x0D,0x04, 0x10,0x04,
0x15,0x04, 0x16,0x04, 0x15,0x03, 0x0D,0x04, 0x0F,0x03,
0x0D,0x04, 0x10,0x04, 0x0D,0x04, 0x0F,0x04, 0x0C,0x04,
0x0D,0x04, 0x0F,0x03, 0x0D,0x04, 0x10,0x04, 0x0D,0x04,
0x0F,0x03, 0x1B,0x04, 0x1F,0x04, 0x1A,0x17, 0x21,0x04,
0x1A,0x04, 0x17,0x04, 0x18,0x04, 0x16,0x7B, 0x18,0x68,
0x19,0x04, 0x17,0x03, 0x17,0x03, 0x11,0x04, 0x15,0x04,
0x10,0x03, 0x11,0x04, 0x15,0x04, 0x10,0x02, 0x1B,0x04,
0x1F,0x04, 0x1A,0x17, 0x21,0x04, 0x1A,0x04, 0x17,0x04,
0x18,0x04, 0x16,0x7B, 0x18,0x68, 0x19,0x04, 0x17,0x03,
0x17,0x03, 0x11,0x04, 0x15,0x04, 0x10,0x03, 0x11,0x04,
0x15,0x04, 0x10,0x02, 0x1B,0x04, 0x1F,0x04, 0x1A,0x17,
0x21,0x04, 0x1A,0x04, 0x1B,0x04, 0x1F,0x04, 0x1A,0x17,
0x21,0x04, 0x1A,0x04, 0x1B,0x04, 0x1F,0x04, 0x1A,0x03,
0x1A,0x67, 0x19,0x04, 0x1A,0x18, 0x1B,0x04, 0x1F,0x04,
0x1A,0x02, 0x1B,0x04, 0x1F,0x04, 0x1A,0x17, 0x21,0x04,
0x1A,0x04, 0x1B,0x04, 0x1F,0x04, 0x1A,0x17, 0x21,0x04,
0x1A,0x04, 0x1B,0x04, 0x1F,0x04, 0x1A,0x03, 0x1A,0x67,
0x19,0x04, 0x1A,0x18, 0x1B,0x04, 0x1F,0x04, 0x1A,0x02,
0x1F,0x04, 0x17,0x04, 0x1A,0x04, 0x1B,0x04, 0x1F,0x04,
0x17,0x04, 0x1A,0x04, 0x1F,0x04, 0x20,0x04, 0x17,0x04,
0x1F,0x04, 0x17,0x04, 0x1B,0x04, 0x17,0x04, 0x1A,0x04,
0x17,0x04, 0x1B,0x04, 0x17,0x68, 0x19,0x04, 0x1A,0x04,
0x1B,0x04, 0x17,0x04, 0x19,0x04, 0x1B,0x04, 0x1F,0x04,
0x17,0x04, 0x1B,0x04, 0x17,0x04, 0x1A,0x04, 0x17,0x04,
0x21,0x04, 0x17,0x04, 0x1F,0x04, 0x17,0x04, 0x1A,0x04,
0x1B,0x04, 0x1F,0x04, 0x17,0x04, 0x1A,0x04, 0x1F,0x04,
0x20,0x04, 0x17,0x04, 0x1F,0x04, 0x17,0x04, 0x1B,0x04,
0x17,0x04, 0x1A,0x04, 0x17,0x04, 0x21,0x04, 0x17,0x68,
0x19,0x04, 0x17,0x04, 0x1F,0x04, 0x17,0x04, 0x1B,0x04,
0x17,0x04, 0x1A,0x04, 0x17,0x04, 0x21,0x04, 0x17,0x04,
0x1A,0x02, 0x21,0x04, 0x1A,0x04, 0x1F,0x04, 0x20,0x04,
0x21,0x04, 0x1A,0x04, 0x1F,0x04, 0x23,0x04, 0x22,0x04,
0x1A,0x04, 0x21,0x04, 0x1A,0x04, 0x22,0x04, 0x1A,0x04,
0x24,0x04, 0x1A,0x04, 0x23,0x04, 0x1B,0x04, 0x20,0x04,
0x24,0x04, 0x23,0x04, 0x1B,0x04, 0x22,0x04, 0x1B,0x04,
0x21,0x04, 0x17,0x04, 0x20,0x04, 0x17,0x04, 0x1F,0x04,
0x17,0x04, 0x1B,0x04, 0x17,0x04, 0x1F,0x04, 0x17,0x04,
0x1A,0x04, 0x1B,0x04, 0x1F,0x04, 0x17,0x04, 0x1A,0x04,
0x1F,0x04, 0x20,0x04, 0x17,0x04, 0x1F,0x04, 0x17,0x04,
0x1B,0x04, 0x17,0x04, 0x1A,0x04, 0x17,0x04, 0x1B,0x04,
0x17,0x68, 0x19,0x04, 0x1B,0x04, 0x20,0x04, 0x19,0x04,
0x1B,0x04, 0x20,0x04, 0x21,0x04, 0x1B,0x04, 0x20,0x04,
0x21,0x68, 0x23,0x04, 0x21,0x04, 0x20,0x04, 0x1F,0x04,
0x1B,0x01, 0x21,0x01, 0x1B,0x04, 0x1F,0x04, 0x1A,0x03,
0x1B,0x04, 0x1F,0x04, 0x1A,0x03, 0x17,0x04, 0x18,0x04,
0x16,0x03, 0x17,0x04, 0x18,0x04, 0x16,0x67, 0x18,0x68,
0x19,0x04, 0x17,0x03, 0x17,0x03, 0x11,0x04, 0x15,0x04,
0x10,0x03, 0x11,0x04, 0x15,0x04, 0x10,0x02, 0x1B,0x04,
0x1F,0x04, 0x1A,0x03, 0x1B,0x04, 0x1F,0x04, 0x1A,0x03,
0x17,0x04, 0x18,0x04, 0x16,0x03, 0x17,0x04, 0x18,0x04,
0x16,0x67, 0x18,0x68, 0x19,0x04, 0x17,0x03, 0x17,0x03,
0x11,0x04, 0x15,0x04, 0x10,0x03, 0x11,0x04, 0x15,0x04,
0x10,0x02, 0x1B,0x04, 0x1F,0x04, 0x1A,0x17, 0x21,0x04,
0x1A,0x04, 0x1B,0x04, 0x1F,0x04, 0x1A,0x17, 0x21,0x04,
0x1A,0x04, 0x1B,0x04, 0x1F,0x04, 0x1A,0x03, 0x1A,0x67,
0x19,0x04, 0x1A,0x18, 0x1B,0x04, 0x1F,0x04, 0x1A,0x02,
0x1B,0x04, 0x1F,0x04, 0x1A,0x17, 0x21,0x04, 0x1A,0x04,
0x1B,0x04, 0x1F,0x04, 0x1A,0x17, 0x21,0x04, 0x1A,0x04,
0x1B,0x04, 0x1F,0x04, 0x1A,0x03, 0x1A,0x67, 0x19,0x04,
0x1A,0x18, 0x1B,0x04, 0x1F,0x04, 0x1A,0x02, 0x1F,0x04,
0x17,0x04, 0x1A,0x04, 0x1B,0x04, 0x1F,0x04, 0x17,0x04,
0x1A,0x04, 0x1F,0x04, 0x20,0x04, 0x17,0x04, 0x1F,0x04,
0x17,0x04, 0x1B,0x04, 0x17,0x04, 0x1A,0x04, 0x17,0x04,
0x1B,0x04, 0x17,0x68, 0x19,0x04, 0x1A,0x04, 0x1B,0x04,
0x17,0x04, 0x19,0x04, 0x1B,0x04, 0x1F,0x04, 0x17,0x04,
0x1B,0x04, 0x17,0x04, 0x1A,0x04, 0x17,0x04, 0x21,0x04,
0x17,0x04, 0x1F,0x04, 0x17,0x04, 0x1A,0x04, 0x1B,0x04,
0x1F,0x04, 0x17,0x04, 0x1A,0x04, 0x1F,0x04, 0x20,0x04,
0x17,0x04, 0x1F,0x04, 0x17,0x04, 0x1B,0x04, 0x17,0x04,
0x1A,0x04, 0x17,0x04, 0x21,0x04, 0x17,0x68, 0x19,0x04,
0x17,0x04, 0x1F,0x04, 0x17,0x04, 0x1B,0x04, 0x17,0x04,
0x1A,0x04, 0x17,0x04, 0x21,0x04, 0x17,0x04, 0x1A,0x02,
0x21,0x04, 0x1A,0x04, 0x1F,0x04, 0x20,0x04, 0x21,0x04,
0x1A,0x04, 0x1F,0x04, 0x23,0x04, 0x22,0x04, 0x1A,0x04,
0x21,0x04, 0x1A,0x04, 0x22,0x04, 0x1A,0x04, 0x24,0x04,
0x1A,0x04, 0x23,0x04, 0x1B,0x04, 0x20,0x04, 0x24,0x04,
0x23,0x04, 0x1B,0x04, 0x22,0x04, 0x1B,0x04, 0x21,0x04,
0x17,0x04, 0x20,0x04, 0x17,0x04, 0x1F,0x04, 0x17,0x04,
0x1B,0x04, 0x17,0x04, 0x1F,0x04, 0x17,0x04, 0x1A,0x04,
0x1B,0x04, 0x1F,0x04, 0x17,0x04, 0x1A,0x04, 0x1F,0x04,
0x20,0x04, 0x17,0x04, 0x1F,0x04, 0x17,0x04, 0x1B,0x04,
0x17,0x04, 0x1A,0x04, 0x17,0x04, 0x1B,0x04, 0x17,0x68,
0x19,0x04, 0x1B,0x04, 0x20,0x04, 0x19,0x04, 0x1B,0x04,
0x20,0x04, 0x21,0x04, 0x1B,0x04, 0x20,0x04, 0x21,0x68,
0x23,0x04, 0x21,0x04, 0x20,0x04, 0x1F,0x04, 0x1B,0x04,
0x1F,0x04, 0x1A,0x03, 0x1B,0x04, 0x1F,0x04, 0x1A,0x03,
0x17,0x04, 0x18,0x04, 0x16,0x03, 0x17,0x04, 0x18,0x04,
0x16,0x67, 0x18,0x68, 0x19,0x04, 0x17,0x03, 0x17,0x03,
0x11,0x04, 0x15,0x04, 0x10,0x03, 0x11,0x04, 0x15,0x04,
0x10,0x02, 0x1B,0x04, 0x1F,0x04, 0x1A,0x03, 0x1B,0x04,
0x1F,0x04, 0x1A,0x03, 0x17,0x04, 0x18,0x04, 0x16,0x03,
0x17,0x04, 0x18,0x04, 0x16,0x67, 0x18,0x68, 0x19,0x04,
0x17,0x03, 0x17,0x03, 0x11,0x04, 0x15,0x04, 0x10,0x03,
0x11,0x04, 0x15,0x04, 0x10,0x02, 0x1B,0x04, 0x1F,0x04,
0x1A,0x17, 0x21,0x04, 0x1A,0x04, 0x1B,0x04, 0x1F,0x04,
0x1A,0x17, 0x21,0x04, 0x1A,0x04, 0x1B,0x04, 0x1F,0x04,
0x1A,0x03, 0x1A,0x67, 0x19,0x04, 0x1A,0x18, 0x1B,0x04,
0x1F,0x04, 0x1A,0x02, 0x1B,0x04, 0x1F,0x04, 0x1A,0x17,
0x21,0x04, 0x1A,0x04, 0x1B,0x04, 0x1F,0x04, 0x1A,0x17,
0x21,0x04, 0x1A,0x04, 0x1B,0x04, 0x1F,0x04, 0x1A,0x03,
0x1A,0x67, 0x19,0x04, 0x1A,0x18, 0x1B,0x04, 0x1F,0x04,
0x1A,0x02, 0x1B,0x04, 0x1F,0x04, 0x1A,0x03, 0x1B,0x04,
0x1F,0x04, 0x1A,0x03, 0x17,0x04, 0x18,0x04, 0x16,0x03,
0x17,0x04, 0x18,0x04, 0x16,0x67, 0x18,0x68, 0x19,0x04,
0x17,0x03, 0x17,0x03, 0x11,0x04, 0x15,0x04, 0x10,0x03,
0x11,0x04, 0x15,0x04, 0x10,0x02, 0x1B,0x04, 0x1F,0x04,
0x1A,0x03, 0x1B,0x04, 0x1F,0x04, 0x1A,0x03, 0x17,0x04,
0x18,0x04, 0x16,0x03, 0x17,0x04, 0x18,0x04, 0x16,0x67,
0x18,0x68, 0x19,0x04, 0x17,0x03, 0x17,0x03, 0x1B,0x03,
0x1A,0x03, 0x21,0x03, 0x24,0x66, 0x18,0x68, 0x19,0x04,
0x17,0x03, 0x17,0x03, 0x1B,0x03, 0x17,0x03, 0x1A,0x03,
0x21,0x66, 0x18,0x68, 0x19,0x04, 0x17,0x03, 0x17,0x03,
0x1B,0x03, 0x17,0x03, 0x1A,0x03, 0x1A,0x02, 0x00,0x00
};
題目的代碼,emmm.....音樂數據太多,只放了一小段
#include <reg52.h>
#include <intrins.h>
//_nop_()函數所在頭文件
char code waringset = 22; //報警溫度
/*----------------音樂函數申明------------------------------*/
void InitialSound(unsigned char *Sound0,unsigned char Signature0,
unsigned char Octachord0,unsigned int Speed0);
void Play();
/*----------------音樂數據申明------------------------------*/
extern unsigned char code Music_Croatian_Rhapsody[];
//(數據太大,放后面了,所以加extern以說明)
/*----------------溫度傳感器申明----------------------------*/
bit Start18B20(); //初始化DS18B20
bit Get18B20Temp(int *temp);//讀取溫度
/*----------------LCD1602顯示模塊申明------------------------*/
void InitLcd1602(); //LCD1602初始化函數
void display(); //顯示控制模塊
/*-------------------LCD1602顯示緩存-------------------------*/
unsigned char strbuff[11];//格式:“+125.0.0625°C”
unsigned char code waringstr[] = " Alarm! ";//報警顯示文字
unsigned char code striswaring[] = " ";//取消報警顯示文字
/*----------------------其他全局變量-------------------------*/
int Temp = 0; //讀取到的當前溫度值(16bit二進制)
int intT, decT; //溫度值的整數和小數部分
bit sign; //溫度值的正負(1正,0負)
bit iswaring = 0; //是否報警標志位
void main()
{
bit sta; //是否成功讀取標志
unsigned int cnt = 0; //檢測標志,主要用於控制檢測溫度的頻率
InitialSound(Music_Croatian_Rhapsody,0,2,360); //蜂鳴器初始化
Start18B20(); //啟動DS18B20
InitLcd1602(); //初始化LCD1602液晶模塊
while(1)
{
cnt++;
if(((iswaring == 0)&&(cnt>14000))||((iswaring == 1)&&(cnt>3))) //大約0.8s(仿真得到) DS18B20最多750ms轉化好
{
cnt = 0;
sta = Get18B20Temp(&Temp); //讀取當前溫度
if (sta) //讀取成功時,刷新當前溫度顯示
{
if((Temp >> 11) < 4) //如果前面5位大部分是0
{
sign = 1; //正號,溫度值為正
}else{
sign = 0; //溫度值為負
}
if(sign == 1) //正號
{
intT = Temp >> 4; //分離出溫度值整數部分
decT = Temp & 0x0F; //分離出溫度值小數部分
decT = decT * 625; //小數轉換成10進制精度
//ftemp = intT + decT/10000;/*無效*/ //轉換為浮點,以便比較
}else{ //負號
Temp = (~Temp)+1; //取反后+1
intT = (Temp >> 4)*(-1);//分離出溫度值整數部分
decT = Temp & 0x0F; //分離出溫度值小數部分
decT = decT * 625; //小數轉換成10進制精度
//ftemp = (intT + decT/10000)*(-1);//轉換為浮點
}
}
else //讀取失敗時,給出錯誤信息
{
intT = 200; //這個值隨便給,主要是大於126就好
//ftemp = intT;
}
Start18B20(); //重新啟動下一次轉換
display(); //顯示
if(intT >= waringset)
{
iswaring = 1;
}else{
iswaring = 0;
}
}
if((iswaring == 1)&&(intT<126)&&(intT>-55))
{
Play(); //蜂鳴器
}else{
EA = 0; //蜂鳴器是用中斷,關掉
}
}
}
/*-----------------------以下是LCD1602顯示驅動------------------*/
//定義LCD1602顯示相關的IO接口
#define LCD1602_DB P0
sbit LCD1602_RS = P1^0;
sbit LCD1602_RW = P1^1;
sbit LCD1602_E = P1^5;
//LCD1602函數調用申明
void LcdShowStr(unsigned char x, unsigned char y,unsigned char *str, unsigned char len);
//顯示控制模塊
void display()
{
static int intTb, decTb; //溫度值的整數和小數部分備份
static bit signb; //溫度值的正負(1正,0負)備份
if(iswaring == 1)
{
LcdShowStr(0,1,waringstr,16);
}
else
{
LcdShowStr(0,1,striswaring,11);
}
if((decTb != decT) || (intTb != intT) || (signb != sign))//如果有變化
{
/*備份當前值*/
decTb = decT;
intTb = intT;
signb = sign;
if(intT>126) //如果信息錯誤,這個判斷是溫度顯示特有的
{
unsigned char i = 1;
//顯示錯誤Error!
strbuff[10] = '!';
strbuff[9] = 'r';
strbuff[8] = 'o';
strbuff[7] = 'r';
strbuff[6] = 'r';
strbuff[5] = 'E';
for(i = 0;i<5;i++)
{
strbuff[i] = ' ';
}
}else{ //信息正確
if(sign == 1)strbuff[0] = ' ';else strbuff[0] = '-';//符號位
if((intT/100) == 0)strbuff[1] = ' ';else strbuff[1] = ((intT/100)%10)+0x30;//百位
if((intT/10) == 0)strbuff[2] = ' ';else strbuff[2] = ((intT/10)%10)+0x30;//十位
if((intT) == 0)strbuff[3] = ' ';else strbuff[3] = (intT%10)+0x30;//個位加“.”
if((decT/1000) == 0)strbuff[5] = '0';else strbuff[5] = ((decT/1000)%10)+0x30;//十分位
if((decT/100) == 0)strbuff[6] = '0';else strbuff[6] = ((decT/100)%10)+0x30;//百分位
if((decT/10) == 0)strbuff[7] = '0';else strbuff[7] = ((decT/10)%10)+0x30;//千分位
if((decT) == 0)strbuff[8] = '0';else strbuff[8] = (decT%10)+0x30;//萬分位
/*以上是 載數碼管緩存代碼,把十進制分離,大家自己研究這里不多解釋*/
strbuff[4] = '.';
strbuff[9] = 0XDF;//‘°’
strbuff[10] = 'C';
}
LcdShowStr(4,0,strbuff,11); //顯示,初始位置隨意,只要能顯示完整就好
}
}
//等待液晶准備好
void LcdWaitReady()
{
unsigned char sta;
LCD1602_DB = 0xFF;
LCD1602_RS = 0;
LCD1602_RW = 1;
do {
LCD1602_E = 1; //使能LCD1602
sta = LCD1602_DB; //讀取狀態字
LCD1602_E = 0; //避免干擾其他器件
} while (sta & 0x80); //第七位等於1表示液晶正忙,重復檢測直到第七位等於0為止
}
//向LCD1602液晶寫入一字節命令,cmd為待寫入命令值
void LcdWriteCmd(unsigned char cmd)
{
LcdWaitReady();
LCD1602_RS = 0;
LCD1602_RW = 0;
LCD1602_DB = cmd;
LCD1602_E = 1;
LCD1602_E = 0;
}
//向LCD1602液晶寫入一字節數據,dat為待寫入數據值
void LcdWriteDat(unsigned char dat)
{
LcdWaitReady();
LCD1602_RS = 1;
LCD1602_RW = 0;
LCD1602_DB = dat;
LCD1602_E = 1;
LCD1602_E = 0;
}
//設置顯示RAM起始地址,亦即光標位置,(x,y)對應屏幕上的字符的坐標
void LcdSetCursor(unsigned char x, unsigned char y)
{
unsigned char addr;
if (y == 0) //由輸入的屏幕坐標計算顯示RAM的地址
addr = 0x00 + x; //第一行字符地址從0x00起始
else
addr = 0x40 + x; //第二行字符地址從0x40起始
LcdWriteCmd(addr | 0x80); //設置RAM地址
}
//在液晶上顯示字符串,(x,y)-對應屏幕上的起始坐標,
//str-字符串指針,len-需顯示的字符長度
void LcdShowStr(unsigned char x, unsigned char y,unsigned char *str, unsigned char len)
{
LcdSetCursor(x, y); //設置起始地址
while (len--) //連續寫入len個字符數據
{
LcdWriteDat(*str++); //先取str指向的數據,然后str自加1
}
}
void InitLcd1602()//初始化1602液晶
{
LcdWriteCmd(0x38); //16*2顯示,5*7點陣,8位數據接口
LcdWriteCmd(0x0C); //顯示器開,光標關閉
LcdWriteCmd(0x06); //文字不動,地址自動+1
LcdWriteCmd(0x01); //清屏
}
/*-----------------------以下是溫度傳感器驅動------------------*/
//DS18B20通信引腳
sbit IO_18B20 = P3^2;
void DelayX10us(unsigned char t)
{
do {
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
} while (--t);
/*_nop_()函數在12M晶振中延遲1us,為什么這里是8個_nop_()
因為while和--t也是需要時間的,這里不一定是准確的10us/循環
只是大致的時間*/
}
bit Get18B20Ack() //DS18B20存在檢測函數
{
bit ack;
EA = 0; //關中斷
IO_18B20 = 0; //拉低引腳
DelayX10us(50); //延時500us(480us - 960us)
IO_18B20 = 1; //釋放總線
DelayX10us(6); //延時60us(15us - 60us)
ack = IO_18B20; //讀取響應(60us - 240us)
while(!IO_18B20); //等待DS18B20釋放總線 (60us - 240us)
EA = 1; //取消關中斷
return ack; //返回是否存在 (0:存在 1:不存在)
}
void Write18B20(unsigned char dat) //寫DS18B20
{
unsigned char mask; //臨時變量定義
EA = 0; //關中斷
for(mask=0x01; mask!= 0; mask<<=1) //循環發送單個bit位
{
IO_18B20 = 0; //拉低(請求讀寫操作)
_nop_(); //延時(1us < time <= 15us)
_nop_();
if((mask&dat) == 0) //按位讀取dat
IO_18B20 = 0; //本位是0,拉低
else
IO_18B20 = 1; //本位是1,拉高
//上面這個操作DS18B20讀取(最小時間 0us<time<15us,
//典型時間 15us,最大時間45us)
DelayX10us(6); //等待60us(足夠DS18B20讀取)
IO_18B20 = 1; //釋放總線
}
EA = 1; //取消關中斷
}
unsigned char Read18B20() //讀DS18B20
{
unsigned char dat; //數據緩存變量
unsigned char mask; //臨時變量
EA = 0; //關中斷
for(mask=0x01; mask!=0; mask<<=1)//同上循環按位操作
{
IO_18B20 = 0; //讀寫請求
_nop_(); //等待(1us < time < 15us)
_nop_();
IO_18B20 = 1; //初始化讀操作
_nop_(); //等待DS18B20輸出
_nop_();
if(!IO_18B20) //讀
dat &= ~mask; //“0”
else
dat |= mask; //“1”
DelayX10us(6); //等待DS18B20釋放總線
}
EA = 1; //取消關中斷
return dat; //返回數據
}
bit Start18B20() //初始化DS18B20
{
bit ack; //存在標志
ack = Get18B20Ack();//檢測存在
if(ack == 0) //存在
{ //寫命令使工作
Write18B20(0xCC); //跳過ROM檢測
Write18B20(0x44); //啟動溫度轉換
}
return ~ack; //返回是否成功(1是,0否)
}
bit Get18B20Temp(int *temp) //獲取DS18B20溫度存於temp
{
bit ack; //存在標志
unsigned char LSB, MSB; //數據低/高位
ack = Get18B20Ack(); //檢測存在
if(ack == 0) //存在
{ //寫指令
Write18B20(0xCC); //跳過ROM檢測
Write18B20(0xBE); //讀寄存器
LSB = Read18B20(); //讀低位
MSB = Read18B20(); //讀高位
*temp = ((int)MSB<<8) + LSB; //合並
}
return ~ack; //返回結果(1成功,0失敗)
}
/*-----------------------以下是蜂鳴器演奏------------------*/
#define SYSTEM_OSC 11059200 //12000000 //定義晶振頻率12000000HZ
#define SOUND_SPACE 4/5 //定義普通音符演奏的長度分率,//每4分音符間隔
sbit BeepIO = P1^6; //定義輸出管腳
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; //音長定時器初值暫存
unsigned char Signature;
unsigned char Octachord;
unsigned int Speed;
unsigned char *Sound;
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;
//unsigned int len = 0,poi = 0; //備份SoundLength
void InitialSound(unsigned char *Sound0,unsigned char Signature0,
unsigned char Octachord0,unsigned int Speed0)
{
Signature = Signature0;
Octachord = Octachord0;
Speed = Speed0;
Sound = Sound0;
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 = 1;
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; // 普通音最長間隔標准
BeepIO = 1;
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;
/*len = SoundLength;
poi = Point;*/
}
void BeepTimer0(void) interrupt 1 //音符發生中斷
{
BeepIO = !BeepIO;
TH0 = Sound_Temp_TH0;
TL0 = Sound_Temp_TL0;
}
void Play()
{
EA = 1;
TR0 = 0;
TR1 = 1;
if(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; BeepIO=1;
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];
}
else
{
/*SoundLength = len;
Point = poi;*/
InitialSound(Music_Croatian_Rhapsody,0,2,360);
}
BeepIO = 1;
TR0 = 0;
TR1 = 0;
}
//這里放生成的音樂數據
unsigned char code Music_Croatian_Rhapsody[]={
0x1B,0x04, 0x1F,0x04, 0x1A,0x17, 0x17,0x04, 0x18,0x04,
0x16,0x7B, 0x18,0x68, 0x19,0x04, 0x17,0x03, 0x17,0x03,
0x11,0x04, 0x15,0x04, 0x10,0x03, 0x11,0x04, 0x15,0x04,
0x10,0x02, 0x1F,0x04, 0x17,0x04, 0x1A,0x04, 0x1B,0x04,
0x1F,0x04, 0x17,0x04, 0x1A,0x04, 0x1F,0x04, 0x20,0x04,
0x17,0x04, 0x1F,0x04, 0x17,0x04, 0x1B,0x04, 0x17,0x04,
0x1A,0x04, 0x17,0x04, 0x1B,0x04, 0x17,0x68, 0x19,0x04,
0x1A,0x04, 0x1B,0x04, 0x17,0x04, 0x19,0x04, 0x1B,0x04,
0x1F,0x04, 0x17,0x04, 0x1B,0x04, 0x17,0x04, 0x1A,0x04,
0x17,0x04, 0x21,0x04, 0x17,0x04, 0x1F,0x04, 0x17,0x04,
0x1A,0x04, 0x1B,0x04, 0x1F,0x04, 0x17,0x04, 0x1A,0x04,
0x1F,0x04, 0x20,0x04, 0x17,0x04, 0x1F,0x04, 0x17,0x04,
0x1B,0x04, 0x17,0x04, 0x1A,0x04, 0x17,0x04, 0x21,0x04,
0x17,0x68, 0x19,0x04, 0x17,0x04, 0x1F,0x04, 0x17,0x04,
0x1B,0x04, 0x17,0x04, 0x1A,0x04, 0x17,0x04, 0x21,0x04,
0x17,0x04, 0x1A,0x02, 0x1F,0x04, 0x17,0x04, 0x1A,0x04,
0x1B,0x04, 0x1F,0x04, 0x17,0x04, 0x1A,0x04, 0x1F,0x04,
0x20,0x04, 0x17,0x04, 0x1F,0x04, 0x17,0x04, 0x1B,0x04,
0x17,0x04, 0x1A,0x04, 0x17,0x04, 0x1B,0x04, 0x17,0x68,
0x19,0x04, 0x1A,0x04, 0x1B,0x04, 0x17,0x04, 0x19,0x04,
0x1B,0x04, 0x1F,0x04, 0x17,0x04, 0x1B,0x04, 0x17,0x04,
0x1A,0x04, 0x17,0x04, 0x21,0x04, 0x17,0x04, 0x1F,0x04,
0x17,0x04, 0x1A,0x04, 0x1B,0x04, 0x1F,0x04, 0x17,0x04,
0x1A,0x04, 0x1F,0x04, 0x20,0x04, 0x17,0x04, 0x1F,0x04,
0x17,0x04, 0x1B,0x04, 0x17,0x04, 0x1A,0x04, 0x17,0x04,
0x21,0x04, 0x17,0x68, 0x19,0x04, 0x17,0x04, 0x1F,0x04,
0x17,0x04, 0x1B,0x04, 0x17,0x04, 0x1A,0x04, 0x17,0x04,
0x21,0x04, 0x17,0x04, 0x1A,0x02, 0x00,0x00
};
怎么樣
音樂是不是很動聽呢? ٩(●´৺`●)૭٩(●´৺'●)و,想嘗試創作更多的蜂鳴器音樂嗎?快發表你的看法吧!!
嗶哩嗶哩效果視頻演示:https://www.bilibili.com/video/BV1Dt41197b9/
謝謝