汇编写的音乐播放器

微原第三次实验

刚转了一个汇编播放器的博客,后面发现需要移植的东西比较多,那个就当学习了,提示信息很全面,人机交互比较好。

 

实验前预习的时候参考这个写了一个欢乐颂的程序,实验时改成最炫民族风了,结果忘拷贝回来,只好把原版的代码发上来。

<1>蜂鸣器的工作方式

以前做单片机蜂鸣器发声的时候,蜂鸣器在三极管的C极,B极接IO口,高电平时候,be之间导通,ce之间通过电流,蜂鸣器振动发声。

这次做的时候,发现需要定时器产生一定频率的波。

用蜂鸣器做音乐发声的比较小,当个提示音就行。

汇编写的音乐播放器_第1张图片

 

<2>算出低中高音的频率,通过输出频率给蜂鸣器来发出不同的声音。

<3>需要一段乐谱

<4>每个音符之后有一定的间隔,也就是延时

<5>每个音符播放出后进入键盘中断,若有键按下则退出。

<6>开始播放时会讲这时需要播放的乐符的频率送入蜂鸣器,加延时后播放下一个,需要计算乐符的长度。

 

DATA SEGMENT
    ;Count number
    LOU  DB 122,108,97,91,81,72,64                       ;三种音调段的频率
    MID  DB 61,54,48,45,40,36,32
    HIG  DB 30,27,24,22,20,18,16
    ;Song huanlesong
    BOK  DB 3,3,4,5,5,4,3,2,1,1,2,3,3,2,2                ;乐谱
  DB 3,3,4,5,5,4,3,2,1,1,2,3,2,1,1
  DB 2,2,3,1,2,3,4,3,1,2,3,4,3,2,1,2,5,3
                DB 3,3,4,5,5,4,3,2,1,1,2,3,2,1,1
    LEN EQU $-BOK  ;How many chars.                  ;长度
    ;TON 1-LOW,2-MID,3-HIG
    TON  DB 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2                        ;音调段的选择
  DB 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
  DB 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2
                DB 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
   ;RHY 1-Quarter beat;2-Half beat
   ;4-One beat;8-Two beat;12-Three beat.
    RHY  DB 4,4,4,4,4,4,4,4,4,4,4,4,4,2,2                      ;延时比例
  DB 4,4,4,4,4,4,4,4,4,4,4,4,4,2,2
  DB 4,4,4,4,4,2,2,4,4,4,2,2,4,4,4,4,4,4
                DB 4,4,4,4,4,4,4,4,4,4,4,4,4,2,2
    KEY  DB 21H,0F4H,0F1H,39H,0D9H,0DDH,61H; 0~7 char code
    TBOK DB 0
    TTON DB 0                                           ;暂存
    TRHY DB 0
    COUNT DB 0
DATA ENDS
;-------------------------------------------------------------
STACK SEGMENT  STACK  'STACK' 
    DB 50 DUP(?)
STACK ENDS
;-------------------------------------------------------------
CODE SEGMENT
    ASSUME DS:DATA,CS:CODE,SS:STACK 
;-------------------------------------------------------------
DELAY MACRO TIME          ;Delay time
      LOCAL LOPA                              
      PUSH CX
      MOV AX,TIME  ;User can control time
LOPA: MOV CX,00H
      LOOP $
      DEC AX  
      JNZ LOPA  
      POP CX
ENDM
;-------------------------------------------------------------
MUSIC MACRO   ;Write count number, music on
     MOV AL,COUNT  ;First get count number.
     MOV DX,0E820H  ;Use Counter 0
     OUT DX,AL   ;Write counter 0
ENDM
;------------------------------------------------------------- 
READ PROC  NEAR   ;Read one note/rhyme/tone
     ;BX is offset, means where to find
     ;Result is saved in memory
     MOV AL,BOK[BX]
     XOR AH,AH
     MOV SI,AX
     DEC SI
     MOV TBOK,AL   ;Save note
     MOV AL,RHY[BX]
     MOV TRHY,AL   ;Save rhyme
     MOV AL,TON[BX]
     CMP AL,1
     JE  ISLOW
     CMP AL,2
     JE  ISMID
     CMP AL,3
     JE  ISHIG
ISLOW:MOV AL,LOU[SI]  ; To find counter
      JMP EXITR
ISMID:MOV AL,MID[SI]
      JMP EXITR
ISHIG:MOV AL,HIG[SI]
EXITR:MOV COUNT,AL      ;Save count value
      RET              
READ ENDP
;------------------------------------------------------------- 
RHYME PROC  NEAR   ;Control rhyme
      MOV AL,TRHY
      MOV AH,0FFH  ;AH is time of Quarter beat
      MUL AH
      DELAY AX   ;Rhyme, delay time in AX
      RET
RHYME ENDP
;-------------------------------------------------------------
DISP PROC NEAR   ;Display note being played
     MOV DX,0E800H                                              
     MOV AL,BOK[BX]  ;Get note char
     XOR AH,AH
     MOV DI,AX
     DEC DI
     MOV AL,KEY[DI]  ;Get char code
     OUT DX,AL
     MOV AL,00000001B  ;Only one digit on
     MOV DX,0E801H
     OUT DX,AL       ;Control which LED on
    RET
DISP ENDP       
;------------------------------------------------------------- 
MAIN:     ;Main program start here
     MOV AX,DATA
     MOV DS,AX
     MOV ES,AX
     MOV DX,0E823H       ;Initialize 8253
     MOV AL,00010110B    ;Use counter 0
     OUT DX,AL
     MOV AL,80H            ;initialize 8255
     MOV DX,0E803H
     OUT DX,AL
    
PLAY:MOV CX,LEN          ;Get book's length
     XOR BX,BX    ;Record current char being played
LOP: CALL READ   ;Read note/rhyme/tone
     CALL DISP   ;Display note on LED
     MUSIC    ;Play music now
     CALL RHYME   ;Control rhyme
     INC BX   ;Next note
     MOV AH, 0BH   ;Test keyboard                          ;键盘中断
     INT 21H
     OR AL, AL
     JNZ OVER   ;Keyboard pressed, quit program

LOOP LOP
OVER:MOV DX, 0E823H  ;Reset 8253A
     MOV AL, 16H
     OUT DX, AL
     MOV AX,4C00H  ;Back to DOS
     INT 21H
;-------------------------------------------------------------  
CODE ENDS
    END MAIN

你可能感兴趣的:(【汇编】)