⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 prog44d.asm

📁 主要是8051源代码
💻 ASM
字号:
;  PROG44d - Play Multiple Songs  
;
;  Simple Application to Run Through Each Tone Twice a Second
;
;  This Application after power up, Sets up Timer 0 to Interrupt at
;   880 Hz and Outputs a 440 Hz Tone, Waits one Second and then Goes
;   to the Next Tone Up, Up to "HighD"
;
;  Myke Predko
;  98.05.30
;
;  Hardware Notes:
;  AT89C2051 is used as the Microcontroller
;   - Oscillator Speed is 1.8432 MHz
;  P3.7 is Connected to a 8 Ohm Speaker Through 0.47 uF Cap

;  Constant Declarations
NLA  EQU 81                     ;  A  -  880 Hz
NLAS EQU 91                     ;  A# -  932 Hz
NLB  EQU 101                    ;  B  -  988 Hz
NLC  EQU 109                    ;  C  - 1046 Hz
NLCS EQU 117                    ;  C# - 1108 Hz
NLD  EQU 125                    ;  D  - 1174 Hz
NLDS EQU 133                    ;  D# - 1249 Hz
NLE  EQU 139                    ;  E  - 1318 Hz
NLF  EQU 146                    ;  F  - 1396 Hz
NLFS EQU 152                    ;  F# - 1480 Hz
NLG  EQU 158                    ;  G  - 1568 Hz
NLGS EQU 164                    ;  G# - 1662 Hz
NHA  EQU 169                    ;  A  - 1760 Hz
NHAS EQU 174                    ;  A# - 1873 Hz
NHB  EQU 178                    ;  B  - 1976 Hz
NHC  EQU 183                    ;  C  - 2094 Hz
NHCS EQU 187                    ;  C# - 2218 Hz
NHD  EQU 191                    ;  D  - 2350 Hz

;  Note Offset Table
LA  EQU 1                       ;  A  -  880 Hz
LAS EQU 2                       ;  A# -  932 Hz
LB  EQU 3                       ;  B  -  988 Hz
LC  EQU 4                       ;  C  - 1046 Hz
LCS EQU 5                       ;  C# - 1108 Hz
LD  EQU 6                       ;  D  - 1174 Hz
LDS EQU 7                       ;  D# - 1249 Hz
LE  EQU 8                       ;  E  - 1318 Hz
LF  EQU 9                       ;  F  - 1396 Hz
LFS EQU 10                      ;  F# - 1480 Hz
LG  EQU 11                      ;  G  - 1568 Hz
LGS EQU 12                      ;  G# - 1662 Hz
HA  EQU 13                      ;  A  - 1760 Hz
HAS EQU 14                      ;  A# - 1873 Hz
HB  EQU 15                      ;  B  - 1976 Hz
HC  EQU 16                      ;  C  - 2094 Hz
HCS EQU 17                      ;  C# - 2218 Hz
HD  EQU 18                      ;  D  - 2350 Hz

;  Variable Declarations
;  R0 - Note Delay Timer
;  R1 - Next Song Value
;  R2 - Note Beat Count
;  R3 - Current Song
Flags EQU 020h                  ;  Bit 0 Is Set for a "Pause"
                                ;  Bit 1 Is Set for "Done"


;  Macros
MACRO Note (Value,Duration)
  db      (Value+(Duration SHL 5))
ENDMAC


;  Mainline
 org 0                          ;  Execution Starts Here
  ajmp    Mainline

 org 00Bh                       ;  Timer0 Interrupt
Timer0:

  jb      0,Timer0End           ;  If a Pause, Don't Trigger the Timer

  cpl     P3.7                  ;  Toggle the Timer

Timer0End:

  reti

 org 01Bh
Timer1:                         ;  Interrupt Every 0.02 Seconds

  djnz    R0,Timer1End          ;  If Not Zero, Then Don't Change Note

  mov     R0,#4                 ;  Reset the Delay Timer

  djnz    R2,Timer1End          ;  Decrement the Beat Counter

  inc     R1                    ;  Point to the Next Value

  mov     A,R1                  ;  Get the Next Note             
  acall   GetTune               ;  Get the Tune in R3
  jz      TuneEnd               ;  Are we at the End of the Tune?

  mov     B,A                   ;  Save the Note Value

  anl     A,#0E0h               ;  Save the Delay Bits
  swap a
  rr a
  mov     R2,A                  ;  Save the Delay Value

  mov     A,B                   ;  Now, Get the Note
  anl     A,#01Fh
  clr     0                     ;  Can we Output the Note?
  acall   GetNote
  mov     TL0,A                 ;   Save the Next Note
  mov     TH0,A

  jnz     Timer1End             ;  If Zero Returned, Then a Pause

  setb    0                     ;  Indicate the Pause

Timer1End:                      ;  Timer1 Interrupt Handler Finished

  reti

TuneEnd:                        ;  At the End of the Tune

  setb    0                     ;  Mark This as a "Pause"
  setb    1                     ;  Indicate that the Tune Has Ended

  mov     R2,#1                 ;  Just One Beat for the Pause

  reti


MainLine:                       ;  Mainline of the Program

  mov     R0,#4                 ;  R0 is the Beat Timer

  mov     R1,#0FFh              ;  R1 is the Note Counter

  mov     R3,#0                 ;  Start with Frosty

  setb    0                     ;  Start with a Pause

  mov     R2,#1                 ;  Very Short Pause

  mov     TMOD,#%00000010       ;  Run Timer0 in Mode 2 and Timer1 in Mode 1
  mov     TH0,#0                ;  Enable the Timer to Reload at Maximum Speed  
  mov     TL0,#0
  orl     TCON,#050h            ;  Enable Timer0 to Run

  mov     IE,#%10001010         ;  Enable Timer0 Interrupt

Loop1:                          ;  Play Frosty
  jnb     1,Loop1               ;  Have We Finished Yet?

  clr     1                     ;  Clear the "Ending" Loop

  mov     R1,#0FFh
  mov     R3,#1                 ;  Now, Play "Ode to Joy"

Loop2:                          ;  Play "Ode to Joy"
  jnb     1,Loop2

  mov     IE,#0                 ;  Turn Off the Interrupts

Loop:
  ajmp    Loop


GetTune:                        ;  According to R3, Get the Correct Tune

  push    ACC                   ;  Save the Tune Value

  mov     DPTR,#TuneTable

  mov     A,R3                  ;  Get the Song to Play
  rl a

  jmp @A+DPTR                   ;  Jump to the Correct Song Subroutine

TuneTable:

  ajmp    GetFrosty             ;  Frosty the Snowman
  ajmp    GetDuckie             ;  Rubber Duckie
  ajmp    GetOde                ;  "Ode to Joy"


GetNote:                        ;  Return the Note Value for the Index in "A"

  add     A,#(NoteTable-InitNoteTable)  ;  Restore the Table Position with Note
  movc A,@A+PC			;  Get the Table Value
InitNoteTable:			;  Table Offset to Display

  ret

NoteTable:                      ;  Table of Notes
  db      0                     ;  First Value is a "Pause"
  db      NLA
  db      NLAS
  db      NLB
  db      NLC
  db      NLCS
  db      NLD
  db      NLDS
  db      NLE
  db      NLF
  db      NLFS
  db      NLG
  db      NLGS
  db      NHA
  db      NHAS
  db      NHB
  db      NHC
  db      NHCS
  db      NHD


GetFrosty:                      ;  Return the Note Value for "Frosty the Snowman"

  pop     ACC                   ;  Restore the Offset into the Tune

  add     A,#(FrostyTable-InitFrostyTable)  ;  Restore the Table Position with Note
  movc A,@A+PC			;  Get the Table Value
InitFrostyTable:		;  Table Offset to Display

  ret

FrostyTable:                    ;  Frosty the Snowman
  Note (LG,4)                   ;  Finally, Play "Frosty"
  Note (LE,3)
  Note (LF,1)
  Note (LG,2)
  Note (HC,4)
  Note (HB,1)
  Note (HC,1)
  Note (HD,2)
  Note (HC,2)
  Note (HB,2)
  Note (HA,2)
  Note (LG,6)
  Note (HB,1)
  Note (HC,1)
  Note (HD,2)
  Note (HC,2)
  Note (HB,2)
  Note (HA,1)
  Note (HA,1)
  Note (LG,2)
  Note (HC,2)
  Note (LE,2)
  Note (LG,1)
  Note (HA,1)
  Note (LG,2)
  Note (LF,2)
  Note (LE,2)
  Note (LF,2)
  Note (LG,6)
  Note (LC,2)
  Note (HA,2)
  Note (HA,2)
  Note (HC,2)
  Note (HC,2)
  Note (HB,2)
  Note (HA,2)
  Note (LG,2)
  Note (LE,2)
  Note (LF,2)
  Note (HA,2)
  Note (LG,2)
  Note (LF,2)
  Note (LE,6)
  Note (LE,2)
  Note (LD,2)
  Note (LD,2)
  Note (LG,2)
  Note (LG,2)
  Note (HB,2)
  Note (HB,2)
  Note (HD,2)
  Note (HD,1)
  Note (HB,1)
  Note (HD,2)
  Note (HC,2)
  Note (HB,2)
  Note (HA,2)
  Note (LG,4)
  Note (LG,4)
  db      0     ;  End of the Tune


GetOde:                         ;  Beethoven's "Ode to Joy"

  pop     ACC                   ;  Restore the Offset into the Tune

  add     A,#(OdeTable-InitOdeTable)  ;  Restore the Table Position with Note
  movc A,@A+PC			;  Get the Table Value
InitOdeTable:                   ;  Table Offset to Display

  ret

OdeTable:                       ;  "Ode to Joy"
  Note (LC,2)
  Note (LD,2)
  Note (LE,2)
  Note (LE,2)
  Note (LD,2)
  Note (LC,2)
  Note (LB,2)
  Note (LA,2)
  Note (LA,2)
  Note (LB,2)
  Note (LC,2)
  Note (LC,2)
  Note (LB,2)
  Note (LB,2)
  Note (LC,2)
  Note (LC,2)
  Note (LD,2)
  Note (LE,2)
  Note (LE,4)
  Note (LD,2)
  Note (LC,2)
  Note (LB,2)
  Note (LA,2)
  Note (LA,2)
  Note (LB,2)
  Note (LC,2)
  Note (LB,2)
  Note (LA,2)
  Note (LA,4)
  db      0     ;  End of the Tune


GetDuckie:                      ;  Ernie's "Rubber Duckie"

  pop     ACC                   ;  Restore the Offset into the Tune

  add     A,#(DuckieTable-InitDuckieTable)  ;  Restore the Table Position with Note
  movc A,@A+PC			;  Get the Table Value
InitDuckieTable:                ;  Table Offset to Display

  ret

DuckieTable:                    ;  "Rubber Duckie"
  Note (LD,2)
  Note (LCS,2)
  Note (LD,2)
  Note (LF,6)
  Note (LE,4)
  Note (HAS,3)
  Note (HA,5)
  Note (0,2)
  Note (LF,2)
  Note (LE,2)
  Note (LF,2)
  Note (LFS,2)
  Note (LG,4)
  Note (HD,3)
  Note (HC,5)
  Note (0,2)
  Note (HAS,2)
  Note (HA,2)
  Note (HAS,2)
  Note (LF,2)
  Note (LD,2)
  Note (LDS,2)
  Note (LF,2)
  Note (LDS,2)
  Note (LD,2)
  Note (LC,2)
  Note (LC,2)
  Note (LF,8)
  db      0     ;  End of the Tune

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -