|
AT89C51單片機實現(xiàn)蜂鳴器播放音樂
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
0.png (9.79 KB, 下載次數(shù): 82)
下載附件
2018-10-11 02:07 上傳
單片機源程序如下:
- #include <reg51.h>
- sbit SPK = P2^7;
- void main(void)
- {
- /* NOTE: this program can not work correctly */
- /*
- #pragma asm
- ORG 001BH ;timer/counter 1 interrupt entry
- mov th1, r1 ;restore timer initial count
- mov tl1, r0 ;
- ; setb p3.7 ;
- cpl p2.7 ;p1.0 output square wave
- reti ;
- ORG 100H ;main function
- ASM_ENTRY:
- mov tmod, #01H ;timer/counter 1 works in mode 1
- mov ie, #88H ;enable timer/counter 1 interrupt
- mov dptr, #TAB ;table start address
- LOOP:
- clr a ;
- movc a, @a + dptr ;read table item
- mov r1, a ;high 8 bits of timer/counter 1 saves in r1
- inc dptr ;
- clr a ;
- movc a, @a+dptr ;read next table item
- mov r0, a ;low 8 bits of timer/counter 1 saves in r0
- orl a, r1 ;
- jz NEXT0 ;all 0 indicating a silence music symbol
- mov a, r0 ;
- anl a, r1 ;
- cjne a, #0FFH, NEXT ;all 1 indicating a end music symbol
- sjmp ASM_ENTRY ;begin to play another music cycle
- NEXT:
- mov th1, r1 ;store in timer/counter 1
- mov tl1, r0 ;
- setb tr1 ;run timer/counter 1
- sjmp NEXT1 ;
- NEXT0: clr tr1 ;
- NEXT1: clr a ;
- inc dptr ;
- movc a, @a + dptr ;read delay constant
- mov r2, a ;
- LOOP1:
- lcall D200 ;call delay 200ms subroutine
- djnz r2, LOOP1 ;control delay count
- inc dptr ;
- ajmp LOOP ;process next music symbol
- D200: mov r4, #81H ;delay 20ms subroutine
- D200B: mov a, #0FFH ;
- D200A: dec a ;
- jnz D200A ;
- dec r4 ;
- cjne r4, #00H, D200B ;
- ret ;
- TAB:
- DB 0FEH, 25H, 02H, 0FEH, 98H, 08H;
- ; DB 0FEH, 84H, 02H, 0FEH, 84H, 02H;
- ; DB 0FEH, 84H, 04H, 0FEH, 25H, 04H;
- ; DB 0FEH, 25H, 02H, 0FEH, 84H, 02H;
- ; DB 0FEH, 0C0H, 04H, 0FEH, 0C0H, 04H;
- ; DB 0FEH, 98H, 02H, 0FEH, 84H, 02H;
- ; DB 0FEH, 57H, 08H, 00H, 00H, 04H;
- ; DB 0FFH, 0FFH;
- #pragma endasm
- */
- /* play music using polling method */
- /*
- #pragma asm
- ORG 0
- ljmp ASM_ENTRY
- ORG 0030H
- ASM_ENTRY:
- mov r3, #0 ;used as a index, pointer to the begin of a music score
- READ_NOTE: ;read currect indexed music note.
- mov dptr, #SCORE ;load music score address
- mov a, r3 ;
- movc a, @a + dptr ;read note
- jz ASM_ENTRY ;0 is the end music symbol then loop
- mov r7, a ;note saves in r7
- inc r3 ;ready for reading note time
- mov a, r3 ;
- movc a, @a + dptr ;read time
- mov r2, a ;time saves in r2
- acall PLAY_NOTE ;
- inc r3 ;ready for reading next note
- sjmp READ_NOTE ;
- mov a, r2 ;get time
- jnz PLAY_NOTE
- acall DELAY ;stop a second for replay
- PLAY_NOTE:
- acall ONE_EIGHT ;
- djnz r2, PLAY_NOTE ;
- ret
- ONE_EIGHT:
- mov a, r7 ;get note
- mov dptr, #TONE_FREQUENCY ;
- movc a, @a + dptr ;
- mov r4, a ;
- mov a, r7 ;
- mov dptr, #TONE_LENGTH ;
- movc a, @a + dptr ;
- mov r5, a ;
- DELAY:
- acall SOUND ;
- djnz r5, DELAY ;
- ret ;
- SOUND:
- setb SPK ;
- acall SDELAY ;
- clr SPK ;
- acall SDELAY ;
- ; cpl SPK ;add begin
- ; acall SDELAY ;add end
- ret ;
- SDELAY:
- mov a, r4 ;
- mov r0, a ;
- D1: mov r1, #03H ;
- D2: nop ;
- djnz r1, D2 ;
- djnz r0, D1 ;
- ret ;
- _DELAY_US: ;delay for 8us
- nop;nop; ;4 * nop + call + ret =
- nop;nop; ;4us + 2us + 2us = 8us
- ret ;
- DELAY_US: ;granularity is 10us
- LOOP:
- lcall _DELAY_US ;_DELAY + djnz = 8us + 2us = 10us
- djnz r5, LOOP ;argument is saved in r5
- ret ;real is n * 10us + call + ret = 10n + 4us
- _DELAY_MS:
- ; push r5 ;protect r5 previous value
- mov r5, #98 ;(980us + 4us) + 8us = 992us
- lcall DELAY_US ;
- nop;nop;nop; ;
- nop;nop;nop; ;
- ret ;
- ; pop r5 ;restore r5 previous value
- DELAY_MS:
- mov dptr, #DELAY_PARAMETER ;which number = 250 * r7 + r6
- mov a, #0 ;
- movc a, @a + dptr ;0-250
- mov r6, a ;
- inc a ;
- movc a, @a + dptr ;0-3, in which domain[250n, 250n+250)
- mov r7, a ;
- ; push r7 ;
- ; push r6 ;
- LOOP1: mov a, r7 ;
- jz DONE1 ;
- dec r7 ;
- LOOP2: mov a, r6 ;
- jz DONE2 ;
- dec r6 ;
- acall _DELAY_MS ;loop2 one iterate time = 992us + 8us = 1000us
- sjmp LOOP2 ;
- DONE2:
- mov r6, #250 ;
- sjmp LOOP1 ;
- DONE1:
- ; pop r6 ;
- ; pop r7 ;
- ret ;
- DELAY_PARAMETER:
- DW 00H ;0 - 1000, low 8 bits represents 0-250, bit 8-9 represents a select.
-
- TONE_LENGTH:
- DS 1DH ;reserve 29 bytes
- DB 15H,16H,00
- DB 19H,00H,1CH,00H,1FH,21H,00H,25H
- DB 00H,29H,2CH,00H,31H,34H,37H,00H
- DB 3EH,41H,00H,49H,00H,52H,57H,00H
- DB 62H
-
- TONE_FREQUENCY:
- DS 1DH ;reserve 29 bytes
- DB 7EH,77H,00H
- DB 6AH,00H,5EH,00H,54H,4FH,00H,46H
- DB 00H,3FH,3BH,00H,35H,32H,2FH,00H
- DB 2AH,27H,00H,23H,00H,1FH,1DH,0C0H
- DB 1AH
- SCORE:
- DW 2202H,2902H,2902H,2902H,2906H,2702H ;
- DW 2502H,2702H,2502H,2402H,2208H ;
- DW 2E02H,2E02H,2E02H,2E02H,2E06H,2C02H ;
- DW 2902H,2C02H,2D02H,2A02H,2908H ;
- DW 2902H,2E02H,2E02H,2C02H,2906H,2702H ;
- DW 2502H,2702H,2502H,2402H,2206H,1D02H ;
- DW 1D02H,2502H,2502H,2402H,2206H,2902H ;
- DW 2702H,2502H,2402H,2002H,2208H ;
- DW 0000H
- #pragma endasm
- */
- /* play music using interrupt method */
- /*
- #pragma asm
- ; spk eql p2.7
- ORG 0
- ljmp ASM_ENTRY
- ORG 0030H
- ASM_ENTRY:
- mov r3, #00H ;table index, clear to 0
- NEXT:
- mov a, r3
- mov dptr, #TABLE ;load table start address
- movc a, @a + dptr ;
- jz ASM_ENTRY ;0 is the end music symbol then loop
- mov r7, a ;r7 is current searched code byte
- inc r3 ;read next code byte
- mov a, r3 ;
- movc a, @a + dptr ;
- mov r2, a ;next byte stores in r2
- acall SONG ;
- inc r3 ;
- sjmp NEXT ;
- SONG:
- mov a, r2 ;get rhythm
- rl a ;
- jnz KEEP ;
- mov a, #01H ;
- KEEP:
- mov r2, a ;
- REPEAT:
- acall ONE_EIGHT ;
- djnz r2, REPEAT ;
- ret ;
- ONE_EIGHT: ;generate one eight delay
- mov a, r7 ;
- mov dptr, #DELAY_T ;
- movc a, @a + dptr ;
- mov r4, a ;
- mov a, r7 ;
- mov dptr, #S_PARA ;
- movc a, @a + dptr ;
- mov r5, a
- NEXT_CYC:
- acall SOUND
- djnz r5, NEXT_CYC ;
- ret ;
- SOUND:
- setb SPK ;
- acall SDELAY ;
- clr SPK ;
- acall SDELAY ;
- ret ;
- SDELAY:
- mov a, r4 ;
- mov r0, a ;
- XL2: mov r1, #03H ;
- DL1:
- nop ;
- djnz r1, DL1 ;
- djnz r0, XL2 ;
- ret ;
- S_PARA:
- ;DS 01H
- DS 1DH
- DB 15H,16H,00
- DB 19H,00H,1CH,00H,1FH,21H,00H,25H
- DB 00H,29H,2CH,00H,31H,34H,37H,00H
- DB 3EH,41H,00H,49H,00H,52H,57H,00H
- DB 62H
- DELAY_T:
- DS 1DH
- DB 7EH,77H,00H
- DB 6AH,00H,5EH,00H,54H,4FH,00H,46H
- DB 00H,3FH,3BH,00H,35H,32H,2FH,00H
- DB 2AH,27H,00H,23H,00H,1FH,1DH,0C0H
- DB 1AH
- TABLE:
- DW 2202H,2902H,2902H,2902H,2906H,2702H ;
- DW 2502H,2702H,2502H,2402H,2208H ;
- DW 2E02H,2E02H,2E02H,2E02H,2E06H,2C02H ;
- DW 2902H,2C02H,2D02H,2A02H,2908H ;
- DW 2902H,2E02H,2E02H,2C02H,2906H,2702H ;
- DW 2502H,2702H,2502H,2402H,2206H,1D02H ;
- DW 1D02H,2502H,2502H,2402H,2206H,2902H ;
- DW 2702H,2502H,2402H,2002H,2208H ;
- DW 0000H
- #pragma endasm
- */
- }
復(fù)制代碼
0.png (17.09 KB, 下載次數(shù): 86)
下載附件
2018-10-11 02:08 上傳
所有資料51hei提供下載:
musicPlayer.zip
(73.23 KB, 下載次數(shù): 73)
2018-10-10 22:26 上傳
點擊文件名下載附件
|
|