【製作】基於金沙灘51微控制器的蜂鳴器音樂 - 克羅埃西亞狂想曲
阿新 • • 發佈:2021-01-11
基於金沙灘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/
謝謝