打印

求助单片机音乐数组的值怎么得到

[复制链接]
3219|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
jxyfdlh1987|  楼主 | 2013-4-23 22:33 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
教你制作单片机音乐文件.pdf (946.81 KB)

请大家帮我看下这个数组的值怎么计算的,非常感谢!
unsigned char n=0;  //n为节拍常数变量   
unsigned char code music_tab[] ={   
0x18, 0x30, 0x1C , 0x10, //格式为:  节拍常数, 频率常数, 节拍常数,   
0x20, 0x40, 0x1C , 0x10,   
0x18, 0x10, 0x20 , 0x10,   
0x1C, 0x10, 0x18 , 0x40,   
0x1C, 0x20, 0x20 , 0x20,   
0x1C, 0x20, 0x18 , 0x20,   
0x20, 0x80, 0xFF , 0x20,   
0x30, 0x1C, 0x10 , 0x18,   
0x20, 0x15, 0x20 , 0x1C,   
0x20, 0x20, 0x20 , 0x26,   
0x40, 0x20, 0x20 , 0x2B,   
0x20, 0x26, 0x20 , 0x20,   
0x20, 0x30, 0x80 , 0xFF,   
0x20, 0x20, 0x1C , 0x10,   
0x18, 0x10, 0x20 , 0x20,   
0x26, 0x20, 0x2B , 0x20,   
0x30, 0x20, 0x2B , 0x40,   
0x20, 0x20, 0x1C , 0x10,   
0x18, 0x10, 0x20 , 0x20,   
0x26, 0x20, 0x2B , 0x20,   
0x30, 0x20, 0x2B , 0x40,   
0x20, 0x30, 0x1C , 0x10,   
0x18, 0x20, 0x15 , 0x20,   
0x1C, 0x20, 0x20 , 0x20,   
0x26, 0x40, 0x20 , 0x20,   
0x2B, 0x20, 0x26 , 0x20,   
0x20, 0x20, 0x30 , 0x80,   
0x20, 0x30, 0x1C , 0x10,   
0x20, 0x10, 0x1C , 0x10,   
0x20, 0x20, 0x26 , 0x20,   
0x2B, 0x20, 0x30 , 0x20,   
0x2B, 0x40, 0x20 , 0x15,   
0x1F, 0x05, 0x20 , 0x10,   
0x1C, 0x10, 0x20 , 0x20,   
0x26, 0x20, 0x2B , 0x20,   
0x30, 0x20, 0x2B , 0x40,   
0x20, 0x30, 0x1C , 0x10,   
0x18, 0x20, 0x15 , 0x20,   
0x1C, 0x20, 0x20 , 0x20,   
0x26, 0x40, 0x20 , 0x20,   
0x2B, 0x20, 0x26 , 0x20,   
0x20, 0x20, 0x30 , 0x30,   
0x20, 0x30, 0x1C , 0x10,   
0x18, 0x40, 0x1C , 0x20,   
0x20, 0x20, 0x26 , 0x40,   
0x13, 0x60, 0x18 , 0x20,   
0x15, 0x40, 0x13 , 0x40,   
0x18, 0x80, 0x00   
};   
   

相关帖子

沙发
tyw| | 2013-4-24 09:45 | 只看该作者
本帖最后由 tyw 于 2013-4-24 09:50 编辑

这是本人一个产品中的音乐单元,很完整,供参考.
中央c组里的A=440Hz
12个半音阶相邻关系是12√2 (2开12次方≈1.0594631)
例如 A=440Hz
     bB=440Hz x 1.0594631 = 466.16Hz   
      B=466.16Hz  x 1.0594631 = 493.88Hz
      C=493.88Hz x 1.0594631 = 523.25Hz

这是本人一个产品中的音乐单元,单音演奏的,多重和音不宜用这方法,一般用硬件的音源加单片机控制方法完成,有兴趣可去合泰网站http://www.holtek.com.cn/docum/consumer/8950.htm看看.ht8950提供了一个产生乐音包络用的硬件平台(a/d,d/a等),用软波表数据来完成音阶及包络,单片机只是进行控制,以前8bit声卡中ym3812与此差不多功能.

中央C的A音为440Hz,半音价之间关系为2开12次方(12√2=1.05946)
中央C的#A音为440Hz*1.05946=466.163Hz
中央C的B音为440Hz*1.05946*1.05946=493.883Hz
用定时器来模拟这个频率,精度取决于时钟快慢,一般小数点后保留一位,音准已可忍受了,生日快乐芯片是小数点前一位的,耳朵容易听坏的拉.

cpu用89c51,p1.7输出乐音,接无源蜂鸣器的驱动三极管基极

        ORG     0000H
        AJMP    CSH             ;主程序进入点
        ORG     000BH
        LJMP    TIM0            ;定时中断T0入口
;
;**********
;* 初始化 *
;**********
;
            ORG     0020H
CSH:    MOV     R0,#7FH         ;内部RAM(00H~7FH)清零
CSH1:   MOV     @R0,#00H
            DJNZ    R0,CSH1
            MOV     SP,#60H         ;堆栈60H~7FH,【使用89C51】
        MOV     TMOD,#01H       ;TMOD=11H,T0作16位计数器(4M晶振)
            CLR     TCON.4          ;T0禁止动作
        SETB    IE.1            ;T0允许中断
        SETB    PT0             ;T0中断优先
        SETB    IE.7            ;系统允许中断
;
;**********
;* 主程序 *
;**********
;
MAIN:   MOV     5CH,#00         ;取简码谱指针
        LCALL   MUSIC
        MOV     5CH,#49         ;取简码谱指针
        LCALL   MUSIC
        MOV     5CH,#66         ;取简码谱指针
        LCALL   MUSIC
        MOV     5CH,#100        ;取简码谱指针
        LCALL   MUSIC
        MOV     5CH,#108        ;取简码谱指针
        LCALL   MUSIC
        MOV     5CH,#136        ;取简码谱指针
        LCALL   MUSIC
        MOV     5CH,#174        ;取简码谱指针
        LCALL   MUSIC
        AJMP    MAIN
;
;*************************
;* 音乐子程序 MUSIC      *
;* 入口: 5CH←简码谱指针 *
;*************************
;
MUSIC:  MOV     A,5CH           ;简码谱指针装入A
        MOV     DPTR,#TABLE     ;至TABLE取简码
        MOVC    A,@A+DPTR
        MOV     R2,A            ;取到的简码暂存于R2
        JZ      END1            ;是否取到00(结束码)?
        ANL     A,#0FH          ;不是,则取低四位(节拍码)
        MOV     R6,A            ;将节拍码存入R6
        MOV     A,R2            ;将取到的简码再装入R2
        SWAP    A               ;高低四位交换
        ANL     A,#0FH          ;取低四位(音符码)
        JNZ     SING            ;取到的音符码是否为0?
        CLR     TR0             ;是,则不发音
        AJMP    D1              ;跳到D1
;
SING:   DEC     A               ;取到的音符码减1
        MOV     4BH,A           ;存入(4BH)
        RL      A               ;乘2
        MOV     DPTR,#TABLE1    ;至TABLE1取相对的高字节计数值
        MOVC    A,@A+DPTR
        MOV     TH0,A           ;取到的高字节存入TH0
        MOV     4AH,A           ;取到的高字节存入(4AH)
        MOV     A,4BH           ;再装入取到的音符码
        RL      A               ;乘2
        INC     A               ;加1
        MOVC    A,@A+DPTR       ;至TABLE1取相对的低位
        MOV     TL0,A           ;取到的低字节存入TL0
        MOV     49H,A           ;取到的低字节存入(49H)
        SETB    TR0             ;启动TIMER0
D1:     CALL    DELAY           ;基本单位时间1/4拍187毫秒
        INC     5CH             ;取简码谱指针加1
        AJMP    MUSIC           ;取下一个码
DD1:    RET
;
STOP:   NOP
;       JB      P3.7,STOP1      ;在软件延时中掺插做其他动作
;       SETB    P2.7            ;P2.7←"1"
        NOP
        NOP
STOP0:  NOP
        RET
STOP1:  NOP
;       JB      P3.6,STOP0    ;在软件延时中掺插做其他动作
;       SETB    P2.6            ;P2.6←"1"
        RET
;
END1:   CLR     TR0             ;停止TIMER0
        RET
;
TIM0:   PUSH    A               ;将A的值暂存于堆栈区
        PUSH    PSW             ;将PSW的值暂存于堆栈区
        MOV     TL0,49H         ;重设计数值
        MOV     TH0,4AH
        CPL     P1.7            ;将输出端P1.7取反(P1.7接至无源蜂鸣器)
        POP     PSW             ;至堆栈区取回PSW的值
        POP     A               ;至堆栈区取回A的值
        RETI                    ;返回主程序
;
DELAY:  MOV     R7,#02          ;187毫秒
D2:     MOV     R4,#24
D3:     MOV     R3,#48
        DJNZ    R3,$
        ACALL   STOP            ;在软件延时中掺插做其他动作
        DJNZ    R4,D3
        DJNZ    R7,D2
        DJNZ    R6,DELAY        ;决定节拍
        RET
;                             .5        .6        .7        1
TABLE1: DW      65111,65150,65199,65217   ;4M晶振时的定时中断时间常数
;                              2         3         4        5      ;若采用其它频率,则要根据乐音的
              DW      65252,65283,65297,65323   ;频率计算,例中央C的A音为440Hz,
;                              6         7        1`        2`    ;440Hz=2.273ms,把T0设置为2.273ms
              DW      65347,65367,65377,65394   ;中断即可发出A音.
;                              3`      4`     #6
              DW      65410,65417,65357
;
;***************************************************************
;* 音符代码  1   2  3  4  5  6  7  8  9  A  B   C  D   E    F     0    *
;* 音高         .5 .6 .7  1  2  3  4  5  6  7  1` 2` 3` 4` 5` 休止 *
;*-------------------------------------------------------------*
;* 节拍代码  1     2   3   4     5         6     8   A      C     F         *
;* 节拍       1/4 2/4 3/4 1 1(1/4) 1(1/2) 2 2(1/2) 3 3(3/4)      *
;*-------------------------------------------------------------*
;* 结束代码 00H                                                *
;*-------------------------------------------------------------*
;* 乐谱格式  每字节的高字节为音符代码,低字节为节拍代码         *
;*-------------------------------------------------------------*
;* 例子:        ⑴   ⑵    ⑶    ⑷    ⑸    ⑹    ⑺    ⑻    ⑼    ⑽    ⑾     *
;*      DB      A4H,02H,84H,02H,A4H,02H,84H,02H,D8H,04H,00H    *
;*      ⑴ A→唱"7" , 4→ 1 拍                                 *
;*      ⑵ 0→休止  , 2→2/4拍                                 *
;*      ⑶ 8→唱"5" , 4→ 1 拍                                 *
;*      ⑷ 0→休止  , 2→2/4拍                                 *
;*      ⑸ A→唱"7" , 4→ 1 拍                                 *
;*      ⑹ 0→休止  , 2→2/4拍                                 *
;*      ⑺ 8→唱"5" , 4→ 1 拍                                 *
;*      ⑻ 0→休止  , 2→2/4拍                                 *
;*      ⑼ D→唱"3`", 8→ 2 拍                                 *
;*      ⑽ 0→休止  , 4→ 1 拍                                 *
;*      ⑾ 00H→乐曲结束                                       *
;***************************************************************
;
TABLE:
;【00】
        DB      98H,02H,B4H,01H,94H,01H,68H,02H,94H,01H
        DB      64H,01H,48H,02H,64H,01H,44H,01H,28H,02H
        DB      64H,01H,94H,01H,B4H,01H,94H,01H,B4H,01H
        DB      94H,01H,B4H,01H,D4H,01H,94H,01H,64H,01H
        DB      44H,01H,64H,01H,98H,02H,01H,01H,00H
;【49】
        DB      A4H,02H,84H,02H,A4H,02H,84H,02H,D8H,04H
        DB      C8H,01H,01H,01H,01H,01H,00H
;【66】
        DB      42H,52H,62H,72H,82H,92H,A2H,B2H,42H,52H
        DB      62H,72H,82H,92H,A2H,B2H,00H
;【100】
        DB      61H,81H,B1H,D1H,B1H,81H,61H,00H
;【108】
        DB      11H,41H,61H,81H,61H,41H,11H,00H
;【136】
        DB      24H,04H,34H,04H,44H,04H,54H,04H,64H,04H,44H,04H,64H,04H,94H,04H
        DB      83H,01H,93H,01H,83H,01H,63H,01H,46H,02H,66H,02H
        DB      91H,21H,91H,21H,91H,21H,91H,21H,94H,00H
;【174】
        DB      94H,04H,A4H,04H,B4H,04H,C4H,04H,D4H,04H
        DB      B4H,04H,D8H,08H,C4H,04H,F4H,04H,CCH,00H
;
    END


使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
jxyfdlh1987 + 1
板凳
jxyfdlh1987|  楼主 | 2013-4-24 10:56 | 只看该作者
不过还非常感谢T叔!能提供这个:
中央c组里的A=440Hz
12个半音阶相邻关系是12√2 (2开12次方≈1.0594631)
例如 A=440Hz
     bB=440Hz x 1.0594631 = 466.16Hz   
      B=466.16Hz  x 1.0594631 = 493.88Hz
      C=493.88Hz x 1.0594631 = 523.25Hz


还麻烦T叔帮我看下 数组中的频率常数和节拍常数怎么计算出来的。谢谢!

使用特权

评论回复
地板
tyw| | 2013-4-24 11:41 | 只看该作者
本帖最后由 tyw 于 2013-4-24 12:20 编辑

频率常数要根据cpu晶振频率来计算,例如:你要让I/O口作1Hz的振荡,则每隔0.5秒打开I/O口,再隔0.5秒关闭I/O口,你的定时器怎么定时0.5秒应该会吧,定时中断的0.5秒的预置数就是这个频率常数.
节拍常数,得有点乐理知识,乐谱中常有δ=120,即每分钟演奏120个四分音符.当然还有δ=40,δ=192....等等.
我们先假定δ=120,即每分钟演奏120个四分音符.那么每个四分音符的时值就是60秒÷120=0.5秒.定时中断的0.5秒的预置数就是这个频率常数.
同理,对于δ=120,即每分钟演奏120个四分音符,它的二分音符时值就是1秒,八分音符时值就是0.25秒,十六分音符时值就是0.125秒.
一首曲子中若是采用了多种节拍速度,这个时值的权重是变化的.根据常用的节拍速度,可事先造表查询.
例如要以δ=120速度唱一个A1音,并保持2拍,则频率=440Hz,节拍=2x0.5秒

电子琴.rar (43.42 KB)
电子琴原理与维修技术.pdf (8.66 MB)

使用特权

评论回复
评论
jxyfdlh1987 2013-4-25 22:19 回复TA
谢谢T叔 
评分
参与人数 1威望 +3 收起 理由
jxyfdlh1987 + 3 赞一个!
5
jxyfdlh1987|  楼主 | 2013-4-24 21:05 | 只看该作者
谢谢T叔的帮忙,不过今天研究了一下,研究出来了,谢谢!

使用特权

评论回复
6
ZM_Caesar| | 2014-5-24 14:23 | 只看该作者
研究研究啊!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

125

帖子

3

粉丝