#include "P18F4455.INC" ORG 0X800 VAR0 EQU 0X00 VAR1 EQU 0X01 TMP EQU 0X02 COUNTER EQU 0X03 FULL_NOTE EQU D'150' HALF_NOTE EQU D'80' PAUSE_NOTE EQU D'10' LONG_PAUSE EQU D'200' CBLOCK 0X00 _DO_ _RE_ _MI_ _FA_ _SOL_ _LA_ _SI_ _DO_UP_ ENDC ;C4 - F = 262 Hz, T = 3.8167 mSec, T/2 = 1.9083 ;D4 - F = 294 Hz, T = 3.4013 mSec, T/2 = 1.7006 ;E4 - F = 330 Hz, T = 3.0303 mSec, T/2 = 1.5151 ;F4 - F = 349 Hz, T = 2.8653 mSec, T/2 = 1.4326 ;G4 - F = 392 Hz, T = 2.5510 mSec, T/2 = 1.2755 ;A4 - F = 440 Hz, T = 2.2727 mSec, T/2 = 1.13635 ;B4 - F = 494 Hz, T = 2.0246 mSec, T/2 = 1.0123 ;C4 - F = 524 Hz, T = 1.9110 mSec, T/2 = 0.9555 GOTO MAIN Get_Next_Note: MULLW D'2' MOVF PRODL, W MOVFF PCL, TMP ADDWF PCL, F RETLW _DO_ RETLW _MI_ RETLW _DO_ RETLW _MI_ RETLW _SOL_ RETLW _SOL_ RETLW _DO_ RETLW _MI_ RETLW _DO_ RETLW _MI_ RETLW _SOL_ RETLW _SOL_ RETLW _DO_UP_ RETLW _SI_ RETLW _LA_ RETLW _SOL_ RETLW _FA_ RETLW _LA_ RETLW _SOL_ RETLW _FA_ RETLW _MI_ RETLW _RE_ RETLW _DO_ RETLW _DO_ Get_Next_Delay: MULLW D'2' MOVF PRODL, W MOVFF PCL, TMP ADDWF PCL, F RETLW HALF_NOTE RETLW HALF_NOTE RETLW HALF_NOTE RETLW HALF_NOTE RETLW FULL_NOTE RETLW FULL_NOTE RETLW HALF_NOTE RETLW HALF_NOTE RETLW HALF_NOTE RETLW HALF_NOTE RETLW FULL_NOTE RETLW FULL_NOTE RETLW HALF_NOTE RETLW HALF_NOTE RETLW HALF_NOTE RETLW HALF_NOTE RETLW FULL_NOTE RETLW FULL_NOTE RETLW HALF_NOTE RETLW HALF_NOTE RETLW HALF_NOTE RETLW HALF_NOTE RETLW FULL_NOTE RETLW FULL_NOTE Get_Next_Period: MULLW D'2' MOVF PRODL, W MOVFF PCL, TMP ADDWF PCL, F RETLW D'237' RETLW D'211' RETLW D'188' RETLW D'178' RETLW D'158' RETLW D'141' RETLW D'127' RETLW D'118' Get_Next_DutyCycle: MULLW D'2' MOVF PRODL, W MOVFF PCL, TMP ADDWF PCL, F RETLW D'29' RETLW D'70' RETLW D'65' RETLW D'60' RETLW D'55' RETLW D'50' RETLW D'40' RETLW D'35' DELAY_1MILLI MOVLW D'200' MOVWF VAR0 LOOP1: NOP NOP NOP NOP DECFSZ VAR0,F GOTO LOOP1 RETURN VARIABLE_DELAY: MOVWF VAR1 LOOP2: CALL DELAY_1MILLI CALL DELAY_1MILLI CALL DELAY_1MILLI CALL DELAY_1MILLI DECFSZ VAR1,F GOTO LOOP2 RETURN NO_SOUND: MOVLW D'255' MOVWF CCPR2L MOVLW PAUSE_NOTE MOVWF VAR1 CALL VARIABLE_DELAY RETURN NO_SOUND_LONG_PAUSE: MOVLW D'255' MOVWF CCPR2L MOVLW LONG_PAUSE MOVWF VAR1 CALL VARIABLE_DELAY RETURN MAIN: ; select internal 4 MHz oscilator MOVLW B'01100010' MOVWF OSCCON CLRF TRISB CLRF TRISC MOVLW 0X0F MOVWF ADCON1 MOVLW 0X07 MOVWF CMCON CLRF COUNTER MOVLW B'00000111' MOVWF T2CON ; set PWM mode MOVLW B'00001111' MOVWF CCP2CON BCF CCP2CON, 5 ; upper bit is set to 0 BCF CCP2CON, 4 MAIN_LOOP: MOVF COUNTER, W ; GET NEXT NOTE TO BE PLAYED CALL Get_Next_Note CALL Get_Next_Period MOVWF PR2 MOVF COUNTER, W ; GET NEXT NOTE TO BE PLAYED CALL Get_Next_Note CALL Get_Next_DutyCycle MOVWF CCPR2L BCF CCP2CON, 4 TSTFSZ COUNTER GOTO START_DELAY BSF CCP2CON, 4 START_DELAY: MOVF COUNTER, W ; GET NEXT NOTE LENGTH CALL Get_Next_Delay MOVWF VAR1 CALL VARIABLE_DELAY ; NO SOUND CALL NO_SOUND ; MOVE TO NEXT NOTE INCF COUNTER, F MOVLW D'24' CPFSEQ COUNTER GOTO MAIN_LOOP CLRF COUNTER CALL NO_SOUND_LONG_PAUSE GOTO MAIN_LOOP END