历史上的今天
今天是:2025年01月28日(星期二)
2021年01月28日 | 8051单片机教程第二十八课:单片机音乐程序的设计
2021-01-28 来源:eefocus
利用单片机(或单板机)奏乐大概是无线电爱好者感兴趣的问题之一。本文从单片机的基本发间实验出发,谈谈音乐程序的设计原理,并给出具体实例,以供参考。
单片机的基本发音实验
我们知道,声音的频谱范围约在几十到几千赫兹,若能利用程序来控制单处机某个口线的“高”电平或低电平,则在该口线上就能产生一定频率的矩形波,接上喇叭就能发出一定频率的声音,若再利用延时程序控制“高”“低”电平的持续时间,就能改变输出频率,从而改变音调。
例如,要产生200HZ的音频信号,按图1接入喇叭(若属临时实验,也可将喇叭直接接在P1口线上),实验程序为:
其中子程序DEL为延时子程序,当R3为1时,延时时间约为20us,R3中存放延时常数,对200HZ音频,其周期为1/200秒,即5ms。这样,当P1.4的高电平或低电平的持续时间为2.5ms,即R3的时间常数取2500/20=125(7DH)时,就能发出200HZ的音调。将上述程序键入学习机,并不断修改R3的常数可以感到音调的变化。乐曲中,每一音符对应着确定的频率,表1给出C调时各音符频率及其相应的时间常数。读者可以根据表1所提供的常数,将其16进制代码送入R3,反复练习体会。根据表1可以奏出音符。仅这还不够,要准确奏出一首曲子,必须准确地控制乐曲节奏,即一音符的持续时间。
音符的节拍我们可以用定时器T0来控制,送入不同的初值,就可以产生不同的定时时间。便如某歌曲的节奏为每分钟94拍,即一拍为0.64秒。其它节拍与时间的对应关系见表2。
但时,由于T0的最大定时时间只能为131毫秒,因此不可能直接用改变T0的时间初值来实现不同节拍。我们可以用T0来产生10毫秒的时间基准,然后设置一个中断计数器,通过判别中断计数器的值来控制节拍时间的长短。表2中也给出了各种节拍所对应的时间常数。例如对1/4拍音符,定时时间为0.16秒,相应的时间常数为16(即10H);对3拍音符,定时时间为1.92秒,相应时间长数为192(即C0H)。
我们将每一音符的时间常数和其相应的节拍常数作为一组,按顺序将乐曲中的所有常数排列成一个表,然后由查表程序依次取出,产生音符并控制节奏,就可以实现演奏效果。此外,结束符和体止符可以分别用代码00H和FFH来表示,若查表结果为00H,则表示曲子终了;若查表结果为FFH,则产生相应的停顿效果。为了产生手弹的节奏感,在某些音符(例如两个相同音符)音插入一个时间单位的频率略有不同的音符。
程序框图如图2所示。
下面给出程序序请单,可直接在TD-III型学习机上演奏,对其它不同型号的学习机,只需相应地改变一下地址即可。本程序演奏的是民歌“八月桂花遍地开”,C调,节奏为94拍/分。读者也可以自行找出一首歌,按表1和表2给定的常数,将乐曲翻译成码表输入机器,而程序不变。本实验方法简便,即使不懂音乐的人,将一首陌生的曲子翻译成代码也是易事,和着机器的演奏学唱一首歌曲,其趣味无穷。
程序清单(略,请参看源程序的说明)。
《无线电》1992年第3期。
硬件连接说明:
随便找一个仿真机或者什么单片机实验板,只要能工作的就行,将程序输入,运行,然后找个音箱(你计算机旁边应当就有一对吧)拨出插头,插头的前端接在P1。0上,后面部分找根线接单片机的地,就应当有声了,然后怎么改进硬件连接就是你的事了。。。。

《无线电》1992年第3期。
史海拾趣
|
尽管我们不能改变制度,也不一定能够改变别人,但我们可以改变自己,因为没有人能够阻止我们不断进步,如果失败或者失意,那只能怪我们自己无能,怪我们自己不善于学习,不能怪别人没有给您机会,更不能怪这个社会...... 我创业至今 ...… 查看全部问答> |
|
几天前帮同学课程设计写的那个数字钟(51单片机简洁版汇编数字钟),由于时间紧,随便搞了两下。那个程序不怎么好,用两个按钮分别调时调分,而且只能增加,不小心按到按钮便调动了时间,不能用于实际产品。恰巧我自己的单片机课程设计题目是“自动 ...… 查看全部问答> |
|
示波器数字示波器一直是工程师设计、调试产品的好帮手。但随着计算机、半导体和通信技术的发展,电路系统的信号时钟速度越来越快,信号上升时间也越来越短,导致因底层模拟信号完整性问题引发的数字错误日益突出。针对这些新的测试挑战,示波器供应 ...… 查看全部问答> |
|
WM60系统 CPU:s3c2443 gprs模块是MC52i 现在通过RIL,希望同时获取信号强弱及IMEI,以及可以拨号上网。 现在可以获取信号及IMEI,但GPRS拨号不上,一下是拨号中的debug message,那位DX可以帮忙指点一下 ####################Debug message## ...… 查看全部问答> |
|
老师让做个多点温度检测通过RS232协议传给上位机。就剩下最关键18B20的通过读64位ROM中的48位序列号来确定具体的那个18B20了。我想尽快结项啊啊啊啊!! 哪位大侠能出来指点一二,给个参考代码更是感激不尽,毫无头绪中…………………………代码啊 ...… 查看全部问答> |
|
我的程序是这么写的,到open哪儿就打不开了.有人说是路径的问题,可是我看不出来路径有问题啊?哪位大侠帮帮忙吧! if(FAILED(CoInitializeEx(NULL, COINIT_MULTITHREADED))) return FA ...… 查看全部问答> |
|
一个RS232一个RS485接口,都是用来做什么收发器,电平逻辑转化的,但这些都是纯理论上的作用,我只想知道他们实际中能干什么,不要有太多专业术语,还有这2个有什么区别?… 查看全部问答> |




