28课:单片机音乐程序设计

发布者:数据小巨人最新更新时间:2020-07-04 来源: 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,则产生对应的停顿效果。为了产生手弹的节奏感,在某些音符(例如两个相同音符)音插入一个时间单位的频率略有不一样的音符。


下面给出程序序清单,可直接在TD-III型学习机上演奏,对其它不一样型号的学习机,只需对应地改变一下地址即可。本程序演奏的是民歌“八月桂花遍地开”,C调,节奏为94拍/分。读者也能自行找出一首歌,按表1和表2给定的常数,将乐曲翻译成码表输入机器,而程序不变。本实验办法简便,即使不懂音乐的人,将一首陌生的曲子翻译成代码也是易事,和着机器的演奏学唱一首歌曲,其趣味无穷。


程序清单(略,请参看源程序的说明)。


程序框图如图2所示。


<单片机音乐程序的设计图>


硬件连接说明:

随便找一个仿真机或者什么单片机实验板,只要能工作的就行,将程序输入,运行,然后找个音箱(你计算机旁边应当就有一对吧)拨出插头,插头的前端接在P1。0上,后面部分找根线接单片机的地,就应当有声了,然后怎么改进硬件连接就是你的事了。。。。


音乐程序汇编代码代码1 -------------Voice.asm--------------------------

        ORG     0000H
        LJMP    START
        ORG     000BH
        INC     20H     ;中断服务,中断计数器加1
        MOV     TH0,#0D8H
        MOV     TL0,#0EFH  ;12M晶振,形成10毫秒中断
        RETI
START: 
        MOV     SP,#50H
        MOV     TH0,#0D8H
        MOV     TL0,#0EFH
        MOV     TMOD,#01H
        MOV     IE,#82H
MUSIC0:
        NOP
        MOV     DPTR,#DAT      ;表头地址送DPTR
        MOV     20H,#00H        ;中断计数器清0
        MOV     B,#00H          ;表序号清0
MUSIC1:
        NOP
        CLR     A
        MOVC    A,@A+DPTR       ;查表取代码
        JZ      END0     ;是00H,则结束
        CJNE    A,#0FFH,MUSIC5
        LJMP    MUSIC3
MUSIC5:
        NOP
        MOV     R6,A
        INC     DPTR
        MOV     A,B
        MOVC    A,@A+DPTR       ;取节拍代码送R7
        MOV     R7,A
        SETB    TR0             ;启动计数
MUSIC2:
        NOP
        CPL     P1.0
        MOV     A,R6
        MOV     R3,A
        LCALL   DEL
        MOV     A,R7
        CJNE    A,20H,MUSIC2    ;中断计数器(20H)=R7否?
                                ;不等,则继续循环
        MOV     20H,#00H        ;等于,则取下一代码
        INC     DPTR
;        INC     B
        LJMP    MUSIC1
MUSIC3:
        NOP
        CLR     TR0     ;休止100毫秒
        MOV     R2,#0DH
MUSIC4:
        NOP
        MOV     R3,#0FFH
        LCALL   DEL
        DJNZ    R2,MUSIC4
        INC     DPTR
        LJMP    MUSIC1
END0:
        NOP
        MOV     R2,#64H ;歌曲结束,延时1秒后继续
MUSIC6:
        MOV     R3,#00H
        LCALL   DEL
        DJNZ    R2,MUSIC6
        LJMP    MUSIC0
DEL:
        NOP
DEL3:                 
        MOV     R4,#02H
DEL4:  
        NOP
        DJNZ    R4,DEL4
        NOP
        DJNZ    R3,DEL3
        RET
        NOP
DAT:
 db 26h,20h,20h,20h,20h,20h,26h,10h,20h,10h,20h,80h,26h,20h,30h,20h
 db 30h,20h,39h,10h,30h,10h,30h,80h,26h,20h,20h,20h,20h,20h,1ch,20h
 db 20h,80h,2bh,20h,26h,20h,20h,20h,2bh,10h,26h,10h,2bh,80h,26h,20h
 db 30h,20h,30h,20h,39h,10h,26h,10h,26h,60h,40h,10h,39h,10h,26h,20h
 db 30h,20h,30h,20h,39h,10h,26h,10h,26h,80h,26h,20h,2bh,10h,2bh,10h
 db 2bh,20h,30h,10h,39h,10h,26h,10h,2bh,10h,2bh,20h,2bh,40h,40h,20h
 db 20h,10h,20h,10h,2bh,10h,26h,30h,30h,80h,18h,20h,18h,20h,26h,20h
 db 20h,20h,20h,40h,26h,20h,2bh,20h,30h,20h,30h,20h,1ch,20h,20h,20h
 db 20h,80h,1ch,20h,1ch,20h,1ch,20h,30h,20h,30h,60h,39h,10h,30h,10h
 db 20h,20h,2bh,10h,26h,10h,2bh,10h,26h,10h,26h,10h,2bh,10h,2bh,80h
 db 18h,20h,18h,20h,26h,20h,20h,20h,20h,60h,26h,10h,2bh,20h,30h,20h
 db 30h,20h,1ch,20h,20h,20h,20h,80h,26h,20h,30h,10h,30h,10h,30h,20h
 db 39h,20h,26h,10h,2bh,10h,2bh,20h,2bh,40h,40h,10h,40h,10h,20h,10h
 db 20h,10h,2bh,10h,26h,30h,30h,80h,00H

END


音乐程序汇编代码代码2 -------------Voice1.asm--------------------------

;标题    '八月桂花香'发声程序       
;摘要    详见'无线电'92年3期
;作者    周振安
  ORG     0000H
        LJMP    START
        ORG     000BH
        INC     20H     ;中断服务,中断计数器加1
        MOV     TH0,#0D8H
        MOV     TL0,#0EFH  ;12M晶振,形成10毫秒中断
        RETI
START: 
        MOV     SP,#50H
        MOV     TH0,#0D8H
        MOV     TL0,#0EFH
        MOV     TMOD,#01H
        MOV     IE,#82H
MUSIC0:
        NOP
        MOV     DPTR,#DAT      ;表头地址送DPTR
        MOV     20H,#00H        ;中断计数器清0
        MOV     B,#00H          ;表序号清0
MUSIC1:
        NOP
        CLR     A
        MOVC    A,@A+DPTR       ;查表取代码
        JZ      END0     ;是00H,则结束
        CJNE    A,#0FFH,MUSIC5
        LJMP    MUSIC3
MUSIC5:
        NOP
        MOV     R6,A
        INC     DPTR
        MOV     A,B
        MOVC    A,@A+DPTR       ;取节拍代码送R7
        MOV     R7,A
        SETB    TR0             ;启动计数
MUSIC2:
        NOP
        CPL     P1.0
        MOV     A,R6
        MOV     R3,A
        LCALL   DEL
        MOV     A,R7
        CJNE    A,20H,MUSIC2    ;中断计数器(20H)=R7否?
                                ;不等,则继续循环
        MOV     20H,#00H        ;等于,则取下一代码
        INC     DPTR
;        INC     B
        LJMP    MUSIC1
MUSIC3:
        NOP
        CLR     TR0     ;休止100毫秒
        MOV     R2,#0DH
MUSIC4:
        NOP
        MOV     R3,#0FFH
        LCALL   DEL
        DJNZ    R2,MUSIC4
        INC     DPTR
        LJMP    MUSIC1
END0:
        NOP
        MOV     R2,#64H ;歌曲结束,延时1秒后继续
MUSIC6:
        MOV     R3,#00H
        LCALL   DEL
        DJNZ    R2,MUSIC6
        LJMP    MUSIC0
DEL:
        NOP
DEL3:                 
        MOV     R4,#02H
DEL4:  
        NOP
        DJNZ    R4,DEL4
        NOP
        DJNZ    R3,DEL3
        RET
        NOP
DAT:  
        DB      18H,     30H,     1CH,     10H
        DB      20H,     40H,     1CH,     10H    
        DB      18H,     10H,     20H,     10H
        DB      1CH,     10H,     18H,     40H
        DB      1CH,     20H,     20H,     20H
        DB      1CH,     20H,     18H,     20H    
        DB      20H,     80H,     0FFH,    20H
        DB      30H,     1CH,     10H  ,   18H
        DB      20H,     15H,     20H ,    1CH
        DB      20H,     20H,     20H ,    26H
        DB      40H,     20H ,    20H ,    2BH
        DB      20H,     26H,     20H ,    20H    
        DB      20H,     30H ,    80H ,    0FFH
        DB      20H,     20H,     1CH ,    10H
        DB      18H,     10H,     20H ,    20H
        DB      26H,     20H ,    2BH ,    20H
        DB      30H,     20H ,    2BH ,    40H
        DB      20H,     20H  ,   1CH  ,   10H
        DB      18H,     10H,     20H,     20H
        DB      26H,     20H ,    2BH,     20H
        DB      30H,     20H,     2BH ,    40H
        DB      20H,     30H,     1CH ,    10H
        DB      18H,     20H ,    15H ,    20H
        DB      1CH,     20H ,    20H ,    20H
        DB      26H,     40H,     20H ,    20H    
        DB      2BH,     20H,     26H ,    20H    
        DB      20H,     20H,     30H ,    80H
        DB      20H,     30H,     1CH ,    10H
        DB      20H,     10H,     1CH ,    10H
        DB      20H,     20H,     26H  ,   20H
        DB      2BH,     20H,     30H  ,   20H
        DB      2BH,     40H,     20H   ,  15H
        DB      1FH,     05H,     20H    , 10H
        DB      1CH,     10H,     20H ,    20H
        DB      26H,     20H,     2BH ,    20H
        DB      30H,     20H,     2BH ,    40H
        DB      20H,     30H,     1CH  ,   10H
        DB      18H,     20H ,    15H  ,   20H
        DB      1CH,     20H ,    20H  ,   20H
        DB      26H,     40H,     20H  ,   20H
        DB      2BH,     20H,     26H   ,  20H
        DB      20H,     20H,     30H,     30H     
        DB      20H,     30H,     1CH,     10H
        DB      18H,     40H,     1CH,     20H
        DB      20H,     20H,     26H,     40H
        DB      13H,     60H,     18H ,    20H
        DB      15H,     40H,     13H ,    40H
        DB      18H,     80H,     00H
end

[1] [1]
关键字:单片机  音乐程序  频谱范围 引用地址:28课:单片机音乐程序设计

上一篇:27课:关于单片机的一些基本概念
下一篇:基于汇编语言单片机的时钟设计

推荐阅读最新更新时间:2024-11-17 12:30

单片机c语言指针和取地址以及类型转换
指针和地址运算符   在第四课我们学习数据类型时,学习过指针类型,知道它是一种存放指向另一个数据的地址的变量类型。指针是C语言中一个十分重要的概念,也是学习C语言中的一个难点。对于指针将会在第九课中做详细的讲解。在这里我们先来了解一下C语言中提供的两个专门用于指针和地址的运算符:      * 取内容      & 取地址    取内容和地址的一般形式分别为:      变量 = * 指针变量      指针变量 = & 目标变量   取内容运算是将指针变量所指向的目标变量的值赋给左边的变量;取地址运算是将目标变量的地址赋给左边的变量。要注意的是:指针变量中只能存放地址(也就是指针型数据),一般情况下不要将非指针类型的数据赋值给一
[单片机]
基于单片机控制的电动车锂电池组设计
   摘 要: 针对目前电动车锂电池组所用的保护电路大多都由分立原件构成,存在控制精度不够高、技术指标低、不能有效保护锂电池组等特点,提出一种基于单片机的电动车36 V锂电池组保护电路设计方案。利用高性能、低功耗的ATmega16L 单片机作为检测和控制核心,用由MC34063构成的DC /DC变换控制电路为整个保护电路提供稳压电源,辅以LM60测温、MOS管IRF530N作充放电控制开关,实现对整个电池组和单个电池的状态监控和保护功能,达到延长电池使用寿命的目的。   随着电动自行车的逐渐普及,电动自行车的主要能源---锂电池也成为众人关心的焦点。 锂电池与镍镉、镍氢电池不太一样,因其能量密度高,对充放电要求很高。 当过充、过
[汽车电子]
基于<font color='red'>单片机</font>控制的电动车锂电池组设计
单片机秘籍之降龙十五掌
学习使用单片机就是理解单片机硬件结构,以及内部资源的应用,在汇编或C语言中学会各种功能的初始化设置,以及实现各种功能的程序编制。 第一步:数字I/O的使用 使用按钮输入信号,发 光二极管显示输出电平,就可以学习引脚的数字I/O功能,在按下某个按钮后,某发光二极管发亮,这就是数字电路中组合逻辑的功能,虽然很简单,但是可以学 习一般的单片机编程思想,例如,必须设置很多寄存器对引脚进行初始化处理,才能使引脚具备有数字输入和输出输出功能。每使用单片机的一个功能,就要对控制该功能的寄存器进行设置,这就是单片机编程的特点,千万不要怕麻烦,所有的单片机都是这样。 第二步:定时器的使用 学会定时器的使用,就 可以用单片机实现时序电路,
[单片机]
MSP430单片机中的WDT研究
引 言 软件的可靠性一直是一个关键问题。任何使用软件的人都可能会经历计算机死机或程序跑飞的问题,这种情况在嵌入式系统中也同样存在。由于单片机的抗干扰能力有限,在工业现场的仪器仪表中,常会由于电压不稳、电弧干扰等造成死机。在水表、电表等无人看守的情况下,也会因系统遭受干扰而无法重启。为了保证系统在干扰后能自动恢复正常,看门狗定时器(Watchdog Timer)的利用是很有价值的。 1 看门狗的作用 看门狗定时器是一个计数器,基本功能是在发生软件问题和程序跑飞后使系统重新启动。看门狗计数器正常工作时自动计数,程序流程定期将其复位清零,如果系统在某处卡死或跑飞,该定时器将溢出,并将进入中断。在定时器中断中执行一些复位操作,使系
[单片机]
AVR单片机-数码管1
八段数码管由八段LED构成 , 各LED阴极或阳极并在一起,称为 位选线 :共阴、共阳 。 其余8个引脚各自引出,称为 段选线 ,各段可以分别控制 。 使用LED数码管时,要注意区分这两种不同的接法。为了显示数字或字符,必须对数字或字符进行编码。七段数码管加上一个小数点,共计8段。因此为LED显示器提供的编码正好是一个字节。 共阳极数码管译码表: 0x3f , 0x06 , 0x5b , 0x4f , 0x66 , 0x6d , 0   1 2   3 4 5 0x7d , 0x07 , 0x7f , 0x6f , 0x77 , 0x7c , 6 7 8 9 A
[单片机]
AVR<font color='red'>单片机</font>-数码管1
单片机控制的静电除尘电源调压系统
       1. 引言   静电除尘器有除尘效率高、运行和维修费用相对低廉等特点,在减少排放到大气中有害粉尘方面起着十分重要的作用,是当前使用较为广泛的一种环保设备。静电除尘器是利用高压静电吸附带电离子的原理进行除尘。一般来说,静电极板电压越高,对带电离子的吸附能力就越强,除尘效率越高。但电压越高,电场内会出现频繁的火花闪烁,甚至产生电弧,放电过程难以控制,除尘效率明显降低,这种情况应该避免。如果能够控制极板电压长时间维持在临界放电状态,就可以获得最佳的除尘效果并有效节约电力资源。实验证明,基于单片机 80C196KC的静电除尘电源三相交流调压控制系统能够很好实现这一功能。    2. 静电除尘电源主电路及交流调压结
[电源管理]
<font color='red'>单片机</font>控制的静电除尘电源调压系统
基于AVR单片机的LED显示屏控制系统的研究
   1 引言   LED 显示屏是八十年代后期在全球迅速发展起来的新型信息传播媒体,是集微电子技术、光电子技术、计算机技术、信息处理技术于一体的大型显示系统。它以其色彩鲜艳、动态范围广、亮度高、寿命长、工作性能稳定而日渐成为显示媒体中的佼佼者,广泛应用于广告、证券、信息传播、新闻发布等方面, 是目前国际上较为先进的宣传显示媒体 .本文提出了一种主从式单片机的LED 显示屏解决方案, 该设计方案利用AVR 单片机自身的FLASH ROM 和RAM,外部无需任何存储电路,电路结构简单。   2 系统的工作原理及总体方案设计   2. 1 AVR 单片机   AVR 单片机是增强型内置Flash 的RISC(Reduc
[电源管理]
基于AVR<font color='red'>单片机</font>的LED显示屏控制系统的研究
【GD32 MCU 入门教程】GD32 MCU 常见外设介绍(14)RTC 模块介绍
GD32 MCU内部提供了一个RTC(实时时钟)模块,通过RTC可以实现日历时钟、闹钟等功能。RTC也可以用于深度睡眠或待机模式的低功耗唤醒。不同系列的GD32 MCU在RTC设计和功能上有所区别,总体可以分为三大系列: (1)F10x、F30x、E10x系列RTC功能基本相同,后文简称0x系列。 (2)F1x0、F3x0、E23x系列RTC功能基本相同,后文简称x0系列。 (3)F405、F407、F450系列RTC功能基本相同,后文简称4xx系列。后文会对0x系列、x0系列、4xx系列的RTC模块分别进行介绍,简单介绍RTC的工作原理、配置使用方法。 14.1.GD32 RTC 外设简介 0x 系列 RTC 0x系列RTC整体
[单片机]
【GD32 <font color='red'>MCU</font> 入门教程】GD32 <font color='red'>MCU</font> 常见外设介绍(14)RTC 模块介绍
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved