USA National Anthem Song Code

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

USA National Anthem Song Code

1,340 Views
wolfgang_b
Contributor II

Hello everyone, could someone help me fix this song code?  I use D-Bug12 on a HC9S12 Minidragon+.  This is an example code from the Han-Way Huang Interfacing book.  The first note is in an infinite loop.  Thanks.

 


TSCR1           equ     $0046
TSCR2           equ     $004D
TIOS            equ     $0040
TCNT            equ     $0044
TCTL1           equ     $0048
TC5             equ     $005A
TIE             equ     $004C
TC0             equ     $0050
TFLG1           equ     $004E
OC5             equ     $20
UserTimerCh5    equ     $3E64
OC4                equ        $10
OC0             equ     $00
DDRB            equ     $0003


G3                equ        7653        ; delay count to generate G3 note (with 1:8 prescaler)
B3                equ        6074        ; delay count to generate B3 note (with 1:8 prescaler)
C4                 equ        5733        ; delay count to generate C4 note (with 1:8 prescaler)
C4S                equ        5412        ; delay count to generate C4S note
D4                 equ        5108        ;;;;;;experiment; delay count to generate D4 note (with 1:8 prescaler)
E4                 equ        4551        ; delay count to generate E4 note (with 1:8 prescaler)
F4                 equ        4295        ; delay count to generate F4 note (with 1:8 prescaler)
F4S                equ        4054        ; delay count to generate F4S note (with 1:8 prescaler)
G4                 equ        3827        ; delay count to generate G4 note (with 1:8 prescaler)
A4                 equ        3409        ; delay count to generate A4 note (with 1:8 prescaler)
B4F                 equ        3218        ; delay count to generate B4F note (with 1:8 prescaler)
B4                equ        3037        ; delay count to generate B4 note (with 1:8 prescaler)
C5         equ        2867        ; delay count to generate C5 note (with 1:8 prescaler)
D5         equ        2554        ; delay count to generate D5 note (with 1:8 prescaler)
E5         equ        2275        ; delay count to generate E5 note (with 1:8 prescaler)
F5         equ        2148        ; delay count to generate F5 note (with 1:8 prescaler)
ZZ                equ        20        ; delay count to generate an inaudible note
notes        equ        118
toggle          equ          $04     ; value to toggle the TC5 pin

                        org          $1000
delay                   dw         1       ; store the delay for output compare operation
rep_cnt        db        1        ; repeat the song this many times
ip                db        1        ; remaining notes to be played
                org          $1500
; establish the SRAM vector address for OC5
        lds          #$1500
        movw        #oc5_isr,UserTimerCh5
        ;movb           #$0000,delay
        ;movb        #$FF,DDRB
        movb         #$90,TSCR1            ; enable TCNT, fast timer flag clear
        movb         #$03,TSCR2            ; set main timer prescaler to 8
        bset         TIOS,OC5              ; enable OC5
        movb         #toggle,TCTL1         ; select toggle for OC5 pin action
        ldx        #score        ; use as a pointer to score table
        ldy        duration,delay        ; points to duration table
        movb        #1,rep_cnt        ; play the song twice
        movb        #notes,ip
        movw        2,x+,delay        ; start with 0th note
        ldd        TCNT        ; play the first note
        addd        delay        ;        "
        std        TC5        ;        "
        bset         TIE,OC5              ; enable OC5 interrupt
     cli                        ;       "
forever     pshy                ; save duration table pointer in stack
        ldy          0,y              ; get the duration of the current note
        jsr          delayby10ms           ;       "
        puly                          ; get the duration pointer from stack
        iny                ; move the duration pointer
        iny                ;        "
        ldd        2,x+        ; get the next note, move pointer
        std        delay        ;        "
        dec        ip
        bne        forever
        dec        rep_cnt
        beq        done        ; if not finished playing, re-establish
        ldx        #score        ; pointers and loop count
        ldy        #duration        ;        "
        movb        #notes,ip        ;        "
        movw        0,x,delay        ; get the first note delay count
        ldd        TCNT        ; play the first note
        addd        delay        ;         "
        std        TC5
        bra          forever
done        swi
; *******************************************************************************************
; The OC5 interrupt service routine simply starts a new OC5 operation.
; *******************************************************************************************
oc5_isr ldd          TC5
        addd         delay
        std          TC5
        rti
; *******************************************************************************************
; The following subroutine creates a time delay which is equal to [Y] times
; 10 ms. The timer prescaler is 1:8.
; *******************************************************************************************
delayby10ms
        pshd
        bset        TIOS,OC0        ; enable OC0
        ldd         TCNT
again1  addd        #30000        ; start an output compare operation
        std        TC0        ; with 10-ms time delay    ;0
        brclr        tflg1,$01,*      ;brclr
        ldd        TC0                      ;0
        dbne        y,again1
        bclr        TIOS,OC0           ; disable OC0
        puld
        rts
; ***********************************************************************************************
; This table determines the frequency of each note.
; ***********************************************************************************************
score   dw        D4,B3,G3,B3,D4,G4,B4,A4,G4,B3,C4S
        dw        D4,ZZ,D4,ZZ,D4,B4,A4,G4,F4S,E4,F4S,G4,ZZ,G4,D4,B3,G3
        dw        D4,B3,G3,B3,D4,G4,B4,A4,G4,B3,C4S,D4,ZZ,D4,ZZ,D4
        dw        B4,A4,G4,F4S,E4,F4S,G4,ZZ,G4,D4,B3,G3,B4,ZZ,B4
        dw        B4,C5,D5,ZZ,D5,C5,B4,A4,B4,C5,ZZ,C5,ZZ,C5,B4,A4,G4
        dw        F4S,E4,F4S,G4,B3,C4S,D4,ZZ,D4,G4,ZZ,G4,ZZ,G4,F4S
        dw        E4,ZZ,E4,ZZ,E4,A4,C5,B4,A4,G4,ZZ,G4,F4S,D4,ZZ,D4
        dw        G4,A4,B4,C5,D5,G4,A4,B4,C5,A4,G4
; ***********************************************************************************************
; Each of the following entries multiplied by 10 ms gives the duration of a note.
; ***********************************************************************************************
duration
        dw        30,10,40,40,40,80,30,10,40,40,40
        dw        80, 3,20,3,20,60,20,40,80,20,20,40,3,40,40,40,40
        dw        30,10,40,40,40,80,30,10,40,40,40,80,3,20,3,20
        dw        60,20,40,80,20,20,40,3,40,40,40,40,20,3,20
        dw        40,40,40,3,80,20,20,40,40,40,3,80,3,40,60,20,40
        dw         80,20,20,40,40,40,80,3,40,40,3,40,3,20,20
        dw        40, 3,40,3,40,40,20,20,20,20,3,40,40,20,3,20
        dw        60,20,20,20,80,20,20,60,20,40,80
        end

Labels (1)
0 Kudos
Reply
4 Replies

873 Views
Lundin
Senior Contributor IV

How are you setting up interrupts? What compiler are you using?

0 Kudos
Reply

873 Views
wolfgang_b
Contributor II

I am just an ameture.  Interupts are my weakest subject.  I use asmide.

0 Kudos
Reply

873 Views
Lundin
Senior Contributor IV

The code provided uses an interrupt. service routine You must make sure that the the address of this interrupt service routine ends up at the correct place in the interrupt vector table. How this is done for your particular IDE, I don't know.

0 Kudos
Reply

873 Views
wolfgang_b
Contributor II

Well embarassingly after the third time looking at it, I believe the errors were due to my self-sabotage.  Perhaps choosing address instead of constant for duration.  It is shamefull that I don't know how I fixed it.  For anyone interested, here it is:

 

 

 


TSCR1           equ     $0046
TSCR2           equ     $004D
TIOS            equ     $0040
TCNT            equ     $0044
TCTL1           equ     $0048
TC5             equ     $005A
TIE             equ     $004C
TC0             equ     $0050
TFLG1           equ     $004E
OC5             equ     $20
UserTimerCh5    equ     $3E64
OC4                equ        $10
OC0             equ     $00
DDRB            equ     $0003


G3                equ        7653        ; delay count to generate G3 note (with 1:8 prescaler)
B3                equ        6074        ; delay count to generate B3 note (with 1:8 prescaler)
C4                 equ        5733        ; delay count to generate C4 note (with 1:8 prescaler)
C4S                equ        5412        ; delay count to generate C4S note
D4                 equ        5108        ;;;;;;experiment; delay count to generate D4 note (with 1:8 prescaler)
E4                 equ        4551        ; delay count to generate E4 note (with 1:8 prescaler)
F4                 equ        4295        ; delay count to generate F4 note (with 1:8 prescaler)
F4S                equ        4054        ; delay count to generate F4S note (with 1:8 prescaler)
G4                 equ        3827        ; delay count to generate G4 note (with 1:8 prescaler)
A4                 equ        3409        ; delay count to generate A4 note (with 1:8 prescaler)
B4F                 equ        3218        ; delay count to generate B4F note (with 1:8 prescaler)
B4                equ        3037        ; delay count to generate B4 note (with 1:8 prescaler)
C5         equ        2867        ; delay count to generate C5 note (with 1:8 prescaler)
D5         equ        2554        ; delay count to generate D5 note (with 1:8 prescaler)
E5         equ        2275        ; delay count to generate E5 note (with 1:8 prescaler)
F5         equ        2148        ; delay count to generate F5 note (with 1:8 prescaler)
ZZ                equ        20        ; delay count to generate an inaudible note
notes        equ        118
toggle          equ          $04     ; value to toggle the TC5 pin

                        org          $1000
delay                   dw         1       ; store the delay for output compare operation
rep_cnt        db        1        ; repeat the song this many times
ip                db        1        ; remaining notes to be played
                org          $1500
; establish the SRAM vector address for OC5
        lds          #$1500
        movw        #oc5_isr,UserTimerCh5
        ;movb           #$0000,delay
        ;movb        #$FF,DDRB
        movb         #$90,TSCR1            ; enable TCNT, fast timer flag clear
        movb         #$03,TSCR2            ; set main timer prescaler to 8
        bset         TIOS,OC5              ; enable OC5
        movb         #toggle,TCTL1         ; select toggle for OC5 pin action
        ldx        #score        ; use as a pointer to score table
        ldy        #duration,delay        ; points to duration table
        movb        #1,rep_cnt        ; play the song twice
        movb        #notes,ip
        movw        2,x+,delay        ; start with 0th note
        ldd        TCNT        ; play the first note
        addd        delay        ;        "
        std        TC5        ;        "
        bset         TIE,OC5              ; enable OC5 interrupt
         cli                        ;       "
forever         pshy                ; save duration table pointer in stack
        ldy          0,y              ; get the duration of the current note
        jsr          delayby10ms           ;       "
        puly                          ; get the duration pointer from stack
        iny                ; move the duration pointer
        iny                ;        "
        ldd        2,x+        ; get the next note, move pointer
        std        delay        ;        "
        dec        ip
        bne        forever
        dec        rep_cnt
        beq        done        ; if not finished playing, re-establish
        ldx        #score        ; pointers and loop count
        ldy        #duration        ;        "
        movb        #notes,ip        ;        "
        movw        0,x,delay        ; get the first note delay count
        ldd        TCNT        ; play the first note
        addd        delay        ;         "
        std        TC5
        bra          forever
done        swi
; *******************************************************************************************
; The OC5 interrupt service routine simply starts a new OC5 operation.
; *******************************************************************************************
oc5_isr ldd          TC5
        addd         delay
        std          TC5
        rti
; *******************************************************************************************
; The following subroutine creates a time delay which is equal to [Y] times
; 10 ms. The timer prescaler is 1:8.
; *******************************************************************************************
delayby10ms
        pshd
        bset        TIOS,$01        ; enable OC0
        ldd         TCNT
again1  addd        #30000        ; start an output compare operation
        std        TC0        ; with 10-ms time delay    ;0
        brclr        tflg1,$01,*      ;brclr
        ldd        TC0                      ;0
        dbne        y,again1
        bclr        TIOS,$01           ; disable OC0
        puld
        rts
; ***********************************************************************************************
; This table determines the frequency of each note.
; ***********************************************************************************************
score   dw        D4,B3,G3,B3,D4,G4,B4,A4,G4,B3,C4S
        dw        D4,ZZ,D4,ZZ,D4,B4,A4,G4,F4S,E4,F4S,G4,ZZ,G4,D4,B3,G3
        dw        D4,B3,G3,B3,D4,G4,B4,A4,G4,B3,C4S,D4,ZZ,D4,ZZ,D4
        dw        B4,A4,G4,F4S,E4,F4S,G4,ZZ,G4,D4,B3,G3,B4,ZZ,B4
        dw        B4,C5,D5,ZZ,D5,C5,B4,A4,B4,C5,ZZ,C5,ZZ,C5,B4,A4,G4
        dw        F4S,E4,F4S,G4,B3,C4S,D4,ZZ,D4,G4,ZZ,G4,ZZ,G4,F4S
        dw        E4,ZZ,E4,ZZ,E4,A4,C5,B4,A4,G4,ZZ,G4,F4S,D4,ZZ,D4
        dw        G4,A4,B4,C5,D5,G4,A4,B4,C5,A4,G4
; ***********************************************************************************************
; Each of the following entries multiplied by 10 ms gives the duration of a note.
; ***********************************************************************************************
duration
        dw        30,10,40,40,40,80,30,10,40,40,40
        dw        80, 3,20,3,20,60,20,40,80,20,20,40,3,40,40,40,40
        dw        30,10,40,40,40,80,30,10,40,40,40,80,3,20,3,20
        dw        60,20,40,80,20,20,40,3,40,40,40,40,20,3,20
        dw        40,40,40,3,80,20,20,40,40,40,3,80,3,40,60,20,40
        dw         80,20,20,40,40,40,80,3,40,40,3,40,3,20,20
        dw        40, 3,40,3,40,40,20,20,20,20,3,40,40,20,3,20
        dw        60,20,20,20,80,20,20,60,20,40,80
        end

0 Kudos
Reply