淺談?dòng)?51hei-5 學(xué)習(xí)單片機(jī)播放音樂(1)
春節(jié)無(wú)事做,試了一下使用 51hei-5 的單片機(jī)播放音樂. 非常遺憾的是:怎么弄也不能正常放出音樂來(lái)!-----把 51hei-5 的蜂鳴器焊下來(lái),一測(cè)量,哈哈!是一個(gè)有源蜂鳴器!----可能焊接元器件出錯(cuò)了! 找了一個(gè) 32Ω 的小耳機(jī)(不要使用8Ω低阻抗的).代替原來(lái)的蜂鳴器.就可以出來(lái)音樂了!(蜂鳴器具有尖銳的頻率響應(yīng)點(diǎn),不適合播放音樂!)
找了一些 51 單片機(jī)播放音樂的例子,網(wǎng)絡(luò)上非常多這種資源.發(fā)現(xiàn)這些例子對(duì)音樂程序的播放首先是對(duì)歌曲簡(jiǎn)譜進(jìn)行編碼.甚至還有人發(fā)布了可以編碼給單片機(jī)使用的軟件. 仔細(xì)分析了一下,主要有 2 種編碼方式: 第一種: 僅僅使用一個(gè)表格,使用 3 字節(jié)結(jié)構(gòu),前面 2 字節(jié)是單個(gè)音符的數(shù)據(jù),這個(gè)數(shù)據(jù)賦值給單片機(jī)的定時(shí)器后,讓定時(shí)器溢出時(shí),反轉(zhuǎn)輸出端口,產(chǎn)生一個(gè)固定頻率輸出.不同的數(shù)據(jù),就有不同的頻率,這樣,音樂的 1 2 3 4 5 就出來(lái)了.第 3 字節(jié)是該音符輸出的節(jié)拍時(shí)間. 例如: DB 0FDH, 5BH,04H DB 0FDH, 08H,02H DB 0FCH,0ABH,02H DB 0FCH, 0BH,02H DB 0FCH, 0BH,02H DB 0FFH,0FFH,01H DB 0FCH, 0BH,02H 第二種: 使用 2 個(gè)表格,它專門有一個(gè)音符表格,里面包含了從低音 1 2 3.... 到 高音 1 2 3 .... 的單個(gè)音符信息.每個(gè)音符使用 2 個(gè)字節(jié),同樣它是給單片機(jī)定時(shí)器賦值后,讓定時(shí)器溢出時(shí),反轉(zhuǎn)輸出端口,達(dá)到輸出對(duì)應(yīng)的頻率.
例如: Z_TABL1: ;決定音調(diào)的定時(shí)初值.----------什么歌都可以使用 ;-1 DB 0F8H,095H; _1 ====0 DB 0F9H,070H; _2 ====1 DB 0FAH,025H; _3 ====2 DB 0FAH,065H; _4 ====3 DB 0FBH,000H; _5 ====4 DB 0FBH,090H; _6 ====5 DB 0FCH,00CH; _7 ====6 ;≥10-4 DB 0FCH,044H; 1 ====7 DB 0FCH,0ACH; 2 ====8 DB 0FDH,009H; 3 ====9 DB 0FDH,034H; 4 ====10 DB 0FDH,082H; 5 ====11 DB 0FDH,0C8H; 6 ====12 DB 0FEH,006H; 7 ====13 ;≥20-7 DB 0FEH,022H; 1_ ====14 DB 0FEH,056H; 2_ ====15 DB 0FEH,085H; 3_ ====16 DB 0FEH,09AH; 4_ ====17 DB 0FEH,0C1H; 5_ ====18 DB 0FEH,0E1H; 6_ ====19 DB 0FEH,0FEH; 7_ ====20 ;≥30-10 DB 0FFH,00AH; 1= ====21 另外一個(gè)表格就是音樂的表格了,它使用 2 個(gè)字節(jié)來(lái)表示,高字節(jié)代表指向某個(gè)音符的數(shù)字,低字節(jié)代表節(jié)拍.
例如: Z_TABL1: ;高字節(jié)是音調(diào)索引,低字節(jié)是節(jié)拍長(zhǎng)度 ;我的祖國(guó)(前奏過門)----05=_5(低音),15=5(正常音),25=5_(高音) DB 13,08;6 DB 13,04;6 DB 15,04;6 DB 16,08;6 DB 16,04;6 DB 21,04;6 DB 22,08;6 DB 23,04;6 DB 21,04;6 DB 22,14 DB 21,2 DB 22,4 DB 13,4 DB 15,4;_5 DB 16,4;_6 DB 17,4;_6 DB 22,4 DB 16,4 DB 17,4 DB 15,16 ;過門完成 DB 00,4 比較一下,上面 2 種方法中,第 2 種方法是很好的.它把基本音符與具體音樂分開了!可以節(jié)省大量?jī)?chǔ)存空間.刪除歌曲不會(huì)影響基本音符在程序里的內(nèi)容.這些音符內(nèi)容僅僅被不同音樂的信息來(lái)調(diào)用,無(wú)論上面歌曲,都可以使用它們. 因此,我就使用第二種方法. 接下來(lái),要說(shuō)的是怎么來(lái)編寫和辨認(rèn)這些信息. 當(dāng)我們得到一份示例程序后,對(duì)音樂信息來(lái)說(shuō),很不直觀的.誰(shuí)也不能一下子看出這些數(shù)字是哪一個(gè)音符.與原始音樂樂譜完完全全變了樣! 如何讓程序里的數(shù)據(jù)與原始音樂對(duì)上號(hào)呢?------怎么讓人一下子看出來(lái)是什么呢? 方法是: 把音樂中的 1 2 3 ..... 與音符表格對(duì)應(yīng)起來(lái).就是當(dāng)你編寫程序時(shí),完完全全可以按照原始音樂的簡(jiǎn)譜照抄下來(lái). 例如:
你可以把 "五星紅旗迎風(fēng)飄揚(yáng)" 直接寫下" 5 5 1 5 3 1 5 6 5 "!----------是不是很直觀! 那么,這樣如何區(qū)別其的音高呢? 同樣一個(gè) 5 ,有低音,中音,高音 啊! 我們把低音寫作 5 ,把中音寫作 15 ,把高音寫作 25 就可以準(zhǔn)確分辨出來(lái). 那么,這些 5 又怎么去獲取對(duì)應(yīng)的音符值(定時(shí)器值)呢? 我們可以讓它與音符表格對(duì)應(yīng)起來(lái).例如上面的 1 2 3 ....低音部分. 表格是從 0 開始放置的,音符是從 1 開始的.那么,把低音的數(shù)字 -1 就可以查表獲得數(shù)據(jù)了! 而中音部分呢? 11 是中音的 1 ,音符表格則是在第 7 行, 11-7=4 ,就是說(shuō),凡是中音數(shù)據(jù),把它們 -4 之后,就對(duì)上表格了! 高音部分的 21 是高音的 1 ,音符表格排列在第 14 行, 21-14=7,就是說(shuō),凡是高音數(shù)據(jù),把它們 -7 之后,就對(duì)上表格了! 而判斷一個(gè)音符的高中低,則是由音符數(shù)據(jù)的高半字節(jié)是 0,1,2....來(lái)決定.非常方便! 經(jīng)過這種改造,編寫歌譜時(shí)就可以直接照原始歌譜抄了!---------樂曲表格數(shù)據(jù)的可讀性極好!分析查錯(cuò)也就非常方便了! 而節(jié)拍信息也是按照原始樂譜來(lái)抄寫.你可以把一個(gè)小節(jié)定義為 16 ,也可以定義為 8 或 32 ,定義數(shù)字越大,每小節(jié)容納音符的最小時(shí)間單位就越少!通常,使用 16 是很好用的! 例如:上面說(shuō)的 "五星紅旗迎風(fēng)飄揚(yáng)" ,對(duì)應(yīng)樂譜為 5 5 1 5 3 1 5 6 5 " ,按照該歌曲的節(jié)拍和上面說(shuō)的音高寫法,可以寫成: DB 5,4 DB 5,4 DB 11,8 DB 5 ,8 DB 13 ,8 DB 11 ,8 DB 15 ,16 DB 16 ,8 DB 15,8 當(dāng)我們垂直往下讀的時(shí)候,原始簡(jiǎn)譜的信息就直觀出來(lái)了!(要把讀 11 讀成中音 1 , 15 讀成中音 5 , 05 讀成低音5 ......) 下面給出一個(gè) 08 奧運(yùn)的"我和你" 的前面 2 句,可以直接根據(jù)數(shù)據(jù)"哼"出來(lái).) ;=============================================== ;我和你 DB 23,08 ;3_ DB 25,08 ;5_ DB 21,16 ;1_ DB 22,08 ;2_ DB 23,08 ;3_ DB 15,16 ;5 DB 21,08 ;1_ DB 22,08 ;2_ DB 23,08 ;3_ DB 25,08 ;5_ DB 22,24 ;2_ DB 00,08 ;2_ DB 23,08 ;3_ DB 25,08 ;5_ DB 21,16 ;1_ DB 22,08 ;2_ DB 23,08 ;3_ DB 16,16 ;6 DB 22,08 ;2_ DB 15,08 ;5 DB 22,08 ;2_ DB 23,08 ;3_ DB 21,24 ;1_ DB 00,08 ;結(jié)束音樂 ;========================================= (未完待續(xù))-------僅供參考! |