[ บทความ : ตัวอย่างสำหรับ 68HC11 V2 ตอนที่ 11 ] ทดสอบติดต่อกับ Output Compare(OCX) เพื่อสร้างเสียงดนตรี

ตัวอย่างซอร์สโค้ดสำหรับติดต่อกับระบบ Output Compare(OCX) เพื่อสร้างเสียงดนตรี กับบอร์ด CP-68HC11 V2 สำหรับการเขียนเพื่อเป็นโปรแกรมมอนิเตอร์เป็นดังนี้


;/**********************************/;
;/* Demo Program For OutputCompare */;
;/*    Timer Run Interrupt Mode    */;
;/* Used OCX : Generate Music Note */;
;/* Hardware : ET-CP68HC11 Ver 2.0 */;
;/* Complier : AS11NEW.EXE (V1.03) */;
;/**********************************/;
;
;/***************************/;
;/*** I/O Register Equate ***/;
;/***************************/;
;
IOREGS      EQU     $1000               ; Start of I/O Register
PORTA       EQU     IOREGS+$00          ; I/O Port-A
PIOC        EQU     IOREGS+$02          ; I/O Control Register
PORTC       EQU     IOREGS+$03          ; I/O Port-C
PORTB       EQU     IOREGS+$04          ; I/O Port-B
PORTCL      EQU     IOREGS+$05          ; I/O Control Register
DDRC        EQU     IOREGS+$07          ; Data Direction Register-C
PORTD       EQU     IOREGS+$08          ; I/O Port-D
DDRD        EQU     IOREGS+$09          ; Data Direction Register-D
PORTE       EQU     IOREGS+$0A          ; I/O Port-E
CFORC       EQU     IOREGS+$0B          ; Force Output Compare
OC1M        EQU     IOREGS+$0C          ; OC1 Mask Bits
OC1D        EQU     IOREGS+$0D          ; OC1 Data Bits??
TCNT        EQU     IOREGS+$0E          ; Timer Count Register
TIC1        EQU     IOREGS+$10          ; Input Capture #1
TIC2        EQU     IOREGS+$12          ; Input Capture #2
TIC3        EQU     IOREGS+$14          ; Input Capture #3
TOC1        EQU     IOREGS+$16          ; Output Compare #1
TOC2        EQU     IOREGS+$18          ; Output Compare #2
TOC3        EQU     IOREGS+$1A          ; Output Compare #3
TOC4        EQU     IOREGS+$1C          ; Output Compare #4
TOC5        EQU     IOREGS+$1E          ; Output Compare #5
TCTL1       EQU     IOREGS+$20          ; Timer Control Register #1
TCTL2       EQU     IOREGS+$21          ; Timer Control Register #2
TMSK1       EQU     IOREGS+$22          ; Timer Mask #1
TFLG1       EQU     IOREGS+$23          ; Timer Flags #1
TMSK2       EQU     IOREGS+$24          ; Timer Mask #2
TFLG2       EQU     IOREGS+$25          ; Timer Flags #2
PACTL       EQU     IOREGS+$26          ; Pulse Accum Control
PACNT       EQU     IOREGS+$27          ; Pulse Accum Counter
SPCR        EQU     IOREGS+$28          ; SPI Control Register
SPSR        EQU     IOREGS+$29          ; SPI Status Register
SPDR        EQU     IOREGS+$2A          ; SPI Data Register
BAUD        EQU     IOREGS+$2B          ; Baudrate Register
SCCR1       EQU     IOREGS+$2C          ; SCI Register 1
SCCR2       EQU     IOREGS+$2D          ; SCI Register 2
SCSR        EQU     IOREGS+$2E          ; SCI Status Register
SCDR        EQU     IOREGS+$2F          ; SCI Data Register
ADCTL       EQU     IOREGS+$30          ; A/D Control Register
ADR1        EQU     IOREGS+$31          ; A/D Result 1
ADR2        EQU     IOREGS+$32          ; A/D Result 2
ADR3        EQU     IOREGS+$33          ; A/D Result 3
ADR4        EQU     IOREGS+$34          ; A/D Result 4
OPTION      EQU     IOREGS+$39          ; Option Register
COPRST      EQU     IOREGS+$3A          ; COP Reset Register
PPROG       EQU     IOREGS+$3B          ; EEPROM Programming Register
HPRIO       EQU     IOREGS+$3C          ; Highest-Priority Register
INIT        EQU     IOREGS+$3D          ; Memory Map Initialization
TEST1       EQU     IOREGS+$3E          ; Test Register 1
CONFIG      EQU     IOREGS+$3F          ; System Configuration

            ORG     $2000
SONG_PTR    RMB     2                   ; Music Note Pointer
SONG_CNT    RMB     2                   ; Song Delay Count
NOTE_CNT    RMB     1                   ; Note/Output Count
OC1_STAS    RMB     1                   ; PA7 Status
;
FREQ_CNT    RMB     2                   ; Timer 1/2 Cycle Count
FREQ_OC1    RMB     2
FREQ_OC2    RMB     2
FREQ_OC3    RMB     2
FREQ_OC4    RMB     2
FREQ_OC5    RMB     2

            ORG     $A000               ; Start of code
MAIN        LDS     #$9FFF              ; Initial Stack on RAM 32KB
            LDD     #0                  ; SONG_CNT = 0
            STD     SONG_CNT
            LDAB    TMSK2
            ORAB    #%01000000          
            STAB    TMSK2               ; Enable RTI Interrupt
            LDAB    #%01000000
            STAB    TFLG2               ; Clear RTIF Flag
            ;
            LDAB    TMSK1
            ORAB    #%11111000
            STAB    TMSK1               ; Enable OC1I-OC5I
            LDAB    #%11111000
            STAB    TFLG1               ; Clear OC1F-OC5F
            LDAB    #%00000000
            STAB    TCTL1               ; Disconnect OC2-OC5 Pin
            LDAB    PACTL
            ORAB    #%10000000
            STAB    PACTL               ; PA7 = Output
            CLI                         ; Enable Global Interrupt
            ;
NEW_SONG    LDAB    #%11111000
            STAB    TFLG1               ; Clear OC1F-OC5F
            LDD     #0                  ; Start 1st Music Note
            STD     SONG_PTR
            ;
            LDAB    #8
            STAB    NOTE_CNT            ; 8-Note on OC5(PA3)
            ;
SONG_OC5    JSR     GET_NOTE            ; Get Note & Delay
            LDD     FREQ_CNT
            STD     FREQ_OC5
            LDD     FREQ_OC5            ; FREQ_OC5 = 0 ?
            CPD     #0
            BNE     ENA_OC5
            JMP     DIS_OC5
            ;
ENA_OC5     LDD     TCNT
            ADDD    FREQ_OC5
            STD     TOC5
            LDAB    TCTL1
            ORAB    #%00000001
            STAB    TCTL1               ; Toggle OC5 Pin
            JMP     CHK_OC5
            ;
DIS_OC5     CLRB                        ; No Active Output
            STAB    TCTL1               ; Disconnect OC2-5
            STAB    OC1M                ; Disconnect PA7
            STAB    OC1D                ; PA7 = 0
            ;
CHK_OC5     LDD     SONG_CNT            ; Loop Until SONG_CNT = 0
            CPD     #0
            BNE     CHK_OC5
            DEC     NOTE_CNT
            BNE     SONG_OC5
            ;
            LDAB    #8
            STAB    NOTE_CNT            ; 8-Note on OC4(PA4)
            ;
SONG_OC4    JSR     GET_NOTE            ; Get Note & Delay
            LDD     FREQ_CNT
            STD     FREQ_OC4
            LDD     FREQ_OC4            ; FREQ_OC4 = 0 ?
            CPD     #0
            BNE     ENA_OC4
            JMP     DIS_OC4
            ;
ENA_OC4     LDD     TCNT
            ADDD    FREQ_OC4
            STD     TOC4
            LDAB    TCTL1
            ORAB    #%00000100
            STAB    TCTL1               ; Toggle OC4 Pin
            JMP     CHK_OC4
            ;
DIS_OC4     CLRB                        ; No Active Output
            STAB    TCTL1               ; Disconnect OC2-5
            STAB    OC1M                ; Disconnect PA7
            STAB    OC1D                ; PA7 = 0
            ;
CHK_OC4     LDD     SONG_CNT            ; Loop Until SONG_CNT = 0
            CPD     #0
            BNE     CHK_OC4
            DEC     NOTE_CNT
            BNE     SONG_OC4
            ;
            LDAB    #8
            STAB    NOTE_CNT            ; 8-Note on OC3(PA5)
            ;
SONG_OC3    JSR     GET_NOTE            ; Get Note & Delay
            LDD     FREQ_CNT
            STD     FREQ_OC3
            LDD     FREQ_OC3            ; FREQ_OC3 = 0 ?
            CPD     #0
            BNE     ENA_OC3
            JMP     DIS_OC3
            ;
ENA_OC3     LDD     TCNT
            ADDD    FREQ_OC3
            STD     TOC3
            LDAB    TCTL1
            ORAB    #%00010000
            STAB    TCTL1               ; Toggle OC3 Pin
            JMP     CHK_OC3
            ;
DIS_OC3     CLRB                        ; No Active Output
            STAB    TCTL1               ; Disconnect OC2-5
            STAB    OC1M                ; Disconnect PA7
            STAB    OC1D                ; PA7 = 0
            ;
CHK_OC3     LDD     SONG_CNT            ; Loop Until SONG_CNT = 0
            CPD     #0
            BNE     CHK_OC3
            DEC     NOTE_CNT
            BNE     SONG_OC3
            ;
            LDAB    #8
            STAB    NOTE_CNT            ; 8-Note on OC2(PA6)
            ;
SONG_OC2    JSR     GET_NOTE            ; Get Note & Delay
            LDD     FREQ_CNT
            STD     FREQ_OC2
            LDD     FREQ_OC2            ; FREQ_OC2 = 0 ?
            CPD     #0
            BNE     ENA_OC2
            JMP     DIS_OC2
            ;
ENA_OC2     LDD     TCNT
            ADDD    FREQ_OC2
            STD     TOC2
            LDAB    TCTL1
            ORAB    #%01000000
            STAB    TCTL1               ; Toggle OC2 Pin
            JMP     CHK_OC2
            ;
DIS_OC2     CLRB                        ; No Active Output
            STAB    TCTL1               ; Disconnect OC2-5
            STAB    OC1M                ; Disconnect PA7
            STAB    OC1D                ; PA7 = 0
            ;
CHK_OC2     LDD     SONG_CNT            ; Loop Until SONG_CNT = 0
            CPD     #0
            BNE     CHK_OC2
            DEC     NOTE_CNT
            BNE     SONG_OC2
            ;
            LDAB    #8
            STAB    NOTE_CNT            ; 8-Note on OC1(PA7)
            ;
SONG_OC1    JSR     GET_NOTE            ; Get Note & Delay
            LDD     FREQ_CNT
            STD     FREQ_OC1
            LDD     FREQ_OC1            ; FREQ_OC1 = 0 ?
            CPD     #0
            BNE     ENA_OC1
            JMP     DIS_OC1
            ;
ENA_OC1     LDD     TCNT
            ADDD    FREQ_OC1
            STD     TOC1
            LDAB    #%10000000
            STAB    OC1M                ; OC1 Active PA7
            STAB    OC1_STAS            ; Save Status Output
            STAB    OC1D                ; PA7 = 1
            JMP     CHK_OC1
            ;
DIS_OC1     CLRB                        ; No Active Output
            STAB    TCTL1               ; Disconnect OC2-5
            STAB    OC1M                ; Disconnect PA7
            STAB    OC1D                ; PA7 = 0
            ;
CHK_OC1     LDD     SONG_CNT            ; Loop Until SONG_CNT = 0
            CPD     #0
            BNE     CHK_OC1
            DEC     NOTE_CNT
            BNE     SONG_OC1
            JMP     NEW_SONG

;/*********************************/;
;/* Get Frequency & Delay of Note */;
;/* Input  : SONG_PTR(Note Table) */;
;/* Output : FREQ_CNT(Note Freq.) */;
;/*        : SONG_CNT(Note Delay) */;
;/*        : SONG_PTR=SONG_PTR+2  */;
;/*********************************/;
;
GET_NOTE    LDD     SONG_PTR            ; Get Note Pointer
            ADDD    #TAB_SONG
            PSHB
            PSHA
            PULX
            LDAA    #2
            LDAB    0,X                 ; B = Note
            MUL
            ADDD    #TAB_NOTE
            PSHB
            PSHA
            PULX                        ; X = Note Pointer
            LDD     0,X
            STD     FREQ_CNT            ; Save Note Frequency
            LDD     #1
            ADDD    SONG_PTR
            STD     SONG_PTR            ; SONG_PTR = SONG_PTR+1
            ;
            ;/* Get Delay of Note (Long-Time) */;
            LDD     SONG_PTR            ; get duration
            ADDD    #TAB_SONG
            PSHB
            PSHA
            PULX
            LDAA    #2
            LDAB    0,X                 ; B = Delay
            MUL
            ADDD    #TAB_DELAY
            PSHB
            PSHA
            PULX                        ; X = Delay Pointer
            LDD     0,X
            STD     SONG_CNT            ; Save Note Delay
            LDD     #1
            ADDD    SONG_PTR
            STD     SONG_PTR            ; SONG_PTR = SONG_PTR+1
            RTS

;/*****************/;
;/* RTI Interrupt */;
;/*****************/;
;
RTI_INT     LDD     SONG_CNT            ; Get Note
            CPD     #0
            BHI     DEC_NOTE            ; If >= 0 Jump (*+5)
            JMP     CLR_FLAG
DEC_NOTE    LDD     SONG_CNT            ; SONG_CNT = SONG_CNT-1
            SUBD    #1
            STD     SONG_CNT
CLR_FLAG    LDD     #%01000000          ; Clear RTIF flag
            STAB    TFLG2
            RTI

;/******************/;
;/* TOC5 Interrupt */;
;/******************/;
;
OC5_INT     LDD     TOC5                ; Read TOC5
            ADDD    FREQ_OC5            ; TOC5 = TOC5 + FREQ_OC5
            STD     TOC5
            LDD     #%00001000          ; Clear OC5F Flag
            STAB    TFLG1
            RTI

;/******************/;
;/* TOC4 Interrupt */;
;/******************/;
;
OC4_INT     LDD     TOC4                ; Read TOC4
            ADDD    FREQ_OC4            ; TOC4 = TOC4 + FREQ_OC4
            STD     TOC4
            LDD     #%00010000          ; Clear OC4F Flag
            STAB    TFLG1
            RTI

;/******************/;
;/* TOC3 Interrupt */;
;/******************/;
;
OC3_INT     LDD     TOC3                ; Read TOC3
            ADDD    FREQ_OC3            ; TOC3 = TOC3 + FREQ_OC3
            STD     TOC3
            LDD     #%00100000          ; Clear OC3F Flag
            STAB    TFLG1
            RTI

;/******************/;
;/* TOC2 Interrupt */;
;/******************/;
;
OC2_INT     LDD     TOC2                ; Read TOC2
            ADDD    FREQ_OC2            ; TOC2 = TOC2 + FREQ_OC2
            STD     TOC2
            LDD     #%01000000          ; Clear OC2F Flag
            STAB    TFLG1
            RTI

;/******************/;
;/* TOC1 Interrupt */;
;/******************/;
;
OC1_INT     LDD     TOC1                ; Read TOC1
            ADDD    FREQ_OC1            ; TOC1 = TOC1 + FREQ_OC1
            STD     TOC1
            LDAB    #%10000000          ; Clear OC1F Flag
            STAB    TFLG1
            LDAB    OC1_STAS            ; Toggle PA7
            COMB
            STAB    OC1_STAS
            ANDB    #%10000000
            STAB    OC1D
            RTI

;/********************/;
;/* Table of Pointer */;
;/* For Note & Delay */;
;/* Song of All Note */;
;/********************/;
;
TAB_SONG    FCB     00,1,01,5,02,5,03,5
            FCB     04,5,05,5,06,5,07,5
            FCB     00,1,08,5,09,5,10,5
            FCB     11,5,12,5,13,5,14,5
            FCB     00,1,15,5,16,5,17,5
            FCB     18,5,19,5,20,5,21,5
            FCB     00,1,22,5,23,5,24,5
            FCB     25,5,26,5,27,5,28,5
            FCB     00,1,29,5,30,5,31,5
            FCB     32,5,33,5,34,5,35,5
            FCB     255                 ; End of Music

;/**************************/;
;/* Table of Standard Note */;
;/**************************/;
;
TAB_NOTE    FDB     0000                ; No Sound
            ;
            FDB     3822                ; Note C  (261.624 Hz) Octave4
            FDB     3405                ; Note D  (293.664 Hz)
            FDB     3034                ; Note E  (329.624 Hz)
            FDB     2863                ; Note F  (349.232 Hz)
            FDB     2551                ; Note G  (391.992 Hz)
            FDB     2273                ; Note A  (440.000 Hz)
            FDB     2025                ; Note B  (493.880 Hz)
            ;
            FDB     1911                ; Note C  (523.248 Hz) Octave5
            FDB     1703                ; Note D  (587.238 Hz)
            FDB     1517                ; Note E  (659.248 Hz)
            FDB     1432                ; Note F  (698.464 Hz)
            FDB     1276                ; Note G  (783.984 Hz)
            FDB     1136                ; Note A  (880.000 Hz)
            FDB     1012                ; Note B  (987.760 Hz)
            ;
            FDB     956                 ; Note C  (1046.496 Hz) Octave6
            FDB     851                 ; Note D  (1174.656 Hz)
            FDB     758                 ; Note E  (1318.496 Hz)
            FDB     716                 ; Note F  (1396.928 Hz)
            FDB     638                 ; Note G  (1567.968 Hz)
            FDB     568                 ; Note A  (1760.000 Hz)
            FDB     506                 ; Note B  (1975.520 Hz)
            ;
            FDB     478                 ; Note C  (2092.992 Hz) Octave7
            FDB     426                 ; Note D  (2349.312 Hz)
            FDB     379                 ; Note E  (2636.992 Hz)
            FDB     358                 ; Note F  (2793.856 Hz)
            FDB     319                 ; Note G  (3135.936 Hz)
            FDB     284                 ; Note A  (3520.000 Hz)
            FDB     253                 ; Note B  (3951.040 Hz)
            ;
            FDB     239                 ; Note C  (4185.984 Hz) Octave8
            FDB     213                 ; Note D  (4698.624 Hz)
            FDB     190                 ; Note E  (5273.984 Hz)
            FDB     179                 ; Note F  (5587.712 Hz)
            FDB     161                 ; Note G  (6217.872 Hz)
            FDB     142                 ; Note A  (7040.000 Hz)
            FDB     127                 ; Note B  (7902.080 Hz)

;/********************/;
;/* Note Delay Table */;
;/********************/;
;
TAB_DELAY   FDB     0,255,190,127,94
            FDB     63,47,31,23,16

            ORG     $FFE0
            FDB     OC5_INT             ; OC5 Vector
            FDB     OC4_INT             ; OC4 Vector
            FDB     OC3_INT             ; OC3 Vector
            FDB     OC2_INT             ; OC2 Vector
            FDB     OC1_INT             ; OC1 Vector
            ORG     $FFF0
            FDB     RTI_INT             ; RTI Vector
            ORG     $FFFE               ; Reset Vector
            FDB     MAIN

            END

ส่วนสำหรับเขียนเพื่อทำงานกับมอนิเตอร์ของอีทีที จะเป็นดังนี้


;/**********************************/;
;/* Demo Program For OutputCompare */;
;/*    Timer Run Interrupt Mode    */;
;/* Used OCX : Generate Music Note */;
;/* Hardware : ET-CP68HC11 Ver 2.0 */;
;/* Complier : AS11NEW.EXE (V1.03) */;
;/**********************************/;
;
;/***************************/;
;/*** I/O Register Equate ***/;
;/***************************/;
;
IOREGS      EQU     $1000               ; Start of I/O Register
PORTA       EQU     IOREGS+$00          ; I/O Port-A
PIOC        EQU     IOREGS+$02          ; I/O Control Register
PORTC       EQU     IOREGS+$03          ; I/O Port-C
PORTB       EQU     IOREGS+$04          ; I/O Port-B
PORTCL      EQU     IOREGS+$05          ; I/O Control Register
DDRC        EQU     IOREGS+$07          ; Data Direction Register-C
PORTD       EQU     IOREGS+$08          ; I/O Port-D
DDRD        EQU     IOREGS+$09          ; Data Direction Register-D
PORTE       EQU     IOREGS+$0A          ; I/O Port-E
CFORC       EQU     IOREGS+$0B          ; Force Output Compare
OC1M        EQU     IOREGS+$0C          ; OC1 Mask Bits
OC1D        EQU     IOREGS+$0D          ; OC1 Data Bits??
TCNT        EQU     IOREGS+$0E          ; Timer Count Register
TIC1        EQU     IOREGS+$10          ; Input Capture #1
TIC2        EQU     IOREGS+$12          ; Input Capture #2
TIC3        EQU     IOREGS+$14          ; Input Capture #3
TOC1        EQU     IOREGS+$16          ; Output Compare #1
TOC2        EQU     IOREGS+$18          ; Output Compare #2
TOC3        EQU     IOREGS+$1A          ; Output Compare #3
TOC4        EQU     IOREGS+$1C          ; Output Compare #4
TOC5        EQU     IOREGS+$1E          ; Output Compare #5
TCTL1       EQU     IOREGS+$20          ; Timer Control Register #1
TCTL2       EQU     IOREGS+$21          ; Timer Control Register #2
TMSK1       EQU     IOREGS+$22          ; Timer Mask #1
TFLG1       EQU     IOREGS+$23          ; Timer Flags #1
TMSK2       EQU     IOREGS+$24          ; Timer Mask #2
TFLG2       EQU     IOREGS+$25          ; Timer Flags #2
PACTL       EQU     IOREGS+$26          ; Pulse Accum Control
PACNT       EQU     IOREGS+$27          ; Pulse Accum Counter
SPCR        EQU     IOREGS+$28          ; SPI Control Register
SPSR        EQU     IOREGS+$29          ; SPI Status Register
SPDR        EQU     IOREGS+$2A          ; SPI Data Register
BAUD        EQU     IOREGS+$2B          ; Baudrate Register
SCCR1       EQU     IOREGS+$2C          ; SCI Register 1
SCCR2       EQU     IOREGS+$2D          ; SCI Register 2
SCSR        EQU     IOREGS+$2E          ; SCI Status Register
SCDR        EQU     IOREGS+$2F          ; SCI Data Register
ADCTL       EQU     IOREGS+$30          ; A/D Control Register
ADR1        EQU     IOREGS+$31          ; A/D Result 1
ADR2        EQU     IOREGS+$32          ; A/D Result 2
ADR3        EQU     IOREGS+$33          ; A/D Result 3
ADR4        EQU     IOREGS+$34          ; A/D Result 4
OPTION      EQU     IOREGS+$39          ; Option Register
COPRST      EQU     IOREGS+$3A          ; COP Reset Register
PPROG       EQU     IOREGS+$3B          ; EEPROM Programming Register
HPRIO       EQU     IOREGS+$3C          ; Highest-Priority Register
INIT        EQU     IOREGS+$3D          ; Memory Map Initialization
TEST1       EQU     IOREGS+$3E          ; Test Register 1
CONFIG      EQU     IOREGS+$3F          ; System Configuration
;
;/* Interrupt Vector For Debugger 68HC11 V2.0 */;
OC5_VEC     EQU     $20D3
OC4_VEC     EQU     $20D6
OC3_VEC     EQU     $20D9
OC2_VEC     EQU     $20DC
OC1_VEC     EQU     $20DF
RTI_VEC     EQU     $20EB

            ORG     $2200               ; Start of Debugger User Area
MAIN        LDAB    #$7E                ; Jump-EXT Opcode
            STAB    OC5_VEC             ; 1st Byte Debugger Vector
            STAB    OC4_VEC
            STAB    OC3_VEC
            STAB    OC2_VEC
            STAB    OC1_VEC
            STAB    RTI_VEC
            LDX     #OC5_INT            ; Address Service Routine
            STX     OC5_VEC+1           ; 2nd,3rd Byte Debugger Vector
            LDX     #OC4_INT
            STX     OC4_VEC+1
            LDX     #OC3_INT
            STX     OC3_VEC+1
            LDX     #OC2_INT
            STX     OC2_VEC+1
            LDX     #OC1_INT
            STX     OC1_VEC+1
            LDX     #RTI_INT
            STX     RTI_VEC+1
            ;
            LDD     #0                  ; SONG_CNT = 0
            STD     SONG_CNT
            LDAB    TMSK2
            ORAB    #%01000000          
            STAB    TMSK2               ; Enable RTI Interrupt
            LDAB    #%01000000
            STAB    TFLG2               ; Clear RTIF Flag
            ;
            LDAB    TMSK1
            ORAB    #%11111000
            STAB    TMSK1               ; Enable OC1I-OC5I
            LDAB    #%11111000
            STAB    TFLG1               ; Clear OC1F-OC5F
            LDAB    #%00000000
            STAB    TCTL1               ; Disconnect OC2-OC5 Pin
            LDAB    PACTL
            ORAB    #%10000000
            STAB    PACTL               ; PA7 = Output
            CLI                         ; Enable Global Interrupt
            ;
NEW_SONG    LDAB    #%11111000
            STAB    TFLG1               ; Clear OC1F-OC5F
            LDD     #0                  ; Start 1st Music Note
            STD     SONG_PTR
            ;
            LDAB    #8
            STAB    NOTE_CNT            ; 8-Note on OC5(PA3)
            ;
SONG_OC5    JSR     GET_NOTE            ; Get Note & Delay
            LDD     FREQ_CNT
            STD     FREQ_OC5
            LDD     FREQ_OC5            ; FREQ_OC5 = 0 ?
            CPD     #0
            BNE     ENA_OC5
            JMP     DIS_OC5
            ;
ENA_OC5     LDD     TCNT
            ADDD    FREQ_OC5
            STD     TOC5
            LDAB    TCTL1
            ORAB    #%00000001
            STAB    TCTL1               ; Toggle OC5 Pin
            JMP     CHK_OC5
            ;
DIS_OC5     CLRB                        ; No Active Output
            STAB    TCTL1               ; Disconnect OC2-5
            STAB    OC1M                ; Disconnect PA7
            STAB    OC1D                ; PA7 = 0
            ;
CHK_OC5     LDD     SONG_CNT            ; Loop Until SONG_CNT = 0
            CPD     #0
            BNE     CHK_OC5
            DEC     NOTE_CNT
            BNE     SONG_OC5
            ;
            LDAB    #8
            STAB    NOTE_CNT            ; 8-Note on OC4(PA4)
            ;
SONG_OC4    JSR     GET_NOTE            ; Get Note & Delay
            LDD     FREQ_CNT
            STD     FREQ_OC4
            LDD     FREQ_OC4            ; FREQ_OC4 = 0 ?
            CPD     #0
            BNE     ENA_OC4
            JMP     DIS_OC4
            ;
ENA_OC4     LDD     TCNT
            ADDD    FREQ_OC4
            STD     TOC4
            LDAB    TCTL1
            ORAB    #%00000100
            STAB    TCTL1               ; Toggle OC4 Pin
            JMP     CHK_OC4
            ;
DIS_OC4     CLRB                        ; No Active Output
            STAB    TCTL1               ; Disconnect OC2-5
            STAB    OC1M                ; Disconnect PA7
            STAB    OC1D                ; PA7 = 0
            ;
CHK_OC4     LDD     SONG_CNT            ; Loop Until SONG_CNT = 0
            CPD     #0
            BNE     CHK_OC4
            DEC     NOTE_CNT
            BNE     SONG_OC4
            ;
            LDAB    #8
            STAB    NOTE_CNT            ; 8-Note on OC3(PA5)
            ;
SONG_OC3    JSR     GET_NOTE            ; Get Note & Delay
            LDD     FREQ_CNT
            STD     FREQ_OC3
            LDD     FREQ_OC3            ; FREQ_OC3 = 0 ?
            CPD     #0
            BNE     ENA_OC3
            JMP     DIS_OC3
            ;
ENA_OC3     LDD     TCNT
            ADDD    FREQ_OC3
            STD     TOC3
            LDAB    TCTL1
            ORAB    #%00010000
            STAB    TCTL1               ; Toggle OC3 Pin
            JMP     CHK_OC3
            ;
DIS_OC3     CLRB                        ; No Active Output
            STAB    TCTL1               ; Disconnect OC2-5
            STAB    OC1M                ; Disconnect PA7
            STAB    OC1D                ; PA7 = 0
            ;
CHK_OC3     LDD     SONG_CNT            ; Loop Until SONG_CNT = 0
            CPD     #0
            BNE     CHK_OC3
            DEC     NOTE_CNT
            BNE     SONG_OC3
            ;
            LDAB    #8
            STAB    NOTE_CNT            ; 8-Note on OC2(PA6)
            ;
SONG_OC2    JSR     GET_NOTE            ; Get Note & Delay
            LDD     FREQ_CNT
            STD     FREQ_OC2
            LDD     FREQ_OC2            ; FREQ_OC2 = 0 ?
            CPD     #0
            BNE     ENA_OC2
            JMP     DIS_OC2
            ;
ENA_OC2     LDD     TCNT
            ADDD    FREQ_OC2
            STD     TOC2
            LDAB    TCTL1
            ORAB    #%01000000
            STAB    TCTL1               ; Toggle OC2 Pin
            JMP     CHK_OC2
            ;
DIS_OC2     CLRB                        ; No Active Output
            STAB    TCTL1               ; Disconnect OC2-5
            STAB    OC1M                ; Disconnect PA7
            STAB    OC1D                ; PA7 = 0
            ;
CHK_OC2     LDD     SONG_CNT            ; Loop Until SONG_CNT = 0
            CPD     #0
            BNE     CHK_OC2
            DEC     NOTE_CNT
            BNE     SONG_OC2
            ;
            LDAB    #8
            STAB    NOTE_CNT            ; 8-Note on OC1(PA7)
            ;
SONG_OC1    JSR     GET_NOTE            ; Get Note & Delay
            LDD     FREQ_CNT
            STD     FREQ_OC1
            LDD     FREQ_OC1            ; FREQ_OC1 = 0 ?
            CPD     #0
            BNE     ENA_OC1
            JMP     DIS_OC1
            ;
ENA_OC1     LDD     TCNT
            ADDD    FREQ_OC1
            STD     TOC1
            LDAB    #%10000000
            STAB    OC1M                ; OC1 Active PA7
            STAB    OC1_STAS            ; Save Status Output
            STAB    OC1D                ; PA7 = 1
            JMP     CHK_OC1
            ;
DIS_OC1     CLRB                        ; No Active Output
            STAB    TCTL1               ; Disconnect OC2-5
            STAB    OC1M                ; Disconnect PA7
            STAB    OC1D                ; PA7 = 0
            ;
CHK_OC1     LDD     SONG_CNT            ; Loop Until SONG_CNT = 0
            CPD     #0
            BNE     CHK_OC1
            DEC     NOTE_CNT
            BNE     SONG_OC1
            JMP     NEW_SONG

;/*********************************/;
;/* Get Frequency & Delay of Note */;
;/* Input  : SONG_PTR(Note Table) */;
;/* Output : FREQ_CNT(Note Freq.) */;
;/*        : SONG_CNT(Note Delay) */;
;/*        : SONG_PTR=SONG_PTR+2  */;
;/*********************************/;
;
GET_NOTE    LDD     SONG_PTR            ; Get Note Pointer
            ADDD    #TAB_SONG
            PSHB
            PSHA
            PULX
            LDAA    #2
            LDAB    0,X                 ; B = Note
            MUL
            ADDD    #TAB_NOTE
            PSHB
            PSHA
            PULX                        ; X = Note Pointer
            LDD     0,X
            STD     FREQ_CNT            ; Save Note Frequency
            LDD     #1
            ADDD    SONG_PTR
            STD     SONG_PTR            ; SONG_PTR = SONG_PTR+1
            ;
            ;/* Get Delay of Note (Long-Time) */;
            LDD     SONG_PTR            ; get duration
            ADDD    #TAB_SONG
            PSHB
            PSHA
            PULX
            LDAA    #2
            LDAB    0,X                 ; B = Delay
            MUL
            ADDD    #TAB_DELAY
            PSHB
            PSHA
            PULX                        ; X = Delay Pointer
            LDD     0,X
            STD     SONG_CNT            ; Save Note Delay
            LDD     #1
            ADDD    SONG_PTR
            STD     SONG_PTR            ; SONG_PTR = SONG_PTR+1
            RTS

;/*****************/;
;/* RTI Interrupt */;
;/*****************/;
;
RTI_INT     LDD     SONG_CNT            ; Get Note
            CPD     #0
            BHI     DEC_NOTE            ; If >= 0 Jump (*+5)
            JMP     CLR_FLAG
DEC_NOTE    LDD     SONG_CNT            ; SONG_CNT = SONG_CNT-1
            SUBD    #1
            STD     SONG_CNT
CLR_FLAG    LDD     #%01000000          ; Clear RTIF flag
            STAB    TFLG2
            RTI

;/******************/;
;/* TOC5 Interrupt */;
;/******************/;
;
OC5_INT     LDD     TOC5                ; Read TOC5
            ADDD    FREQ_OC5            ; TOC5 = TOC5 + FREQ_OC5
            STD     TOC5
            LDD     #%00001000          ; Clear OC5F Flag
            STAB    TFLG1
            RTI

;/******************/;
;/* TOC4 Interrupt */;
;/******************/;
;
OC4_INT     LDD     TOC4                ; Read TOC4
            ADDD    FREQ_OC4            ; TOC4 = TOC4 + FREQ_OC4
            STD     TOC4
            LDD     #%00010000          ; Clear OC4F Flag
            STAB    TFLG1
            RTI

;/******************/;
;/* TOC3 Interrupt */;
;/******************/;
;
OC3_INT     LDD     TOC3                ; Read TOC3
            ADDD    FREQ_OC3            ; TOC3 = TOC3 + FREQ_OC3
            STD     TOC3
            LDD     #%00100000          ; Clear OC3F Flag
            STAB    TFLG1
            RTI

;/******************/;
;/* TOC2 Interrupt */;
;/******************/;
;
OC2_INT     LDD     TOC2                ; Read TOC2
            ADDD    FREQ_OC2            ; TOC2 = TOC2 + FREQ_OC2
            STD     TOC2
            LDD     #%01000000          ; Clear OC2F Flag
            STAB    TFLG1
            RTI

;/******************/;
;/* TOC1 Interrupt */;
;/******************/;
;
OC1_INT     LDD     TOC1                ; Read TOC1
            ADDD    FREQ_OC1            ; TOC1 = TOC1 + FREQ_OC1
            STD     TOC1
            LDAB    #%10000000          ; Clear OC1F Flag
            STAB    TFLG1
            LDAB    OC1_STAS            ; Toggle PA7
            COMB
            STAB    OC1_STAS
            ANDB    #%10000000
            STAB    OC1D
            RTI

;/********************/;
;/* Table of Pointer */;
;/* For Note & Delay */;
;/* Song of All Note */;
;/********************/;
;
TAB_SONG    FCB     00,1,01,5,02,5,03,5
            FCB     04,5,05,5,06,5,07,5
            FCB     00,1,08,5,09,5,10,5
            FCB     11,5,12,5,13,5,14,5
            FCB     00,1,15,5,16,5,17,5
            FCB     18,5,19,5,20,5,21,5
            FCB     00,1,22,5,23,5,24,5
            FCB     25,5,26,5,27,5,28,5
            FCB     00,1,29,5,30,5,31,5
            FCB     32,5,33,5,34,5,35,5
            FCB     255                 ; End of Music

;/**************************/;
;/* Table of Standard Note */;
;/**************************/;
;
TAB_NOTE    FDB     0000                ; No Sound
            ;
            FDB     3822                ; Note C  (261.624 Hz) Octave4
            FDB     3405                ; Note D  (293.664 Hz)
            FDB     3034                ; Note E  (329.624 Hz)
            FDB     2863                ; Note F  (349.232 Hz)
            FDB     2551                ; Note G  (391.992 Hz)
            FDB     2273                ; Note A  (440.000 Hz)
            FDB     2025                ; Note B  (493.880 Hz)
            ;
            FDB     1911                ; Note C  (523.248 Hz) Octave5
            FDB     1703                ; Note D  (587.238 Hz)
            FDB     1517                ; Note E  (659.248 Hz)
            FDB     1432                ; Note F  (698.464 Hz)
            FDB     1276                ; Note G  (783.984 Hz)
            FDB     1136                ; Note A  (880.000 Hz)
            FDB     1012                ; Note B  (987.760 Hz)
            ;
            FDB     956                 ; Note C  (1046.496 Hz) Octave6
            FDB     851                 ; Note D  (1174.656 Hz)
            FDB     758                 ; Note E  (1318.496 Hz)
            FDB     716                 ; Note F  (1396.928 Hz)
            FDB     638                 ; Note G  (1567.968 Hz)
            FDB     568                 ; Note A  (1760.000 Hz)
            FDB     506                 ; Note B  (1975.520 Hz)
            ;
            FDB     478                 ; Note C  (2092.992 Hz) Octave7
            FDB     426                 ; Note D  (2349.312 Hz)
            FDB     379                 ; Note E  (2636.992 Hz)
            FDB     358                 ; Note F  (2793.856 Hz)
            FDB     319                 ; Note G  (3135.936 Hz)
            FDB     284                 ; Note A  (3520.000 Hz)
            FDB     253                 ; Note B  (3951.040 Hz)
            ;
            FDB     239                 ; Note C  (4185.984 Hz) Octave8
            FDB     213                 ; Note D  (4698.624 Hz)
            FDB     190                 ; Note E  (5273.984 Hz)
            FDB     179                 ; Note F  (5587.712 Hz)
            FDB     161                 ; Note G  (6217.872 Hz)
            FDB     142                 ; Note A  (7040.000 Hz)
            FDB     127                 ; Note B  (7902.080 Hz)

;/********************/;
;/* Note Delay Table */;
;/********************/;
;
TAB_DELAY   FDB     0,255,190,127,94
            FDB     63,47,31,23,16

;/* Variable Buffer in EXT-RAM */;
;
SONG_PTR    RMB     2                   ; Music Note Pointer
SONG_CNT    RMB     2                   ; Song Delay Count
NOTE_CNT    RMB     1                   ; Note/Output Count
OC1_STAS    RMB     1                   ; PA7 Status
;
FREQ_CNT    RMB     2                   ; Timer 1/2 Cycle Count
FREQ_OC1    RMB     2
FREQ_OC2    RMB     2
FREQ_OC3    RMB     2
FREQ_OC4    RMB     2
FREQ_OC5    RMB     2

            END


สามารถ download ไฟล์ตัวอย่างของบอร์ด พร้อม assembler ได้เลยครับ


เขียนโดย : ETT
Author : ETT team
e-mail : sales@etteam.com
วันที่ทำการปรับปรุง : ๖ ธ.ค. ๒๕๔๓