<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > MIDI信號的解碼及實時音符顯示

          MIDI信號的解碼及實時音符顯示

          作者: 時間:2007-03-09 來源:網(wǎng)絡(luò) 收藏
          摘要:介紹了MIDI數(shù)據(jù)的格式,討論了一種使用AT89C51系列完成MIDI信號的實時解碼,從中提高音符數(shù)據(jù),并隨時利用專用LED驅(qū)動芯片將音符顯示出來的設(shè)計方案。該方案經(jīng)實際產(chǎn)品應(yīng)用,證明合理可靠。關(guān)鍵詞:MIDI 串行接口 LED顯示 MIDI是音樂設(shè)備數(shù)字接口的簡答,是各種電子音樂設(shè)備之間數(shù)據(jù)傳輸?shù)臉?biāo)準(zhǔn)接口,廣泛應(yīng)用于各種電子樂器上,目前較高檔的電子琴子均帶有MIDI接口。筆者在開發(fā)用于音樂教學(xué)的產(chǎn)品“音樂電教板”的過程中,遇到了有關(guān)MIDI信號解碼的問題,產(chǎn)品要求能夠接受電子琴傳送來的MIDI信號,并將相應(yīng)的音符顯示出來。經(jīng)過對MIDI協(xié)議的研究,用AT89C51和128段LED顯示控制芯片BC7281構(gòu)成的系統(tǒng)完成了設(shè)計要求。 1 MIDI信號簡介及與的接口 MIDI信號的傳輸采用異步串行方式,其速率為31.5kbps,數(shù)據(jù)格式為8個數(shù)據(jù)位、1個起始位和1個停止位。因此,完全可以采用MCS內(nèi)部的硬件UART串口完成MIDI信號的接收和發(fā)送(本設(shè)計中只用到其接收部分),在硬件方面只需采取適當(dāng)?shù)碾娐愤M(jìn)行電平轉(zhuǎn)換即可。 MIDI接口采用標(biāo)準(zhǔn)的5芯DIN連接器,如圖1。傳送電纜使用屏蔽層的雙絞線電纜,因為信號的傳輸利用的是電流信號而不是電壓信號,所以其抗干擾能力比較強(qiáng),盡管其速率高達(dá)31.5kbps,傳輸距離仍可以達(dá)到15m,比常見的RS-232接口的傳送距離要遠(yuǎn)。一般的MIDI接收電路如圖2,本文采用與之相同的電路。 其中RX接單片機(jī)的串口RX端,電路中的光耦既起到隔離的作用,又有電平轉(zhuǎn)換的作用,因為速率較高,必須選用開關(guān)速度較高的型號,這里使用的是6N136。D1是保護(hù)二極管。 MIDI中共有16個通道(channel),一般稱之為通道1至通道16,每個通道相當(dāng)于樂曲中的個聲部,使用者可以為每個通道指定一種音色。音色可以是MIDI規(guī)范中規(guī)定的128種音色中的任何一種,每一個通道只能有一種音色。也就是說,在一個標(biāo)準(zhǔn)的MIDI系統(tǒng)中,最多相當(dāng)于可以有16種樂器同時演奏。 按照MIDI協(xié)議的規(guī)定,傳送的數(shù)據(jù)可以分為兩類:狀態(tài)字節(jié)和數(shù)據(jù)字節(jié)。所謂狀態(tài)字節(jié)實際就是命令字,表明其后所跟數(shù)據(jù)的種類,狀態(tài)字節(jié)總是大于等于80H,而數(shù)據(jù)字節(jié)總是小于80H,因此,可以很容易地區(qū)分狀態(tài)字節(jié)和數(shù)據(jù)字節(jié)。在狀態(tài)字節(jié)中,用數(shù)據(jù)的低4位表示通道號,高4位表示不同的命令。比如,設(shè)定音色為ChH指令,其中n是通道號。 在各種MIDI的指令中,與本機(jī)有關(guān)的只有兩種:8nH和9nH(n為通道號),兩種指令的基本格式一樣,一般由3個字節(jié)組成,格式是: 8n(9n) aa bb 其中,aa是音符數(shù)據(jù),表明所演奏的音符,其范圍為0~7fH,這樣共有128個音符,足以覆蓋整個音域;bb是速度數(shù)據(jù),表明擊鍵的速度,又稱力度數(shù)據(jù),其范圍也是0~7fH。第一個字節(jié)是狀態(tài)字節(jié)(指令),其具體含義說明如下: 8nH——“音符關(guān)”指令,在多數(shù)MIDM設(shè)備中,該指令中的速度數(shù)據(jù)bb被忽略。 9nH——“音符開”指令,如果速度數(shù)據(jù)等于0,則等同于8nH指令。在本機(jī)中,因為只需要顯示音符的開關(guān),而不必考慮其聲音的大小,故速度數(shù)據(jù)被忽略(速度數(shù)據(jù)不等于0時)。 MIDI中有一個特殊的通道即通道10,通道10是節(jié)奏樂器的專用通道,與其它通道不同,其它通道中不同的音符表示不同的音高,而在通道1中,不同音符表示不同的節(jié)奏樂器,因為節(jié)奏樂器是沒有音高的,一般如各種鼓等,在本機(jī)中,所要顯示的是各種旋律的音符,因此,通道10的數(shù)據(jù)要過濾掉。 2 顯示電路 音符的顯示,通過一個鋼琴鍵盤的面板,在鍵盤的每個鍵上,都有一個LED指示燈,用LED的亮和滅代表音符的開和關(guān)。一個完整的鋼琴鍵盤,83個鍵,再加上系統(tǒng)中用于指示工作狀態(tài)的指示燈等,本機(jī)需要顯示LED達(dá)100多個。因此,選用了16位數(shù)碼管(128位LED)及64鍵鍵盤接口芯片BC7281,該芯片可以驅(qū)動128個獨(dú)立的LED,同時還可以提供鍵盤管理,筆者設(shè)計的系統(tǒng)中16個按鍵,完全可以滿足要求。而其本身僅為18腳DIP封裝,體積小巧。該芯片與之間采用串行通信,只需要3根引線,為簡單起見,這里只給出本系統(tǒng)中鍵盤、顯示部分的電路框圖如圖3。 BC7281中有16位顯示寄存器,其每一數(shù)據(jù)位都對應(yīng)著顯示矩陣中的一個LED,每個數(shù)據(jù)位都有一個位地址,用以做尋址,樣每一個LED的開關(guān)都可以單獨(dú)控制,其地址范圍是07FH。將地址0~52H的LED作為音符顯示用,69H~7FH的地址作為系統(tǒng)狀態(tài)指示用,共余LED顯示不用。 3 程序設(shè)計 因為MIDI數(shù)據(jù)的傳送速率較高,因此,決定采用中斷的方式來處理MIDI數(shù)據(jù)。對于顯示部分,則在數(shù)據(jù)區(qū)中設(shè)立一個特定的緩沖區(qū),處理MIDI數(shù)據(jù)的中斷程序只負(fù)責(zé)對緩沖區(qū)內(nèi)的數(shù)據(jù)進(jìn)行更新,而不直接完成對顯示芯片的操作,這樣可以提高中斷處理速度。顯示的刷新,則放在程序的主循環(huán)中來完成。 用于處理MIDI數(shù)據(jù)的串口中斷程序,必須完成以下工作: (1)根據(jù)狀態(tài)字節(jié),過濾掉不必要的數(shù)據(jù); (2)根據(jù)保留下的“音符開”和“音符關(guān)”數(shù)據(jù),更新顯示數(shù)據(jù)緩沖區(qū)。因為設(shè)計要求所有旋律通道的音符都要顯示出來,也就是說,除第10通道外,每個通道的音符都要顯示出來。這樣就存在著音符重疊的問題,比如第一通道中的C音和第二通道中的C音同時演奏,這時如果單片機(jī)收到一個“音符關(guān)”指令,則必須判斷其它通道中有沒有相同的音符處在“開”的狀態(tài),如果有,則相應(yīng)的音符指示燈就不能關(guān)閉。為了到達(dá)這個目的,將音符顯示的緩沖區(qū)設(shè)置為一個128單元的數(shù)組,數(shù)組單元和MIDI的128個音符一一對應(yīng)(雖然只需要顯示其中的8個音符),但是為了簡化程序及日后升級的方便,仍將數(shù)組設(shè)為128單元,只在主程序中顯示刷新的部分才將多余的數(shù)據(jù)忽略),每當(dāng)收到一個“音符開”指令時,相應(yīng)的數(shù)組單元就加一,而收到“音符關(guān)”指令時,則減一,在顯示時,只要數(shù)組單元不等于零,對應(yīng)的音符指示LED就點亮,而只有在數(shù)組單元等于零時,才將已經(jīng)點亮的LED關(guān)閉,“音符關(guān)”指令不直接控制LED,這樣就很好地解決了省符重疊的問題。 AT89C51串口中斷處理程序流程圖如圖4。 目前該產(chǎn)品已經(jīng)批量生產(chǎn),并已成功進(jìn)入市場銷售一年有余,實踐證明該設(shè)計方案是合理和可靠的。

          評論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();