找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5158|回复: 0
打印 上一主题 下一主题
收起左侧

[原创]浅谈用 51hei-5 学习单片机播放音乐(1)

[复制链接]
跳转到指定楼层
楼主
ID:27770 发表于 2011-2-13 00:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

浅谈用 51hei-5 学习单片机播放音乐(1)

春节无事做,试了一下使用 51hei-5 的单片机播放音乐.
非常遗憾的是:怎么弄也不能正常放出音乐来!-----把 51hei-5 的蜂鸣器焊下来,一测量,哈哈!是一个有源蜂鸣器!----可能焊接元器件出错了!
找了一个 32Ω 的小耳机(不要使用8Ω低阻抗的).代替原来的蜂鸣器.就可以出来音乐了!(蜂鸣器具有尖锐的频率响应点,不适合播放音乐!)

找了一些 51 单片机播放音乐的例子,网络上非常多这种资源.发现这些例子对音乐程序的播放首先是对歌曲简谱进行编码.甚至还有人发布了可以编码给单片机使用的软件.
仔细分析了一下,主要有 2 种编码方式:
第一种:
仅仅使用一个表格,使用 3 字节结构,前面 2 字节是单个音符的数据,这个数据赋值给单片机的定时器后,让定时器溢出时,反转输出端口,产生一个固定频率输出.不同的数据,就有不同的频率,这样,音乐的 1 2 3 4 5 就出来了.第 3 字节是该音符输出的节拍时间.
例如:
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 个字节,同样它是给单片机定时器赋值后,让定时器溢出时,反转输出端口,达到输出对应的频率.

例如:
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 个字节来表示,高字节代表指向某个音符的数字,低字节代表节拍.

例如:
Z_TABL1:           ;高字节是音调索引,低字节是节拍长度
;我的祖国(前奏过门)----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 种方法是很好的.它把基本音符与具体音乐分开了!可以节省大量储存空间.删除歌曲不会影响基本音符在程序里的内容.这些音符内容仅仅被不同音乐的信息来调用,无论上面歌曲,都可以使用它们.
因此,我就使用第二种方法.
接下来,要说的是怎么来编写和辨认这些信息.
当我们得到一份示例程序后,对音乐信息来说,很不直观的.谁也不能一下子看出这些数字是哪一个音符.与原始音乐乐谱完完全全变了样!
如何让程序里的数据与原始音乐对上号呢?------怎么让人一下子看出来是什么呢?
方法是:
把音乐中的 1 2 3 ..... 与音符表格对应起来.就是当你编写程序时,完完全全可以按照原始音乐的简谱照抄下来.
例如:

你可以把  "五星红旗迎风飘扬" 直接写下" 5 5 1 5 3 1 5 6 5  "!----------是不是很直观!
那么,这样如何区别其的音高呢? 同样一个 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 之后,就对上表格了!
而判断一个音符的高中低,则是由音符数据的高半字节是 0,1,2....来决定.非常方便!
经过这种改造,编写歌谱时就可以直接照原始歌谱抄了!---------乐曲表格数据的可读性极好!分析查错也就非常方便了!
而节拍信息也是按照原始乐谱来抄写.你可以把一个小节定义为 16 ,也可以定义为 8 或 32 ,定义数字越大,每小节容纳音符的最小时间单位就越少!通常,使用 16 是很好用的!
例如:上面说的  "五星红旗迎风飘扬" ,对应乐谱为 5 5 1 5 3 1 5 6 5  " ,按照该歌曲的节拍和上面说的音高写法,可以写成:
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 ;结束音乐
;=========================================
(未完待续)-------仅供参考!

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表