基于51單片機(jī)的電子琴設(shè)計(jì)附原理圖、PCB和程序-課程設(shè)計(jì)說明書_第1頁
基于51單片機(jī)的電子琴設(shè)計(jì)附原理圖、PCB和程序-課程設(shè)計(jì)說明書_第2頁
基于51單片機(jī)的電子琴設(shè)計(jì)附原理圖、PCB和程序-課程設(shè)計(jì)說明書_第3頁
基于51單片機(jī)的電子琴設(shè)計(jì)附原理圖、PCB和程序-課程設(shè)計(jì)說明書_第4頁
基于51單片機(jī)的電子琴設(shè)計(jì)附原理圖、PCB和程序-課程設(shè)計(jì)說明書_第5頁
已閱讀5頁,還剩30頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

課程設(shè)計(jì)說明書題目: 基于單片機(jī)的電子琴設(shè)計(jì)院(系):電子工程與自動(dòng)化學(xué)院專業(yè):測(cè)控技術(shù)與儀器(卓越)2013年9月21日目錄1摘要……………………12關(guān)鍵字…………………13設(shè)計(jì)任務(wù)及要求………14方案可行性論證………15程序框圖………………26關(guān)鍵單元電路與程序介紹……………36.1復(fù)位與震蕩電路………………36.24x4矩陣鍵盤…………………36.3數(shù)碼管與LED燈………………46.4蜂鳴器…………66.5音樂相關(guān)知識(shí)…………………77調(diào)試過程………………118總結(jié)與體會(huì)……………119參考文獻(xiàn)………………1110附錄……………………1210.1設(shè)備與儀器……………………1210.2軟件……………1210.3原件清單………1210.4原理圖與PCB圖………………1310.5總程序……………1410.6實(shí)物圖……………31【摘要】:打造一個(gè)多功能電子琴,核心是一塊單片機(jī)。單片機(jī)讀取鍵值,為內(nèi)置定時(shí)器賦初值,定時(shí)器每溢出一次,驅(qū)動(dòng)蜂鳴器的引腳電平就取反一次,產(chǎn)生相應(yīng)頻率的方波,即音調(diào);設(shè)好鍵值與數(shù)碼管段碼表的對(duì)應(yīng)關(guān)系,鍵按下時(shí),數(shù)碼管顯示對(duì)應(yīng)音調(diào)。一首音樂儲(chǔ)存在一個(gè)表中,表中的數(shù)據(jù)是音調(diào)與節(jié)拍,單片機(jī)讀取音符的音調(diào)與節(jié)拍,根據(jù)音調(diào)賦予定時(shí)器初值,根據(jù)節(jié)拍決定定時(shí)器工作的時(shí)間,也就是蜂鳴器響的時(shí)間,一個(gè)接一個(gè)地讀取音符,即可播放一首歌曲。節(jié)拍用led燈的點(diǎn)亮個(gè)數(shù)表示。單片機(jī)讀取音樂表中的節(jié)拍,控制led燈的點(diǎn)亮個(gè)數(shù),達(dá)到顯示節(jié)拍的效果。特別要注意的是:該方案采用了兩個(gè)定時(shí)器,T0、T1。T0作為驅(qū)動(dòng)蜂鳴器的定時(shí)器,要給予高優(yōu)先級(jí),不然會(huì)被T1干擾,音質(zhì)變差?!娟P(guān)鍵字】:?jiǎn)纹瑱C(jī)、stc89c52、電子琴、C51、keil?!驹O(shè)計(jì)任務(wù)及要求】:1.通過按鍵能夠發(fā)出相應(yīng)的音符并播放產(chǎn)生樂音,實(shí)現(xiàn)演奏;2.演奏的同時(shí)可數(shù)字顯示當(dāng)前的音調(diào),利于培養(yǎng)樂感3.可以選定播放固定樂曲自動(dòng)演奏,演奏時(shí)LED進(jìn)行節(jié)拍指示;4.在自動(dòng)演奏和奏樂的過程中按停止鍵則中斷演奏;5.可以選擇調(diào)節(jié)音或小?!痉桨缚尚行哉撟C】:本課題采用stc89c52單片機(jī)作為核心器件,實(shí)現(xiàn)基本的音樂彈奏、音樂播放、音調(diào)顯示和音樂節(jié)拍指示的功能。音樂彈奏:通過程序識(shí)別4x4矩陣鍵盤中按下的鍵的坐標(biāo)(x,y),

然后根據(jù)(x,y)從計(jì)數(shù)初值表中讀取對(duì)應(yīng)的計(jì)數(shù)初值,賦值給定時(shí)器0,定時(shí)器產(chǎn)生對(duì)應(yīng)頻率的方波,達(dá)到播放對(duì)應(yīng)音調(diào)的功能。音樂播放:先建立一個(gè)包含一首音樂的音調(diào)與節(jié)拍的表。其中,音調(diào)就是0x01(低音、do)、0x12(中音、re)、0x23(高音、mi)之類的數(shù);節(jié)拍就是0x02(半拍),0x04(一拍)之類的數(shù)。然后,根據(jù)音調(diào)讀取計(jì)數(shù)初值,再將計(jì)數(shù)初值賦給定時(shí)器T0->開啟定時(shí)器T0->讀取節(jié)拍并延時(shí)->關(guān)閉定時(shí)器T0。這樣就發(fā)出了一個(gè)音,然后再讀下一個(gè)音的初值與節(jié)拍,重復(fù)上一個(gè)操作即可。(具體實(shí)現(xiàn)方法見附錄總程序)數(shù)碼管顯示音調(diào):

①按鍵:讀出按鍵坐標(biāo)(x,y),用if語句來判斷(x,y)該給數(shù)碼管賦什么值,然后從ucharcodenum[]表中讀取這個(gè)值賦給數(shù)碼管(例如P0)。②播放歌曲時(shí):讀入音調(diào),根據(jù)音調(diào)的值來判斷num[i]這個(gè)表中的i,再把num[i]賦給P0口。4.led燈的節(jié)拍指示:采用定時(shí)器1來控制,作為節(jié)拍指示。①按鍵時(shí):根據(jù)按下的時(shí)長(zhǎng)來控制led的點(diǎn)亮個(gè)數(shù),并且是按一定的時(shí)間間隔逐個(gè)點(diǎn)亮;釋放按鍵時(shí),led燈按一定的時(shí)間間隔逐個(gè)熄滅,從而達(dá)到一種比較簡(jiǎn)單的節(jié)拍指示效果。②播放音樂時(shí):根據(jù)音符的節(jié)拍,控制點(diǎn)亮到哪一個(gè)燈,在點(diǎn)亮那個(gè)燈之前,前面的燈逐個(gè)等時(shí)距點(diǎn)亮。音符結(jié)束后,led燈全部一起熄滅。這樣,達(dá)到了一個(gè)精確顯示節(jié)拍的效果。開始開始【程序框圖】:掃描鍵盤掃描鍵盤根據(jù)音調(diào)給T0賦初值開啟T0T1是否停止播放讀下一個(gè)音符關(guān)閉T0T1數(shù)碼管與led數(shù)碼管顯示音調(diào)Led指示節(jié)拍否按節(jié)拍延遲算出音符的音調(diào)、節(jié)拍是否結(jié)束符關(guān)閉定時(shí)器P0口置0否否是按鍵是否釋放開啟定時(shí)器,并賦初值,蜂鳴器發(fā)聲算出定時(shí)器初值數(shù)碼管顯示音調(diào)識(shí)別按鍵有矩陣鍵按下否否播放鍵按下讀取歌曲是根據(jù)音調(diào)給T0賦初值開啟T0T1是否停止播放讀下一個(gè)音符關(guān)閉T0T1數(shù)碼管與led數(shù)碼管顯示音調(diào)Led指示節(jié)拍否按節(jié)拍延遲算出音符的音調(diào)、節(jié)拍是否結(jié)束符關(guān)閉定時(shí)器P0口置0否否是按鍵是否釋放開啟定時(shí)器,并賦初值,蜂鳴器發(fā)聲算出定時(shí)器初值數(shù)碼管顯示音調(diào)識(shí)別按鍵有矩陣鍵按下否否播放鍵按下讀取歌曲是是是 是是【復(fù)位與震蕩電路】:原件的參數(shù)如圖所示。C1,C2可采用30pF無極性陶瓷電容;C3可采用10μF記性電解質(zhì)電容。值得注意的是,晶振不能隨便摸!尤其在通電工作的時(shí)候,觸摸容易損壞。自從摸過一次后,震蕩頻率變得不穩(wěn)定,蜂鳴器聲音時(shí)好時(shí)壞?!?x4矩陣鍵盤】:鍵盤掃描的基本思路是:先得出觸發(fā)按鍵的“行”,即橫坐標(biāo)x,再得出他的“列”,即縱坐標(biāo)y。以下是獲取橫坐標(biāo)x的代碼:ucharkey_x()/*P1口高位接縱坐標(biāo)(P1.7-P1.4)低位接橫坐標(biāo)(P1.3-P1.0)*/{ uchari; P1=0x0f; /*有按鍵按下后對(duì)應(yīng)按鍵的橫坐標(biāo)電位被拉低(注意低電位引腳不能被高電位引腳抬高,只能是低電位拉低高電位)*/ if(P1_0==0) { delayms(5);//延時(shí)5ms去抖動(dòng) if(P1_0==0) i=1; } elseif(P1_1==0) { delayms(5); if(P1_1==0) i=2; } elseif(P1_2==0) { delayms(5); if(P1_2==0) i=3; } elseif(P1_3==0) { delayms(5); if(P1_3==0) i=4; } else i=0; return(i); //0表示按鍵未按下}獲取y的方法與獲取x的方法類似,具體可以參考附件總程序。得到觸發(fā)按鍵的坐標(biāo)(x,y)之后,可以通過x,y的值來確定按鍵的功能。例如x==1,y==1時(shí)(S1按下),可以讓數(shù)碼管顯示1: if(x==1&&y==1) P0=led_table[1];或者更方便一點(diǎn):if(x==1) P0=led_table[y];就能顯示第一行的所有的數(shù)了?!緮?shù)碼管與LED燈】: 數(shù)碼管: 在本課題中,數(shù)碼管要顯示A-G,1-7,1.-7.,所以段碼比較另類。num[0]的值是沒用到的,起占位作用。ucharcodenum[]={0x00, //共陰極數(shù)碼管段選碼0x77,0x7c,0x39,0x5e,0x79,0x71,0x3d, //a-g0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, //1-70x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87 //1.-7.};編寫程序時(shí),要根據(jù)實(shí)際情況來編寫:比如16個(gè)按鍵不能夠把低中高音都全部表示完全,只能選取合適的部分。我讓第一行的按鍵觸發(fā)低音4-7,第二行觸發(fā)中音1-4,第三行觸發(fā)中音5-7和高音1,第四行觸發(fā)高音2-5。這樣設(shè)置能彈奏大部分曲目。以下是控制數(shù)碼管的代碼片段: if(x==1) P0=num[3+y]; //低音4-7 elseif(x==2) P0=num[7+y]; //中音1-4 elseif(x==3) P0=num[11+y]; //中音5-7和高音1 elseif(x==4) P0=num[15+y]; //高音2-5LED燈: 因?yàn)長(zhǎng)ED燈要按一定的時(shí)間逐個(gè)點(diǎn)亮或者逐個(gè)熄滅,所以我用定時(shí)器1來控制它。定時(shí)器1每溢出一次并滿足一定條件時(shí)flash變量就+1或者-1,然后從led_table[]這個(gè)表中讀出相應(yīng)的數(shù)賦給P2口。表:ucharcodeled_table[]={0xff,0x7f,0x3f,0x1f,0x0f,0x07,0x03,0x01,0x00};/*發(fā)光二極管閃爍表*/代碼:if(x!=0&&y!=0&&flash<8) //最大加到8 ++flash; elseif(x==0&&y==0&&flash>0)//最小減到0 --flash; P2=led_table[flash];播放音樂時(shí)又有所不同: 播放音樂時(shí),led燈要精確地顯示當(dāng)前音符的節(jié)拍,所以if語句里加了一條限制語句:flash<jiepai)代碼:if(out==1&&flash<8&&flash<jiepai) /*out==1表示有歌曲發(fā)聲時(shí),(flash<jiepai)使led燈剛好指示節(jié)拍*/ ++flash; elseif(out==0&&flash>0) --flash; P2=led_table[flash]; 這樣做,就能看得出音符的節(jié)拍了。只是,由于led燈的個(gè)數(shù)有限,所以大于二分音符(2拍)的節(jié)拍就無法看到了。因?yàn)?個(gè)燈全亮才表示二分音符。如果當(dāng)初采用16個(gè)燈的話,就沒有這個(gè)窘境了?!痉澍Q器】:蜂鳴器采用一個(gè)s8550NPN三極管驅(qū)動(dòng),一個(gè)可變電阻改變音量。三極管的選用要注意放大倍數(shù),放大倍數(shù)太小會(huì)導(dǎo)致蜂鳴器聲音很小。最初采用8050就造成了這個(gè)問題。 另外,采用P3.0口連接接蜂鳴器是一個(gè)錯(cuò)誤。因?yàn)镻3.0、P3.1是燒寫程序用到的接口。倘若連接了其他器件,每次調(diào)試都要拔下燒寫線,很不方便?!疽魳废嚓P(guān)知識(shí)】:【表6.5.1】音符頻率對(duì)照表音符頻率(HZ)簡(jiǎn)譜碼(T值)音符頻率(HZ)簡(jiǎn)譜碼(T值)低1DO262636280xf88c#4FA#74064860#1DO#27763731中5SO784648980xfd82低2RE294638350xf95b#5SO#83164934#2RE#31163928中6LA880649680xfdc8低3M330640210xfa15#693264994低4FA349641030xfa67中7SI988650300xfe06#4FA#37064185高1DO1046650580xfe22低5SO392642600xfb04#1DO#110965085#5SO#41564331高2RE1175651100xfe56低6LA440644000xfb90#2RE#124565134#646664463高3M1318651570xfe85低7SI494645240xfc0c高4FA1397651780xfe9a中1DO523645800xfc44#4FA#148065198#1DO#55464633高5SO1568652170xfec1中2RE587646840xfcac#5SO#166165235#2RE#62264732高6LA1760652520xfee4中3M659647770xfd09#6186565268中4FA698648200xfd34高7SI1967652830xff03音調(diào)、節(jié)拍以及編碼的確定方法:一般說來,單片機(jī)演奏音樂基本都是單音頻率,它不包含相應(yīng)幅度的諧波頻率,也就是說不能像電子琴那樣能奏出多種音色的聲音。因此單片機(jī)奏樂只需弄清楚兩個(gè)概念即可,也就是“音調(diào)”和節(jié)拍。其中節(jié)拍表示一個(gè)音符唱多長(zhǎng)的時(shí)間。音調(diào)的確定:不同音高的樂音是用C、D、E、F、G、A、B來表示,這7個(gè)字母就是音樂的音名,它們一般依次唱成DO、RE、MI、FA、SO、LA、SI,即唱成簡(jiǎn)譜的1、2、3、4、5、6、7,相當(dāng)于漢字“多來米發(fā)梭拉西”的讀音,這是唱曲時(shí)樂音的發(fā)音,所以叫“音調(diào)”,即Tone。把C、D、E、F、G、A、B這一組音的距離分成12個(gè)等份,每一個(gè)等份叫一個(gè)“半音”。兩個(gè)音之間的距離有兩個(gè)“半音”,就叫“全音”。在鋼琴等鍵盤樂器上,C–D、D–E、F–G、G–A、A–B兩音之間隔著一個(gè)黑鍵,他們之間的距離就是全音;E–F、B–C兩音之間沒有黑鍵相隔,它們之間的距離就是半音。通常唱成1、2、3、4、5、6、7的音叫自然音,那些在它們的左上角加上﹟號(hào)或者b號(hào)的叫變化音。﹟叫升記號(hào),表示把音在原來的基礎(chǔ)上升高半音,b叫降記音,表示在原來的基礎(chǔ)上降低半音。例如高音DO的頻率(1046Hz)剛好是中音DO的頻率(523Hz)的一倍,中音DO的頻率(523Hz)剛好是低音DO頻率(266Hz)的一倍;同樣的,高音RE的頻率(1175Hz)剛好是中音RE的頻率(587Hz)的一倍,中音RE的頻率(587Hz)剛好是低音RE頻率(294Hz)的一倍。 1)要產(chǎn)生音頻脈沖,只要算出某一音頻的周期(1/頻率),然后將此周期除以2,即為半周期的時(shí)間。利用定時(shí)器計(jì)時(shí)這半個(gè)周期時(shí)間,每當(dāng)計(jì)時(shí)到后就將輸出脈沖的I/O反相,然后重復(fù)計(jì)時(shí)此半周期時(shí)間再對(duì)I/O反相,就可在I/O腳上得到此頻率的脈沖。 2)利用stc89c52的內(nèi)部定時(shí)器使其工作在計(jì)數(shù)器模式MODE1下,改變計(jì)數(shù)值TH0及TL0以產(chǎn)生不同頻率的方法。 此外結(jié)束符和休止符可以分別用代碼00H和FFH來表示,若查表結(jié)果為00H,則表示曲子終了;若查表結(jié)果為FFH,則產(chǎn)生相應(yīng)的停頓效果。 3)例如頻率為523Hz,其周期T=1/523=1912us,因此只要令計(jì)數(shù)器計(jì)時(shí)956us/1us=956,在每次計(jì)數(shù)956次時(shí)將I/O反相,就可得到中音DO(523Hz)。 計(jì)數(shù)脈沖值與頻率的關(guān)系公式如下: N=Fi2Fr N:計(jì)算值; Fi:內(nèi)部計(jì)時(shí)一次為1us,故其頻率為1MHz;其計(jì)數(shù)值的求法如下:T=65536-N=65536-Fi2Fr例如:設(shè)K=65536,F(xiàn)=1000000=Fi=1MHz,求低音DO(261Hz)。中音DO(523Hz)。高音的DO(1046Hz)的計(jì)算值T=65536-N=65536-Fi2Fr=65536-10000002Fr=65536-500000/Fr低音DO的T=65536-500000/262=63627中音DO的T=65536-500000/523=64580高音DO的T=65536-500000/1047=65059C調(diào)各音符頻率與計(jì)數(shù)值T的對(duì)照表如表所示。低音頻率T參數(shù)中音頻率T參數(shù)高音頻率T參數(shù)Do2621908229Do523956115Do10465757Do﹟2771805217Do﹟554903108Do﹟11095454Re2941701204Re587852102Re11755151Re﹟3111608193Re﹟62280497Re﹟12454848Mi3301515182Mi65975991Mi13184545Fa3491433172Fa69871686Fa13974343Fa﹟3701351162Fa﹟74067681Fa﹟14804141So3921276153So78463877So15683838So﹟4151205145So﹟83160272So﹟16613636La4401136136La88056868La17603434La﹟4641078129La﹟93253664La﹟18653232Si4941012121Si98850661Si19763030表表6.5.2C調(diào)各音符頻率與計(jì)數(shù)值T的對(duì)照表節(jié)拍的確定:若要構(gòu)成音樂,光有音調(diào)是不夠的,還需要節(jié)拍,讓音樂具有旋律(固定的律動(dòng)),而且可以調(diào)節(jié)各個(gè)音的快滿度?!肮?jié)拍”,即Beat,簡(jiǎn)單說就是打拍子,就像我們聽音樂不自主的隨之拍手或跺腳。若1拍實(shí)0.5s,則1/4拍為0.125s。至于1拍多少s,并沒有嚴(yán)格規(guī)定,就像人的心跳一樣,大部分人的心跳是每分鐘72下,有些人快一點(diǎn),有些人慢一點(diǎn),只要聽的悅耳就好。音持續(xù)時(shí)間的長(zhǎng)短即時(shí)值,一般用拍數(shù)表示。休止符表示暫停發(fā)音。一首音樂是由許多不同的音符組成的,而每個(gè)音符對(duì)應(yīng)著不同頻率,這樣就可以利用不同的頻率的組合,加以與拍數(shù)對(duì)應(yīng)的延時(shí),構(gòu)成音樂。了解音樂的一些基礎(chǔ)知識(shí),我們可知產(chǎn)生不同頻率的音頻脈沖即能產(chǎn)生音樂。對(duì)于單片機(jī)來說,產(chǎn)生不同頻率的脈沖是非常方便的,利用單片機(jī)的定時(shí)/計(jì)數(shù)器來產(chǎn)生這樣的方波頻率信號(hào)。因此,需要弄清楚音樂中的音符和對(duì)應(yīng)的頻率,以及單片機(jī)定時(shí)計(jì)數(shù)的關(guān)系。音樂的編碼:每個(gè)音符采用2個(gè)字節(jié)。第一個(gè)字節(jié)表示音調(diào),第二個(gè)字節(jié)表示節(jié)拍。音調(diào)字節(jié)中,高四位表示低中高音,0表示低音,1表示中音,2表示高音;低四位表示“音調(diào)”。比如:0x11表示中音do。節(jié)拍字節(jié)中,數(shù)值i表示代表著延遲i個(gè)十六分音符。比如:0x04,表示延時(shí)4個(gè)16分音符,即延時(shí)1個(gè)四分之一音符。在以四分音符為一拍的歌曲中,0x04就代表一拍。底下沒有橫線,右側(cè)也沒有橫線的數(shù)字(音調(diào)),就用0x04表示他的延時(shí)。底下有一橫線:0x02;右側(cè)有一橫:0x08;右側(cè)兩橫:0x0c;右側(cè)三橫:0x10;右下角有一點(diǎn):加上當(dāng)前延時(shí)的一半。由于不同的歌曲有不同的播放速度,即曲速(單位——拍每分鐘)。所以音樂編碼表中的第0和第1元素用來表示曲速。我們可以找到任意歌曲的簡(jiǎn)譜圖,然后根據(jù)上述規(guī)則編寫出單片機(jī)識(shí)別的簡(jiǎn)譜表。例如:可以翻譯成:ucharcodeymt[]={//玉滿堂0x96,0x00,//曲速0x96表示150拍/分0x00,0x0a,0x05,0x02,0x15,0x02,0x12,0x02,0x13,0x04,0x13,0x02,0x15,0x02,0x12,0x04,0x12,0x02,0x13,0x02,0x12,0x10,0x13,0x04,0x13,0x02,0x12,0x02,0x13,0x04,0x15,0x02,0x16,0x02,0x15,0x0c,0x13,0x02,0x15,0x02,0x16,0x04,0x16,0x02,0x21,0x02,0x16,0x04,0x15,0x02,0x13,0x02,0x15,0x0c,0x15,0x02,0x16,0x02,0x21,0x04,0x21,0x02,0x22,0x02,0x23,0x04,0x22,0x02,0x21,0x02,0x22,0x10,0x23,0x08,0x15,0x02,0x16,0x02,0x21,0x02,0x22,0x02,0x23,0x04,0x23,0x02,0x22,0x02,0x21,0x06,0x21,0x02,0x16,0x04,0x16,0x02,0x21,0x02,0x16,0x04,0x13,0x04,0x15,0x10,0x16,0x04,0x16,0x02,0x21,0x02,0x16,0x04,0x21,0x02,0x22,0x02,0x23,0x04,0x23,0x02,0x22,0x02,0x21,0x06,0x21,0x02,0x16,0x02,0x21,0x02,0x16,0x02,0x21,0x02,0x22,0x02,0x23,0x02,0x25,0x02,0x23,0x02,0x22,0x0c,0x21,0x02,0x22,0x02,0x23,0x06,0x15,0x02,0x16,0x02,0x21,0x02,0x22,0x02,0x23,0x04,0x23,0x02,0x22,0x02,0x21,0x06,0x21,0x02,0x16,0x04,0x16,0x02,0x21,0x02,0x16,0x02,0x21,0x02,0x15,0x02,0x13,0x02,0x15,0x0c,0x13,0x02,0x15,0x02,0x16,0x04,0x16,0x02,0x21,0x02,0x16,0x04,0x16,0x02,0x21,0x02,0x22,0x04,0x22,0x02,0x23,0x02,0x22,0x04,0x22,0x02,0x23,0x02,0x25,0x02,0x26,0x02,0x23,0x02,0x25,0x02,0x22,0x02,0x23,0x02,0x21,0x02,0x16,0x02,0x21,0x10,0xff};【調(diào)試過程】: 編寫程序階段,一個(gè)功能、一個(gè)模塊地編寫。先寫好鍵盤掃描程序,然后再到數(shù)碼管顯示、蜂鳴器發(fā)聲、led節(jié)拍指示。分部進(jìn)行,個(gè)個(gè)擊破?!究偨Y(jié)體會(huì)】:本課題讓我更深刻地認(rèn)識(shí)到了單片機(jī)這種器件,特別是對(duì)單片機(jī)里面的定時(shí)器收獲最多。而且這是我第一次焊雙面板,意義不同凡響。有了這次經(jīng)驗(yàn),對(duì)以后做板子定有深遠(yuǎn)的影響。制作過程中,感觸最深的是解決雜音問題。在彈奏與播放時(shí),蜂鳴器聲音不純,有顫音,影響音樂美感。為此,我煞費(fèi)苦心,花了很多時(shí)間找原因。想到了精簡(jiǎn)定時(shí)器中斷程序里的代碼和運(yùn)算,但效果甚微。直到最后,忽然想到了定時(shí)器有優(yōu)先級(jí)的說法。試了一下,將控制蜂鳴器的定時(shí)器T0設(shè)為高優(yōu)先級(jí)。終于問題解決了!而且是如此的簡(jiǎn)單,但是過程卻是又如此的艱辛,讓人感覺不太值得。。不過,終歸是值得的!【參考文獻(xiàn)】:《單片微機(jī)原理、匯編與C51及接口技術(shù)》(朱定華戴穎穎李川香著)序號(hào)名稱數(shù)量備注1四腳開關(guān)186x6mm212Mhz晶振1330pF陶瓷電容2410μF無極性電容1510K2.2K電阻910Kx9;2.2Kx16240電阻107NPN三極管1s85508七段共陰極數(shù)碼管29無源蜂鳴器110電位器111發(fā)光二極管10紅色x8黃x1綠x112排針3排13雙面覆銅銅板115x10cm1440P杜邦線115單片機(jī)底座216電源開關(guān)117Stc89c52單片機(jī)1【附錄】:設(shè)備與儀器:電腦、單片機(jī)開發(fā)板(或者單片機(jī)燒寫器)軟件:KeiluVision4、DXP09原件清單:原理圖與PCB圖:總程序:#include<reg52.h>#include<intrins.h>#defineucharunsignedchar#defineuintunsignedint#defineallsong4//歌曲總數(shù)按實(shí)際寫sbitP1_0=P1^0;sbitP1_1=P1^1;sbitP1_2=P1^2;sbitP1_3=P1^3;sbitP1_4=P1^4;sbitP1_5=P1^5;sbitP1_6=P1^6;sbitP1_7=P1^7;sbitbeep=P3^0;sbitkey_play=P3^1;ucharx=0; /*矩陣鍵盤橫坐標(biāo)從1開始0為未按下的標(biāo)志*/uchary=0; /*矩陣鍵盤縱坐標(biāo)從1開始0為未按下的標(biāo)志*/ucharflash=0; //控制led燈顯示 的變量*/ucharf_l; /*按鍵發(fā)出音調(diào)的初值(低位)*/ucharf_h; //高位ucharsong_l; /*歌曲音調(diào)的初值(低位)*/ucharsong_h; //高位 ucharout=0; /*聲音輸出變量1表示有輸出0表示無輸出*/ucharyindiao; /*音調(diào) 定義為全局變量為了在播放時(shí)數(shù)碼管能顯示當(dāng)前音調(diào)*/ucharyindiao_h; //音調(diào)的高四位ucharyindiao_l; //音調(diào)的低四位ucharjiepai; /*節(jié)拍(簡(jiǎn)而言之就是一個(gè)音調(diào)響的時(shí)間長(zhǎng)度)*/ucharsong_id=1; //歌曲序號(hào)變量uchartemp_id=1; //歌曲臨時(shí)序號(hào)uintwhich=2; /*簡(jiǎn)譜表里的第幾個(gè)音從第2個(gè)開始第0個(gè)用來存曲速,第1個(gè)占位*/ucharsame=0; /*在暫停時(shí)選了同一首歌曲,用于跳出暫停循環(huán)*/ucharkey_x(); //獲取鍵盤橫坐標(biāo)函數(shù)ucharkey_y(); //獲取鍵盤縱坐標(biāo)函數(shù)voidplay(); //播放歌曲函數(shù)voiddelayms(uintms);//延時(shí)xxms函數(shù)voiddelay(uintpai);//節(jié)拍延時(shí)函數(shù)voidkey_check(); //檢查按鍵狀態(tài)函數(shù)voiddisplay(); //數(shù)碼管顯示對(duì)應(yīng)音調(diào)函數(shù)voidspeak(); /*按鍵后給定時(shí)器0賦對(duì)應(yīng)音調(diào)的初值從而發(fā)出聲音*/ucharchoose(); /*播放狀態(tài)下選歌函數(shù)釋放按鍵后才跳出函數(shù),返回歌曲序號(hào)*/ucharchoose2(); /*暫停狀態(tài)下選歌函數(shù)不用釋放按鍵即可跳出函數(shù),返回歌曲序號(hào)*/voidplay(); //播放歌曲函數(shù)ucharcodenum[]={0x00, //數(shù)碼管段選碼0x77,0x7c,0x39,0x5e,0x79,0x71,0x3d, //a-g0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, //1-70x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87 //1.-7.};ucharcodeled_table[]={0xff,0x7f,0x3f,0x1f,0x0f,0x07,0x03,0x01,0x00};/*發(fā)光二極管閃爍表*/ucharcodechuzhi[]={//音調(diào)對(duì)應(yīng)的計(jì)數(shù)初值 0xff,0xff,//占0位 0xf8,0x8c,//低1(0x01) a-數(shù)碼管顯示方式 0xf9,0x5b,//2 b 0xfa,0x15,//3 c 0xfa,0x67,//4 d 0xfb,0x04,//5 e 0xfb,0x90,//6 f 0xfc,0x0c,//低7(0x07)g 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,/*占位0x08-0x0b(8-11)*/ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,/*占位0x0c-0x10 (12-16)*/ 0xfc,0x44,//中1(0x11)(17) 0xfc,0xac,//2 0xfd,0x09,//3 0xfd,0x34,//4 0xfd,0x82,//5 0xfd,0xc8,//6 0xfe,0x06,//中7(0x17)(23) 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,/*占位0x18-0x1b(24-27)*/ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,/*占位0x1c-0x20 (28-32)*/ 0xfe,0x22,//高1(0x21)1. (33) 0xfe,0x56,// 2 2. 0xfe,0x85,// 3 3. 0xfe,0x9a,// 4 4. 0xfe,0xc1,// 5 5. 0xfe,0xe4,// 6 6. 0xff,0x03//高7(0x27)7. (39) }; ucharcodeymt[]={//玉滿堂0x96,0x00,//曲速0x96表示150拍/分0x00,0x0a,0x05,0x02,0x15,0x02,0x12,0x02,0x13,0x04,0x13,0x02,0x15,0x02,0x12,0x04,0x12,0x02,0x13,0x02,0x12,0x10,0x13,0x04,0x13,0x02,0x12,0x02,0x13,0x04,0x15,0x02,0x16,0x02,0x15,0x0c,0x13,0x02,0x15,0x02,0x16,0x04,0x16,0x02,0x21,0x02,0x16,0x04,0x15,0x02,0x13,0x02,0x15,0x0c,0x15,0x02,0x16,0x02,0x21,0x04,0x21,0x02,0x22,0x02,0x23,0x04,0x22,0x02,0x21,0x02,0x22,0x10,0x23,0x08,0x15,0x02,0x16,0x02,0x21,0x02,0x22,0x02,0x23,0x04,0x23,0x02,0x22,0x02,0x21,0x06,0x21,0x02,0x16,0x04,0x16,0x02,0x21,0x02,0x16,0x04,0x13,0x04,0x15,0x10,0x16,0x04,0x16,0x02,0x21,0x02,0x16,0x04,0x21,0x02,0x22,0x02,0x23,0x04,0x23,0x02,0x22,0x02,0x21,0x06,0x21,0x02,0x16,0x02,0x21,0x02,0x16,0x02,0x21,0x02,0x22,0x02,0x23,0x02,0x25,0x02,0x23,0x02,0x22,0x0c,0x21,0x02,0x22,0x02,0x23,0x06,0x15,0x02,0x16,0x02,0x21,0x02,0x22,0x02,0x23,0x04,0x23,0x02,0x22,0x02,0x21,0x06,0x21,0x02,0x16,0x04,0x16,0x02,0x21,0x02,0x16,0x02,0x21,0x02,0x15,0x02,0x13,0x02,0x15,0x0c,0x13,0x02,0x15,0x02,0x16,0x04,0x16,0x02,0x21,0x02,0x16,0x04,0x16,0x02,0x21,0x02,0x22,0x04,0x22,0x02,0x23,0x02,0x22,0x04,0x22,0x02,0x23,0x02,0x25,0x02,0x26,0x02,0x23,0x02,0x25,0x02,0x22,0x02,0x23,0x02,0x21,0x02,0x16,0x02,0x21,0x10,0xff};ucharcodedl[]={//蝶戀0x8c,0x00,//曲速0x8c表示140拍/分0x13,0x04,0x13,0x04,0x13,0x04,0x12,0x04,0x13,0x08,0x12,0x04,0x13,0x04,0x12,0x04,0x12,0x04,0x06,0x08,0x06,0x04,0x07,0x04,0x11,0x08,0x12,0x04,0x11,0x04,0x07,0x08,0x06,0x04,0x05,0x04,0x06,0x10,0x13,0x04,0x13,0x04,0x13,0x04,0x12,0x04,0x13,0x0c,0x16,0x04,0x15,0x04,0x16,0x04,0x15,0x04,0x15,0x04,0x12,0x04,0x12,0x04,0x13,0x04,0x14,0x08,0x15,0x04,0x14,0x04,0x13,0x04,0x12,0x04,0x11,0x04,0x13,0x0f,0x13,0x0c,0x13,0x04,0x16,0x08,0x17,0x04,0x16,0x04,0x15,0x0c,0x13,0x04,0x15,0x0f,0x13,0x04,0x15,0x04,0x12,0x08,0x16,0x04,0x15,0x04,0x13,0x08,0x12,0x04,0x12,0x04,0x13,0x0c,0x12,0x08,0x16,0x04,0x16,0x0c,0x11,0x08,0x16,0x04,0x16,0x08,0x16,0x04,0x17,0x04,0x21,0x08,0x17,0x04,0x16,0x04,0x17,0x08,0x16,0x04,0x17,0x04,0x13,0x08,0x13,0x0c,0x13,0x04,0x16,0x08,0x17,0x08,0x16,0x04,0x15,0x0c,0x13,0x04,0x15,0x10,0x14,0x04,0x15,0x04,0x16,0x08,0x17,0x04,0x16,0x04,0x17,0x08,0x16,0x04,0x17,0x04,0x13,0x10,0x13,0x10,0x12,0x08,0x16,0x04,0x16,0x02,0x16,0x10,0x11,0x04,0x16,0x04,0x16,0x02,0x16,0x08,0x16,0x04,0x17,0x04,0x21,0x08,0x17,0x04,0x16,0x04,0x17,0x08,0x15,0x08,0x16,0x10,0x23,0x04,0x22,0x04,0x22,0x04,0x21,0x04,0x21,0x04,0x17,0x04,0x17,0x04,0x16,0x04,0x21,0x04,0x17,0x04,0x17,0x04,0x16,0x04,0x16,0x04,0x15,0x04,0x15,0x04,0x14,0x04,0x16,0x04,0x15,0x04,0x15,0x04,0x14,0x04,0x14,0x04,0x13,0x04,0x13,0x04,0x12,0x04,0x13,0x10,0x13,0x10,0xff};ucharcodesrkl[]={//生日快樂0x78,0x00,//曲速1200x15,0x02,0x15,0x02,0x16,0x04,0x15,0x04,0x21,0x04,0x17,0x04,0x00,0x04,0x15,0x02,0x15,0x02,0x16,0x04,0x15,0x04,0x22,0x04,0x21,0x08,0x15,0x02,0x15,0x02,0x25,0x04,0x23,0x04,0x21,0x04,0x17,0x04,0x16,0x08,0x16,0x04,0x00,0x04,0x24,0x02,0x24,0x02,0x23,0x04,0x21,0x04,0x22,0x04,0x21,0x08,0x21,0x08,0x00,0x08,0x15,0x02,0x15,0x02,//第二遍0x16,0x04,0x15,0x04,0x21,0x04,0x17,0x04,0x00,0x04,0x15,0x02,0x15,0x02,0x16,0x04,0x15,0x04,0x22,0x04,0x21,0x08,0x15,0x02,0x15,0x02,0x25,0x04,0x23,0x04,0x21,0x04,0x17,0x04,0x16,0x08,0x16,0x04,0x00,0x04,0x24,0x02,0x24,0x02,0x23,0x04,0x21,0x04,0x22,0x04,0x21,0x08,0x21,0x08,0x00,0x04,0xff};ucharcodetest[]={//測(cè)試0x78,0x00,//曲速0x78表示120拍/分 0x01,0x04,0x02,0x04,0x03,0x04,0x04,0x04,0x05,0x04,0x06,0x04,0x07,0x04,0x00,0x04,0x11,0x08,0x12,0x07,0x13,0x06,0x14,0x05,0x15,0x04,0x16,0x03,0x17,0x02,0x00,0x01,0x21,0x01,0x22,0x02,0x23,0x03,0x24,0x04,0x25,0x05,0x26,0x06,0x27,0x07,0x00,0x08,0xff,};voiddelayms(uintms) /*ms等于1時(shí),延時(shí)1ms等于2時(shí),延時(shí)2ms,以此類推*/{ uchara,b,c; //+3 while(ms--){ for(c=1;c>0;c--) // 1+2=3for(b=142;b>0;b--) // 1*(1+142*2))=285 for(a=2;a>0;a--); // 142*(1+2*2)=710 }}voiddelay(uintpai) /*pai是節(jié)拍pai若定義成uchar類型,當(dāng)節(jié)拍>0x0c時(shí),會(huì)造成數(shù)據(jù)溢出,產(chǎn)生失真。*/{ uchara,b,c; while(pai--) //延遲pai個(gè)6.25ms { for(c=1;c>0;c--) // 1+2=3 for(b=28;b>0;b--) // 1*(1+28*2)=57 for(a=110;a>0;a--); // 28*(1+110*2)=6188 } }ucharkey_x()/*P1口高位接縱坐標(biāo)(P1.7-P1.4)低位接橫坐標(biāo)(P1.3-P1.0)*/{ uchari; P1=0x0f; /*有按鍵按下后對(duì)應(yīng)按鍵的橫坐標(biāo)電位被拉低(注意低電位引腳不能被高電位引腳抬高,只能是低電位拉低高電位)*/ if(P1_0==0) { delayms(5);//延時(shí)5ms去抖動(dòng) if(P1_0==0) i=1; } elseif(P1_1==0) { delayms(5); if(P1_1==0) i=2; } elseif(P1_2==0) { delayms(5); if(P1_2==0) i=3; } elseif(P1_3==0) { delayms(5); if(P1_3==0) i=4; } else i=0; return(i); //0表示按鍵未按下}ucharkey_y(){ ucharj; P1=0xf0; if(P1_4==0) { delayms(5); if(P1_4==0) j=1; } elseif(P1_5==0) { delayms(5); if(P1_5==0) j=2; } elseif(P1_6==0) { delayms(5); if(P1_6==0) j=3; } elseif(P1_7==0) { delayms(5); if(P1_7==0) j=4; } else j=0; return(j);}voidkey_check()/*檢查矩陣按鍵坐標(biāo)、播放鍵的狀態(tài)及播放鍵狀態(tài)設(shè)置*/{ x=key_x(); y=key_y(); if(key_play==0) key_play=0;/*保持播放鍵引腳低電平,讓其作為歌曲正在播放的標(biāo)志*/ else key_play=1;/*保持播放鍵引腳高電平,讓其作為歌曲未播放的標(biāo)志*/ }voiddisplay() /*數(shù)碼管顯示相應(yīng)的音調(diào)*/{ if(key_play==1)//按鍵彈奏時(shí) { if(x!=0&&y!=0) { if(x==1) P0=num[3+y]; //低音4-7 elseif(x==2) P0=num[7+y]; //中音1-4 elseif(x==3) P0=num[11+y]; //中音5-7和高音1 elseif(x==4) P0=num[15+y]; //高音2-5 } else P0=0x00; } else//播放音樂時(shí) { if(yindiao_h==0) /*yindiao變量的高四位表示低(0)中(1)高(2)音 */ P0=num[yindiao_l];/*yindiao變量的低四位表示“調(diào)”,數(shù)碼管顯示當(dāng)前音調(diào)*/ elseif(yindiao_h==1) // 中音 P0=num[yindiao_l+7]; elseif(yindiao_h==2)//高音 P0=num[yindiao_l+14]; }}voidspeak() /*按鍵,為定時(shí)器0T0賦計(jì)數(shù)初值,讓T0函數(shù)驅(qū)動(dòng)蜂鳴器發(fā)出對(duì)應(yīng)的音調(diào)*/{ if(x==1) { f_h=chuzhi[2*y+6]; //低音4-7 f_l=chuzhi[2*y+6+1]; } elseif(x==2) { f_h=chuzhi[(16+y)*2]; //中音1-4 f_l=chuzhi[(16+y)*2+1]; } elseif(x==3) { if(y<=3) { f_h=chuzhi[(20+y)*2]; //中音5-7 f_l=chuzhi[(20+y)*2+1]; } else { f_h=chuzhi[66]; //高音1 f_l=chuzhi[67]; } } elseif(x==4) { f_h=chuzhi[(33+y)*2]; //高音2-5 f_l=chuzhi[(33+y)*2+1]; } }voidtimer0()interrupt1//定時(shí)器0{ if(key_play==0) { TL0=song_l; TH0=song_h; beep=~beep; } else if(x!=0&&y!=0&&key_play==1)/*當(dāng)有矩陣按鍵按下,并且不播放歌曲時(shí)*/ { TL0=f_l; //賦初值 TH0=f_h; // beep=~beep;/*蜂鳴器引腳電平取反,定時(shí)器每溢出一次電平取反一次,不同的計(jì)數(shù)初值對(duì)應(yīng)不同的溢出時(shí)間,對(duì)應(yīng)不同的方波頻率*/ } }voidtimer1()interrupt3//定時(shí)器1 led燈起落{ TL1=0x00; TH1=0x54;/*定時(shí)器1高8位初值。控制led燈的起落快慢(數(shù)值不嚴(yán)格)*/ if(key_play==1)//不播放歌曲時(shí) { if(x!=0&&y!=0&&flash<8) //最大加到8 ++flash; elseif(x==0&&y==0&&flash>0)//最小減到0 --flash; P2=led_table[flash]; } elseif(key_play==0) //播放歌曲時(shí) { if(out==1&&flash<8&&flash<jiepai) /*out==1表示有歌曲發(fā)聲時(shí),(flash<jiepai)使led燈剛好指示節(jié)拍*/ ++flash; elseif(out==0&&flash>0) --flash; P2=led_table[flash]; } }ucharchoose() //播放狀態(tài)下選歌{ uchari=0;//第i首歌初值0表示未選歌 ucharj; x=key_x(); y=key_y(); if(x==1&&y==1) i=1; //選第一首 elseif(x==1&&y==2) i=2; //選第二首 elseif(x==1&&y==3) i=3; elseif(x==1&&y==4) i=4; elseif(x==2&&y==1) i=5; elseif(x==4&&y==1)//上一首 i=13; elseif(x==4&&y==2)//用作暫停播放 i=14; elseif(x==4&&y==3) //下一首 i=15; elseif(x==4&&y==4) i=16; //用作停止播放 if(i==song_id) { which=2;//選同一首歌時(shí),重播這首歌 } elseif(i>allsong&&i<13) /*如果按鍵號(hào)在最大歌曲序號(hào)和功能鍵之間,返回原歌曲序號(hào)*/ i=song_id; // elseif(i==0) //i等于初值說明未按鍵 i=song_id; //不按鍵選歌時(shí),返回原歌曲的序號(hào) while(1) //釋放按鍵時(shí)才進(jìn)行下一步 { x=key_x(); y=key_y(); if(x==1) j=y; elseif(x==2) j=4+y; elseif(x==3) j=8+y; elseif(x==4) j=12+y; if(x==0||(j>allsong&&j<13))/*釋放按鍵或者按鍵號(hào)在最大歌曲序號(hào)和功能鍵之間時(shí)跳出循環(huán)*/ break; } return(i);}ucharchoose2() /*選歌 不用放開按鍵在暫停的狀態(tài)下使用*/{ uchari=0; x=key_x(); y=key_y(); if(x==1&&y==1) //選第一首 i=1; elseif(x==1&&y==2) //選第二首 i=2; elseif(x==1&&y==3) i=3; elseif(x==1&&y==4) i=4; elseif(x==2&&y==1) i=5; elseif(x==4&&y==1) //上一首 i=13; elseif(x==4&&y==2) //用作暫停播放 i=14; elseif(x==4&&y==3) //下一首 i=15; elseif(x==4&&y==4) i=16; //用作停止播放 if(i==song_id) { same=1; which=2;/*選了同一首歌時(shí),重播這首歌 (0,1用來存曲速了故從2開始)*/ } elseif(i>allsong&&i<13) /*如果按鍵號(hào)在最大歌曲序號(hào)和功能鍵之間,返回原歌曲序號(hào)*/ i=song_id; elseif(i==0) //i等于初值說明未按鍵 i=song_id;/*不按鍵選歌時(shí),返回原歌曲的序號(hào)*/ return(i);}voidplay() //播放歌曲{ uintqusu;//歌曲播放速度(拍/分) uintpai2;/* pai2=(2400/qusu)*jiepai;送到delay()函數(shù)*/while(1){ while(1) { choose_id: temp_id=choose();//選歌/****************************↓↓↓↓↓暫?!?****************************************/ if(temp_id==14) //如果按下暫停鍵 { delayms(500); //延時(shí)500ms while(1) { temp_id=choose2();/*choose2按下就起作用不必等到放開按鍵才起作用*/ if(temp_id==14)/*再次按下“暫停鍵”表示繼續(xù)播放*/ { break; } elseif(temp_id==16)/*按下停止鍵,功能表現(xiàn)為:暫停播放時(shí)也能停止播放,回到播放前狀態(tài)*/ { song_id=16; break; } elseif(temp_id==13) //上一首 { which=2; if(song_id==1) song_id=allsong;//播放最后一首 else --song_id; break; } elseif(temp_id==15)//下一首 { which=2; if(song_id==allsong) song_id=1;//播放第一首 else ++song_id; break; } elseif(temp_id!=song_id&&temp_id<=allsong)/*選了另一首歌曲屏蔽掉了未定義的按鍵 */ { which=2; /*從歌曲的第一個(gè)音播放(0,1用來存曲速了故從2開始) */ song_id=temp_id; break; } elseif(same==1) break; } same=0;//跳出循環(huán)后需重置為0 } /****************************↑↑↑↑↑暫?!?**************************************/ elseif(temp_id==13) //上一首 { which=2; if(song_id==1) song_id=allsong;//播放最后一首 else --song_id; } elseif(temp_id==15)//下一首 { which=2; if(song_id==allsong) song_id=1;//播放第一首 else ++song_id; } elseif(temp_id==16) { song_id=16; } elseif(temp_id!=song_id&&temp_id<=allsong)//選了另一首歌曲 { which=2; //從歌曲的第一個(gè)音播放 song_id=temp_id; } /**************************************************************************************/ nochoose: //不用選歌當(dāng)正常放完一首歌時(shí),跳到這里 if(song_id==3) { key_play=0; if(srkl[which]==0xff)/*遇到結(jié)束符跳出循環(huán)(內(nèi)循環(huán))停止播放*/ break; qusu=srkl[0]; yindiao=srkl[which];//音調(diào) jiepai=srkl[which+1];//節(jié)拍 } else if(song_id==1) { key_play=0; if(ymt[which]==0xff)/*遇到結(jié)束符跳出循環(huán)(內(nèi)循環(huán))停止播放*/ break; qusu=ymt[0]; yindiao=ymt[which];//音調(diào) jiepai=ymt[which+1];//節(jié)拍 } else if(song_id==2) { key_play=0; if(dl[which]==0xff)/*遇到結(jié)束符跳出循環(huán)停止播放*/ break; qusu=dl[0]; yindiao=dl[which];// jiepai=dl[which+1];// } elseif(song_id==4) { key_play=0; if(test[which]==0xff)/*遇到結(jié)束符跳出循環(huán)停止播放*/ break; qusu=test[0]; yindiao=test[which]; jiepai=test[which+1]; }/******************************************************************************/ elseif(song_id==16) { which=2; break; } else { key_play=1; gotochoose_id; /*如果既沒有選歌又沒有停止返回去做選擇*/ }/********************************************************************************************/ yindiao_l=yindiao%16; //低四位調(diào) yindiao_h=yindiao/16; /* 高四位。。是低音0中音1還是高音2 */ if(yindiao!=0)/*音調(diào)不為0。(當(dāng)音調(diào)為0時(shí)表示這個(gè)音不響但依舊要占這個(gè)音的播放時(shí)間)*/ { song_h=chuzhi[yindiao*2]; song_l=chuzhi[yindiao*2+1]; TR0=1;/*給初值賦值后,開啟定時(shí)器0 蜂鳴器開始發(fā)聲*/ TR1=1; /*開啟定時(shí)器1,led開始閃動(dòng)*/ display();//數(shù)碼管顯示音調(diào) out=1;/*正在發(fā)聲的標(biāo)志,定時(shí)器1得以控制led燈按一定的時(shí)間間隔逐個(gè)點(diǎn)亮*/ } else { TR0=0; out=0; TR1=0; P0=0x00; flash=0; P2=led_table[0]; } pai2=(2400/qusu)*jiepai; delay(pai2); /*延時(shí)=節(jié)拍數(shù)x125ms(決定著1個(gè)音的發(fā)聲時(shí)間)*/ TR0=0; //蜂鳴器停止發(fā)聲 P0=0x00; out=0; delayms(39);/*唱完一個(gè)音停xxms(決定每個(gè)音調(diào)之間的時(shí)間間隔根據(jù)個(gè)人喜好節(jié)奏來定*/ TR1=0;//led停止閃動(dòng) flash=0; P2=led_table[0]; which=which+2; //下一個(gè)音 }/*已經(jīng)放完一首歌,或者停止播放 ,接下來判斷是停止播放還是播放下一首*/ TR0=0; P0=0x00; out=0; flash=0; P2=led_table[0]; if(song_id==16)/*坐標(biāo)(4,4)的鍵盤作為停止播放鍵*/ { while(1) { x=key_x(); if(x==0) break;/*松開按鍵才結(jié)束避免觸發(fā)其他程序比如電子琴發(fā)聲、led顯示等 */ } key_play=1;/*播放鍵引腳置高電平,播放結(jié)束的標(biāo)志 */ song_id=1;//第一首歌開始 which=2; //每首歌的最開始的一個(gè)音 break;/*跳出第二個(gè)循環(huán)(即結(jié)束play函數(shù))*/ } elseif(song_id==allsong)/*當(dāng)放到最后一首時(shí),從第一首開始(當(dāng)前共3首)*/ { song_id=1; which=2; delayms(1000);//一秒后從第一首開始播放 gotonochoose; } else { ++song_id;/*歌曲序號(hào)自動(dòng)+1自動(dòng)播放下一首歌*/ which=2; delayms(1000); gotonochoose;//不用選歌播放下一首 }}}voidmain(){ P0=0x00; P2=0xff; TMOD=0x11;/*定時(shí)器0定時(shí)器1都采用方式1(16位定時(shí)器方式)*/ IE=0x8a; PT0=1;/*設(shè)置定時(shí)器0為高優(yōu)先級(jí),避免被定時(shí)器1干擾,造成聲音失真 */while(1){ key_check(); if(key_play==1&&x!=0&&y!=0) { TR1=1; display(); speak(); TR0=1; } elseif(key_play==0) { key_play=0; play(); /*play函數(shù)有循環(huán)語句,當(dāng)按下停止鍵(16鍵)時(shí)才能跳出*/ } else { if(flash==0)/*當(dāng)flash減到0時(shí)再關(guān)閉定時(shí)器1,即讓led燈全部熄滅再關(guān)閉T1*/ TR1=0; TR0=0; P0=0x00; } } }【實(shí)物圖】:【原理圖、PCB、程序下載地址】:/s/19oaXJ (百度網(wǎng)盤)【版權(quán)聲明】:共享文檔、可自由轉(zhuǎn)載,但僅限于學(xué)習(xí)交流!最后建議同學(xué)們,課設(shè)最好認(rèn)真做,不可完全照搬他人。基于C8051F單片機(jī)直流電動(dòng)機(jī)反饋控制系統(tǒng)的設(shè)計(jì)與研究基于單片機(jī)的嵌入式Web服務(wù)器的研究MOTOROLA單片機(jī)MC68HC(8)05PV8/A內(nèi)嵌EEPROM的工藝和制程方法及對(duì)良率的影響研究基于模糊控制的電阻釬焊單片機(jī)溫度控制系統(tǒng)的研制基于MCS-51系列單片機(jī)的通用控制模塊的研究基于單片機(jī)實(shí)現(xiàn)的供暖系統(tǒng)最佳啟停自校正(STR)調(diào)節(jié)器單片機(jī)控制的二級(jí)倒立擺系統(tǒng)的研究基于增強(qiáng)型51系列單片機(jī)的TCP/IP協(xié)議棧的實(shí)現(xiàn)基于單片機(jī)的蓄電池自動(dòng)監(jiān)測(cè)系統(tǒng)基于32位嵌入式單片機(jī)系統(tǒng)的圖像采集與處理技術(shù)的研究基于單片機(jī)的作物營(yíng)養(yǎng)診斷專家系統(tǒng)的研究基于單片機(jī)的交流伺服電機(jī)運(yùn)動(dòng)控制系統(tǒng)研究與開發(fā)基于單片機(jī)的泵管內(nèi)壁硬度測(cè)試儀的研制基于單片機(jī)的自動(dòng)找平控制系統(tǒng)研究基于C8051F040單片機(jī)的嵌入式系統(tǒng)開發(fā)基于單片機(jī)的液壓動(dòng)力系統(tǒng)狀態(tài)監(jiān)測(cè)儀開發(fā)模糊Smith智能控制方法的研究及其單片機(jī)實(shí)現(xiàn)一種基于單片機(jī)的軸快流CO〈,2〉激光器的手持控制面板的研制基于雙單片機(jī)沖床數(shù)控系統(tǒng)的研究基于CYGNAL單片機(jī)的在線間歇式濁度儀的研制HYPERLINK"/detail.ht

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論