陳 新,張麗華
(合肥工業(yè)大學(xué) 計(jì)算機(jī)與信息學(xué)院,安徽 合肥 230009)
科技館的激光豎琴,是一種利用激光信號(hào)有無(遮擋和無遮擋)作為輸入信號(hào),控制音樂芯片發(fā)出各種音符,來模擬豎琴的設(shè)備。
激光豎琴可以通過MP3模塊播放豎琴音階進(jìn)行設(shè)計(jì),但這種方式反應(yīng)緩慢,很難奏出快速音符。激光豎琴還可以采用繼電器控制音樂芯片進(jìn)行設(shè)計(jì),而這種方式的缺點(diǎn)是繼電器的噪音很大。本文應(yīng)用單片機(jī)直接控制電子琴音樂芯片進(jìn)行發(fā)音,快速有效,既可以彈奏電子豎琴,也可以自動(dòng)演奏電子豎琴音樂,如圖1所示。圖中激光傳感器采用了M658D200激光器作為光發(fā)射器,IS486/485作為光接收器??刂破饔?2位單片機(jī)LM3S615,音樂芯片用YM-6100,功放采用KA2206芯片配兩只3W/8Ω揚(yáng)聲器。其中IS486/485和KA2206芯片的外圍電路采用相關(guān)的數(shù)據(jù)手冊(cè)電路即可。
圖1 激光豎琴電路方框圖
YM-6100音樂芯片采用8行8列掃描按鍵方式發(fā)出64個(gè)音,這64個(gè)音符對(duì)應(yīng)電子琴鍵盤按鍵的排列如圖2所示。每個(gè)音階黑、白鍵共12個(gè),5組音階另加4個(gè)音符,共64個(gè)按鍵。每個(gè)按鍵排列值在圖的最下面一行。
圖2 64鍵音樂芯片YM-6100的鍵盤編碼
本設(shè)計(jì)的難點(diǎn)是:音樂芯片YM-6100內(nèi)部也含有MCU,它的輸入是8×8的行列按鍵矩陣,每行依次輸出掃描信號(hào),讀取對(duì)應(yīng)每行的8個(gè)列按鍵信號(hào)[1],如圖3所示。應(yīng)注意,不能用TTL電平直接輸給YM-6100的行列按鍵矩陣,YM-6100只能接收干觸點(diǎn)信號(hào)[2]。這就牽涉到如何用單片機(jī)去完成一個(gè)行列按鍵矩陣的功能。我們把音樂芯片YM-6100的行掃描脈沖 AB0~AB7作為單片機(jī)LM3S615的中斷輸入,當(dāng) YM-6100掃描某行時(shí),LM3S615發(fā)生中斷并在中斷服務(wù)程序中讀取激光傳感器信號(hào)[3],譯碼后由PD口輸出給YM-6100,控制其發(fā)什么音和不發(fā)音,如圖4所示。(注:不發(fā)音時(shí)輸給YM-6100的信號(hào)為0。)
圖3 音樂片YM-6100的行列按鍵矩陣
圖4 音樂芯片YM-6100和LM3S615連接
激光傳感器信號(hào)也可以用硬件直接譯碼,如圖5所示,用8片74HC373把 64個(gè)激光傳感器TTL電平信號(hào)Y1~Y64譯碼為YM-6100的行列按鍵矩陣。其中AB0~AB7是YM-6100的第0~7行對(duì)應(yīng)掃描脈沖,Y1輸入對(duì)應(yīng)第0行第0列按鍵輸入D0,Y2對(duì)應(yīng)第0行第1列按鍵輸入D1,……Y8對(duì)應(yīng)第0行第7列按鍵輸入D7。當(dāng)AutoPlay=1且掃描脈沖為AB0=1時(shí),Y1~Y7被允許輸出給YM-6100的D0~D7按鍵輸入端,可以發(fā)出最低音階12個(gè)音符的前8個(gè)音符。其它74HC373輸入和發(fā)音原理類似。而來自單片機(jī)的信號(hào)AutoPlay是用來控制自動(dòng)播放音樂還是手工彈奏,當(dāng)AutoPlay=0時(shí),D0~D7輸出為高阻態(tài),這時(shí)掃描脈沖 AB0~AB7使LM3S615中斷,在中斷服務(wù)程序中LM3S615只需按照預(yù)存的簡(jiǎn)譜音符,譯碼并通過PD口直接輸出按鍵信號(hào),進(jìn)行單片機(jī)自動(dòng)播放音樂。
圖5 64個(gè)TTL電平輸入譯碼為行列按鍵矩陣
我們可以通過編程讓LM3S615自動(dòng)播放音樂。音樂用簡(jiǎn)譜存儲(chǔ),用0.25秒定時(shí)器做一個(gè)最小時(shí)隙,表示1/4拍。簡(jiǎn)譜編碼用十進(jìn)制整型數(shù)(2字節(jié))表示。對(duì)一個(gè)音符用:“-”表示升半調(diào),“+”表示原調(diào);對(duì)音符整數(shù)取絕對(duì)值后,個(gè)位為1、2、3、4、5、6、7表示音符,個(gè)位為其它值譯為休止符;十位為0、1、2、3、4、5 分別表示該音符處在的音階:低 2 音階、低1音階、中音階、高1音階、高2音階、高3音階,十位為其它值譯為休止符;百千萬位組合表示該音符時(shí)隙長(zhǎng)度(即1/4拍得整倍數(shù)),如圖6所示。為了譯碼方便百千萬位組合超過255,截取為255,即一個(gè)音符的時(shí)長(zhǎng)最大為256*1/4=64拍(秒);超過范圍的音符全部譯為休止符,常數(shù)30000表示歌曲結(jié)束。例如:整數(shù)1237表示(高1階)7,時(shí)長(zhǎng)為12;-10247表示(高2階)7#,時(shí)長(zhǎng)為102;整數(shù)2299、整數(shù)2219、整數(shù)2219都表示休止符,時(shí)長(zhǎng)為22等。
圖6 簡(jiǎn)譜音符編碼方式
如圖7所示為《東方紅》樂曲,其簡(jiǎn)譜可以編碼為:int JP[]={425,225,226,822,421,221,216,822,425,425,226,231,226,225,421,221,216,822,30000};其中30000表示歌曲簡(jiǎn)譜數(shù)組結(jié)束。為了方便,譯碼后保存為2個(gè)數(shù)組:音符的行列掃描值數(shù)組HL[]、時(shí)隙長(zhǎng)度數(shù)組Slots[]。行列掃描值為2字節(jié)無符號(hào)整型數(shù),高字節(jié)為行掃描值,低字節(jié)為列按鍵輸入值。時(shí)隙長(zhǎng)度為無符號(hào)字符型數(shù),是1/4拍的整倍數(shù)。
圖7 《東方紅》簡(jiǎn)譜
下面我們介紹譯碼函數(shù)的譯碼步驟。在函數(shù)decode()中:①先把單個(gè)簡(jiǎn)譜音符值Yinfu分解為原音和升半音、音符、音階、音符時(shí)長(zhǎng);②計(jì)算音符對(duì)應(yīng)的鍵盤按鍵排列值,公式為音符小于等于3時(shí),為音階*12+(音符-1)*2+升半調(diào)值;音符大于3時(shí),為音階*12+(音符-1)*2+升半調(diào)值-1;③將其譯為音符時(shí)長(zhǎng)和音符的行列掃描信號(hào)組合成的long型數(shù),作為返回值,時(shí)長(zhǎng)占D31~D16,行掃描占D15~D8,列掃描占D7~D0;④如果是休止符,則long型返回值為:時(shí)長(zhǎng)占 D31~D16,行列為0xFFFF。
接著在另一個(gè)函數(shù)decodeSZ()中,譯碼一首曲子的音符數(shù)組,先判斷JP[i]是否為30000,是則簡(jiǎn)譜譯碼結(jié)束,否則調(diào)用decode()函數(shù)進(jìn)行簡(jiǎn)譜譯碼。用這種方式還可以對(duì)多聲部的樂曲,多次這樣做,最后把各個(gè)聲部進(jìn)行組合,就可以構(gòu)成多聲部樂曲。LM3S615單片機(jī)在自動(dòng)播放音樂的時(shí),依次讀取各個(gè)音符的時(shí)長(zhǎng)和行列掃描值,把行列掃描值輸給YM-6100音樂片進(jìn)行播放,當(dāng)時(shí)長(zhǎng)遞減到零時(shí),再讀取下一音符同樣進(jìn)行播放。
在湖南科技館鋼琴噴泉項(xiàng)目設(shè)備中,我們使用了自動(dòng)播放功能,還可以同時(shí)準(zhǔn)確的控制噴泉和指示燈的開關(guān),效果很好。
本文介紹的激光豎琴設(shè)計(jì)方法,是筆者在設(shè)計(jì)中國科技流動(dòng)館激光豎琴和湖南省科技館的鋼琴噴泉展品的經(jīng)驗(yàn)總結(jié)。自動(dòng)播放音樂部分的編碼和譯碼等都有一定的獨(dú)創(chuàng)性,展品運(yùn)行穩(wěn)定效果良好。
[1] YM6100音樂芯片數(shù)據(jù)手冊(cè)[C].廣州:廣東省揭西縣永美電子琴廠
[2] LM3S615微控制器數(shù)據(jù)[C].廣州:廣州周立功單片機(jī)發(fā)展有限公司
[3] 丁志剛,李剛民.單片微型計(jì)算機(jī)原理和應(yīng)用[M].北京:電子工業(yè)出版社,1990.5