實驗七         I/O驅動喇叭唱一首歌

 

目的:

             瞭解如何利用執行時間作準確輸出週期控制。

 

使用材料:                           

                        8051模擬器一個。

 

功能說明:

        程式執行後,喇叭放出〝祝你生日快樂〞之旋律, 反覆不停.

 

流程圖:

電路圖:

程式及說明:

    SO EQU 0                                             define constant value so=0 

    LA EQU 1                                             define constant value so=1 

    SI EQU 2                                               define constant value so=2 

    HDO EQU 3                                          define constant value so=3 

    HRE EQU 4                                           define constant value so=4 

    HMI EQU 5                                           define constant value so=5 

    HFA EQU 6                                           define constant value so=6 

    HSO EQU 7                                           define constant value so=7 

    ORG 000H                                             reset  start here

START:

    MOV R3,#NNN                                     load unmber of tatal tones

    MOV R4,#0                                           set data index =0.first tone

LOOPR:

    CALL SONG1                                       get a tone data of the song   

    MOV R5,A                                            r5= note name

    INC R4                                                  inrcease index

    CALL SONG1                                       get a tone length

    MOV R2,A                                            r2=time values

    CALL PLAY                                          play a tone with time values 

    INC R4                                                 increase index

    DJNZ R3,LOOPR                                    if song not finish.  next tone

    JMP START                                           sing again

PLAY:

    MOV A,R5                                            load a tone number 

    RL A                                                    mulitple 2

    PUSH ACC                                            save accumulator

    MOV DPTR,#TABLE                               load frequency table address

    MOVC A,@A+DPDR                               get frequency  parameter

    MOV R0,A                                            load R0 with freq. parameter

    INC DPTR                                             point next data 

    POP ACC                                              restore tone number

    MOVC A,@A+DPDR                               load tone length

    MOV R1,A                                            R1= tone length

    CALL TONE                                          sing a tone

    RET                                                     return caller

TONE:

    LOOP3: MOV R6,1                                  load R6 with R1 

    LOOP2: CPL P3,7                                    invert p3.7 for speaker on-off         

    MOV R7,0                                             load R7 with R0 

LOOP1:         

     SJMP $+2                                             delay 2 us  

    NOP                                                     delay 1 usecind

    DJNZ R7,LOOP1                                    delay R0 * (2+1+2) us

    DJNZ R6,LOOP2                                    delay R1 * (R0*5) us= 0.125s

    DJNZ R2,LOOP3                                    delay R2 * (0.125us)

    SETB P3,7                                             let p3.7= 1,speaker off

     RET                                                    return caller

FROTAB:

     DB 255,98                                           no.0 = period, times of so

    DB 227,110                                           no.1 = period, times of la

    DB 202,124                                          no.2 = period, times of si

    DB 191,131                                          no.3 = period, times of . do

    DB 170.147                                          no.4 = period, times of . re

    DB 151,165                                          no.5 = period, times of . mi   

    DB 143,175                                          no.6 = period, times of . fa

    DB 127,196                                          no.7 = period, times of  . so

SONG1:    

    MOV A,R4                                           load a with index number           

    INC A                                                 A = A+1 = R4+1

    MOVC A,@A+PC                                  get display code

    RET                                                    return 

SONG:

    DB SO,4 SO,4 LA,8 SO,8 HDO,8 SI,16 SO,4 SO,4                  

    DB LA,8 SO,8 HRE,8 HDO,16 SO,4 SO,4 HSO,8

    DB HMI,8 HDO,8 SI,8 HFA,4 HFA,4  HMI,8

    DB HDO,8 HRE,8 HHDO,16

NNN:

    EQU ($-SONG)/2                                   number of tones        

    END