淺談用 51hei-5 學習單片機播放音樂(1)
春節(jié)無事做,試了一下使用 51hei-5 的單片機播放音樂. 非常遺憾的是:怎么弄也不能正常放出音樂來!-----把 51hei-5 的蜂鳴器焊下來,一測量,哈哈!是一個有源蜂鳴器!----可能焊接元器件出錯了! 找了一個 32Ω 的小耳機(不要使用8Ω低阻抗的).代替原來的蜂鳴器.就可以出來音樂了!(蜂鳴器具有尖銳的頻率響應點,不適合播放音樂!)
找了一些 51 單片機播放音樂的例子,網絡上非常多這種資源.發(fā)現(xiàn)這些例子對音樂程序的播放首先是對歌曲簡譜進行編碼.甚至還有人發(fā)布了可以編碼給單片機使用的軟件. 仔細分析了一下,主要有 2 種編碼方式: 第一種: 僅僅使用一個表格,使用 3 字節(jié)結構,前面 2 字節(jié)是單個音符的數據,這個數據賦值給單片機的定時器后,讓定時器溢出時,反轉輸出端口,產生一個固定頻率輸出.不同的數據,就有不同的頻率,這樣,音樂的 1 2 3 4 5 就出來了.第 3 字節(jié)是該音符輸出的節(jié)拍時間. 例如: 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 個表格,它專門有一個音符表格,里面包含了從低音 1 2 3.... 到 高音 1 2 3 .... 的單個音符信息.每個音符使用 2 個字節(jié),同樣它是給單片機定時器賦值后,讓定時器溢出時,反轉輸出端口,達到輸出對應的頻率.
例如: Z_TABL1: ;決定音調的定時初值.----------什么歌都可以使用 ;-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 另外一個表格就是音樂的表格了,它使用 2 個字節(jié)來表示,高字節(jié)代表指向某個音符的數字,低字節(jié)代表節(jié)拍.
例如: Z_TABL1: ;高字節(jié)是音調索引,低字節(jié)是節(jié)拍長度 ;我的祖國(前奏過門)----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é)省大量儲存空間.刪除歌曲不會影響基本音符在程序里的內容.這些音符內容僅僅被不同音樂的信息來調用,無論上面歌曲,都可以使用它們. 因此,我就使用第二種方法. 接下來,要說的是怎么來編寫和辨認這些信息. 當我們得到一份示例程序后,對音樂信息來說,很不直觀的.誰也不能一下子看出這些數字是哪一個音符.與原始音樂樂譜完完全全變了樣! 如何讓程序里的數據與原始音樂對上號呢?------怎么讓人一下子看出來是什么呢? 方法是: 把音樂中的 1 2 3 ..... 與音符表格對應起來.就是當你編寫程序時,完完全全可以按照原始音樂的簡譜照抄下來. 例如:
你可以把 "五星紅旗迎風飄揚" 直接寫下" 5 5 1 5 3 1 5 6 5 "!----------是不是很直觀! 那么,這樣如何區(qū)別其的音高呢? 同樣一個 5 ,有低音,中音,高音 啊! 我們把低音寫作 5 ,把中音寫作 15 ,把高音寫作 25 就可以準確分辨出來. 那么,這些 5 又怎么去獲取對應的音符值(定時器值)呢? 我們可以讓它與音符表格對應起來.例如上面的 1 2 3 ....低音部分. 表格是從 0 開始放置的,音符是從 1 開始的.那么,把低音的數字 -1 就可以查表獲得數據了! 而中音部分呢? 11 是中音的 1 ,音符表格則是在第 7 行, 11-7=4 ,就是說,凡是中音數據,把它們 -4 之后,就對上表格了! 高音部分的 21 是高音的 1 ,音符表格排列在第 14 行, 21-14=7,就是說,凡是高音數據,把它們 -7 之后,就對上表格了! 而判斷一個音符的高中低,則是由音符數據的高半字節(jié)是 0,1,2....來決定.非常方便! 經過這種改造,編寫歌譜時就可以直接照原始歌譜抄了!---------樂曲表格數據的可讀性極好!分析查錯也就非常方便了! 而節(jié)拍信息也是按照原始樂譜來抄寫.你可以把一個小節(jié)定義為 16 ,也可以定義為 8 或 32 ,定義數字越大,每小節(jié)容納音符的最小時間單位就越少!通常,使用 16 是很好用的! 例如:上面說的 "五星紅旗迎風飄揚" ,對應樂譜為 5 5 1 5 3 1 5 6 5 " ,按照該歌曲的節(jié)拍和上面說的音高寫法,可以寫成: 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 當我們垂直往下讀的時候,原始簡譜的信息就直觀出來了!(要把讀 11 讀成中音 1 , 15 讀成中音 5 , 05 讀成低音5 ......) 下面給出一個 08 奧運的"我和你" 的前面 2 句,可以直接根據數據"哼"出來.) ;=============================================== ;我和你 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 ;結束音樂 ;========================================= (未完待續(xù))-------僅供參考! |