電子工程網(wǎng)

標題: 用C語(yǔ)言寫(xiě)歌曲程序 [打印本頁(yè)]

作者: A-lin    時(shí)間: 2011-11-29 12:40
標題: 用C語(yǔ)言寫(xiě)歌曲程序
向單片機高手求助,怎樣用C語(yǔ)言編寫(xiě)歌曲程序?
作者: tyw    時(shí)間: 2011-12-6 08:04
音樂(lè )生成器.rar (3.26 MB)    這個(gè)可參考一下

以下是本人一個(gè)產(chǎn)品中的音樂(lè )單元,用51匯編寫(xiě)的,很完整,供參考.
中央c組里的A=440Hz
12個(gè)半音階相鄰關(guān)系是12√2 (2開(kāi)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

這是本人一個(gè)產(chǎn)品中的音樂(lè )單元,單音演奏的,多重和音不宜用這方法,一般用硬件的音源加單片機控制方法完成,有興趣可去合泰網(wǎng)站http://www.holtek.com.cn/docum/consumer/8950.htm看看.ht8950提供了一個(gè)產(chǎn)生樂(lè )音包絡(luò )用的硬件平臺(a/d,d/a等),用軟波表數據來(lái)完成音階及包絡(luò ),單片機只是進(jìn)行控制,以前8bit聲卡中ym3812與此差不多功能.

中央C的A音為440Hz,半音價(jià)之間關(guān)系為2開(kāi)12次方(12√2=1.05946)
中央C的#A音為440Hz*1.05946=466.163Hz
中央C的B音為440Hz*1.05946*1.05946=493.883Hz
用定時(shí)器來(lái)模擬這個(gè)頻率,精度取決于時(shí)鐘快慢,一般小數點(diǎn)后保留一位,音準已可忍受了,生日快樂(lè )芯片是小數點(diǎn)前一位的,耳朵容易聽(tīng)壞的拉.

cpu用89c51,p1.7輸出樂(lè )音,接無(wú)源蜂鳴器的驅動(dòng)三極管基極

        ORG     0000H
        AJMP    CSH             ;主程序進(jìn)入點(diǎn)
        ORG     000BH
        LJMP    TIM0            ;定時(shí)中斷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禁止動(dòng)作
        SETB    IE.1            ;T0允許中斷
        SETB    PT0             ;T0中斷優(yōu)先
        SETB    IE.7            ;系統允許中斷
;
;**********
;* 主程序 *
;**********
;
MAIN:   MOV     5CH,#00         ;取簡(jiǎn)碼譜指針
        LCALL   MUSIC
        MOV     5CH,#49         ;取簡(jiǎn)碼譜指針
        LCALL   MUSIC
        MOV     5CH,#66         ;取簡(jiǎn)碼譜指針
        LCALL   MUSIC
        MOV     5CH,#100        ;取簡(jiǎn)碼譜指針
        LCALL   MUSIC
        MOV     5CH,#108        ;取簡(jiǎn)碼譜指針
        LCALL   MUSIC
        MOV     5CH,#136        ;取簡(jiǎn)碼譜指針
        LCALL   MUSIC
        MOV     5CH,#174        ;取簡(jiǎn)碼譜指針
        LCALL   MUSIC
        AJMP    MAIN
;
;*************************
;* 音樂(lè )子程序 MUSIC      *
;* 入口: 5CH←簡(jiǎn)碼譜指針 *
;*************************
;
MUSIC:  MOV     A,5CH           ;簡(jiǎn)碼譜指針裝入A
        MOV     DPTR,#TABLE     ;至TABLE取簡(jiǎn)碼
        MOVC    A,@A+DPTR
        MOV     R2,A            ;取到的簡(jiǎn)碼暫存于R2
        JZ      END1            ;是否取到00(結束碼)?
        ANL     A,#0FH          ;不是,則取低四位(節拍碼)
        MOV     R6,A            ;將節拍碼存入R6
        MOV     A,R2            ;將取到的簡(jiǎn)碼再裝入R2
        SWAP    A               ;高低四位交換
        ANL     A,#0FH          ;取低四位(音符碼)
        JNZ     SING            ;取到的音符碼是否為0?
        CLR     TR0             ;是,則不發(fā)音
        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             ;啟動(dòng)TIMER0
D1:     CALL    DELAY           ;基本單位時(shí)間1/4拍187毫秒
        INC     5CH             ;取簡(jiǎn)碼譜指針加1
        AJMP    MUSIC           ;取下一個(gè)碼
DD1:    RET
;
STOP:   NOP
;       JB      P3.7,STOP1      ;在軟件延時(shí)中摻插做其他動(dòng)作
;       SETB    P2.7            2.7←"1"
        NOP
        NOP
STOP0:  NOP
        RET
STOP1:  NOP
;       JB      P3.6,STOP0    ;在軟件延時(shí)中摻插做其他動(dòng)作
;       SETB    P2.6            2.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接至無(wú)源蜂鳴器)
        POP     PSW             ;至堆棧區取回PSW的值
        POP     A               ;至堆棧區取回A的值
        RETI                    ;返回主程序
;
DELAY:  MOV     R7,#02          ;187毫秒
D2:     MOV     R4,#24
D3:     MOV     R3,#48
        DJNZ    R3,$
        ACALL   STOP            ;在軟件延時(shí)中摻插做其他動(dòng)作
        DJNZ    R4,D3
        DJNZ    R7,D2
        DJNZ    R6,DELAY        ;決定節拍
        RET
;                 .5   .6     .7    1
TABLE1: DW      65111,65150,65199,65217   ;4M晶振時(shí)的定時(shí)中斷時(shí)間常數
;                  2    3     4     5     ;若采用其它頻率,則要根據樂(lè )音的
        DW      65252,65283,65297,65323   ;頻率計算,例中央C的A音為440Hz,
;                  6    7     1`    2`    ;440Hz=2.273ms,把T0設置為2.273ms
        DW      65347,65367,65377,65394   ;中斷即可發(fā)出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                                                *
;*-------------------------------------------------------------*
;* 樂(lè )譜格式  每字節的高字節為音符代碼,低字節為節拍代碼         *
;*-------------------------------------------------------------*
;* 例子:        ⑴  ⑵  ⑶  ⑷  ⑸  ⑹  ⑺  ⑻  ⑼  ⑽  ⑾     *
;*      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→樂(lè )曲結束                                       *
;***************************************************************
;
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
作者: laber    時(shí)間: 2011-12-6 12:31
NB!
作者: sfjugg    時(shí)間: 2012-10-8 19:54
厲害
作者: maizchen    時(shí)間: 2012-12-1 11:15
匯編的,牛,可惜樓主要C的
作者: xxlwsj    時(shí)間: 2012-12-4 18:22
主要就是打開(kāi)Speaker端口,延時(shí)關(guān)閉
作者: wang.ass    時(shí)間: 2013-1-8 21:29

作者: tt98    時(shí)間: 2013-2-28 08:24
看不懂匯編的路過(guò)!
作者: cyun0223    時(shí)間: 2013-3-7 15:39
有意思
作者: ywzhao1970    時(shí)間: 2013-3-16 21:04
我也想看C的,




歡迎光臨 電子工程網(wǎng) (http://selenalain.com/) Powered by Discuz! X3.4
午夜高清国产拍精品福利|亚洲色精品88色婷婷七月丁香|91久久精品无码一区|99久久国语露脸精品|动漫卡通亚洲综合专区48页