<var id="fnfpo"><source id="fnfpo"></source></var>
<rp id="fnfpo"></rp>

<em id="fnfpo"><object id="fnfpo"><input id="fnfpo"></input></object></em>
<em id="fnfpo"><acronym id="fnfpo"></acronym></em>
  • <th id="fnfpo"><track id="fnfpo"></track></th>
  • <progress id="fnfpo"><track id="fnfpo"></track></progress>
  • <tbody id="fnfpo"><pre id="fnfpo"></pre></tbody>

  • x
    x
    查看: 7500|回復: 9
    打印 上一主題 下一主題

    [提問] 用C語言寫歌曲程序

    [復制鏈接]
    跳轉到指定樓層
    樓主
    發表于 2011-11-29 12:40:59 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
    單片機高手求助,怎樣用C語言編寫歌曲程序?
    沙發
    發表于 2011-12-6 08:04:56 | 只看該作者
    音樂生成器.rar (3.26 MB)    這個可參考一下

    以下是本人一個產品中的音樂單元,用51匯編寫的,很完整,供參考.
    中央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            2.7←"1"
            NOP
            NOP
    STOP0:  NOP
            RET
    STOP1:  NOP
    ;       JB      P3.6,STOP0    ;在軟件延時中摻插做其他動作
    ;       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接至無源蜂鳴器)
            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
    板凳
    發表于 2011-12-6 12:31:15 | 只看該作者
    NB!
    地板
    發表于 2012-10-8 19:54:13 | 只看該作者
    厲害
    地下室
    發表于 2012-12-1 11:15:02 | 只看該作者
    匯編的,牛,可惜樓主要C的
    6
    發表于 2012-12-4 18:22:09 | 只看該作者
    主要就是打開Speaker端口,延時關閉
    7
    發表于 2013-1-8 21:29:35 | 只看該作者
    8
    發表于 2013-2-28 08:24:51 | 只看該作者
    看不懂匯編的路過!
    9
    發表于 2013-3-7 15:39:53 | 只看該作者
    有意思
    10
    發表于 2013-3-16 21:04:40 | 只看該作者
    我也想看C的,
    您需要登錄后才可以回帖 登錄 | 立即注冊

    本版積分規則

    關于我們  -  服務條款  -  使用指南  -  站點地圖  -  友情鏈接  -  聯系我們
    電子工程網 © 版權所有   京ICP備16069177號 | 京公網安備11010502021702
    快速回復 返回頂部 返回列表
    精品一区二区三区自拍图片区_国产成人亚洲精品_亚洲Va欧美va国产综合888_久久亚洲国产精品五月天婷