;**************************************************** ; PIC12F1501 DAC FREQUENCY GENERATOR /W envelope *** ;********* 20150103 by Minarai Syokunin ************* ;**************************************************** INCLUDE "P12F1501.inc" __CONFIG _CONFIG1 , _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOREN_OFF & _CLKOUTEN_OFF __CONFIG _CONFIG2 , _WRT_OFF & _STVREN_OFF & _BORV_HI & _LPBOR_OFF & _LVP_OFF ;************** DEFINES ******************* EnvTiming EQU D'10' ;************** VARIABLES ***************** WAVE_COUNT EQU 20H WAVE_DCOUNT EQU 21H WAVE_PHASE EQU 22H WAVE_DREST EQU 23H WAVE_REST EQU 24H TONE_LEN0 EQU 25H TONE_LEN1 EQU 26H TONE_LEN2 EQU 27H MUSIC_PHASE EQU 28H MUSIC_NOTE EQU 29H WK0 EQU 2AH ; ENV_STATE EQU 30H ENV_VOL EQU 31H ENV_CNT0 EQU 32H ENV_CNT1 EQU 33H ; ;************** MACRO ******************* SetSFR macro REG,VAL ; Copy FIXED VALUE to SFR BANKSEL REG MOVLW VAL MOVWF REG endm SetVAR macro REG,VAL ; Copy FIXED VALUE to RAM (NO bank control) MOVLW VAL MOVWF REG endm ;********************************************* ;********* MAIN PROGRAM ********************** ;********************************************* ;************** ORG DEFINE ******************* ORG 0h GOTO START ORG 4h GOTO START ;************** INITIALIZE ******************** START SetSFR OSCCON ,B'01111010' ; Clock 16MHz SetSFR ANSELA ,B'00000000' ; ALL digital (DAC output = digital setting) SetSFR TRISA ,B'00000000' ; All output SetSFR DACCON1 ,B'00000000' ; DAC value = 0 SetSFR DACCON0 ,B'11110000' ; DAC1,2 Enabled SetSFR OPTION_REG ,B'00000000' ; CLK=FOSC/4 , Prescaler 1:2 SetSFR TMR0 ,0 ; Timer setting ; BANKSEL 0 ; To access RAM data CLRF WAVE_COUNT CLRF WAVE_PHASE CLRF WAVE_REST CLRF MUSIC_PHASE CALL GET_MUSIC MOVLW 255 MOVWF TONE_LEN0 MOVLW 25 MOVWF TONE_LEN1 MOVLW 2 MOVWF TONE_LEN2 ; SetVAR ENV_STATE,D'15' CLRF ENV_VOL SetVAR ENV_CNT0,D'20' SetVAR ENV_CNT1,EnvTiming ; ;************** MAIN ************************** MAIN SetSFR INTCON ,B'00000000' ; Timer0 overflow flag clear SetSFR TMR0 ,D'224' ; Timer0 set for 20us (50KHz) interval ;***************** ;GOTO WAIT_TIM0 ; *** To check basic frequency ;***************** BANKSEL 0 DECFSZ TONE_LEN0 GOTO TONE_NOT_END MOVLW D'255' MOVWF TONE_LEN0 DECFSZ TONE_LEN1 GOTO TONE_NOT_END MOVLW D'25' MOVWF TONE_LEN1 DECFSZ TONE_LEN2 GOTO TONE_NOT_END CALL GET_MUSIC MOVLW D'2' MOVWF TONE_LEN2 TONE_NOT_END ;********* Envelope control *************** DECFSZ ENV_CNT0 GOTO NOT_ENV_TIMING SetVAR ENV_CNT0,D'50' DECFSZ ENV_CNT1 GOTO NOT_ENV_TIMING MOVFW ENV_STATE ADDLW 0 ; If over 31 then hold BTFSC STATUS,Z GOTO DO_WAVE CALL ENV_DEF MOVWF ENV_VOL ; Envelpoe volume is here DECF ENV_STATE SetVAR ENV_CNT1,EnvTiming GOTO DO_WAVE NOT_ENV_TIMING ;********* Envelope control *************** DO_WAVE MOVFW WAVE_COUNT ADDLW 0 BTFSS STATUS,Z ; check if wave generating now. GOTO STILL_COUNT ; Still waving COUNT_END MOVFW WAVE_PHASE ADDLW 0 BTFSS STATUS,Z ; check if wave generating now. GOTO STILL_PHASE REST_PART MOVFW WAVE_REST ADDLW 0 BTFSS STATUS,Z ; check if rest part. GOTO STILL_REST MOVLW D'16' MOVWF WAVE_PHASE MOVFW WAVE_DCOUNT MOVWF WAVE_COUNT MOVFW WAVE_DREST MOVWF WAVE_REST STILL_REST DECF WAVE_REST,f GOTO WAIT_TIM0 STILL_PHASE MOVFW WAVE_DCOUNT MOVWF WAVE_COUNT DECF WAVE_PHASE,f GOTO SET_DAC STILL_COUNT DECF WAVE_COUNT,f GOTO WAIT_TIM0 SET_DAC MOVFW WAVE_PHASE CALL WAVE_DEF ;********************* Multiplying W with ENV_VOL ********************* MOVWF WK0 MOVLW 0 BTFSC ENV_VOL,0 ; bit 0 ADDWF WK0,W LSLF WK0 BTFSC ENV_VOL,1 ; bit 1 ADDWF WK0,W LSLF WK0 BTFSC ENV_VOL,2 ; bit 2 ADDWF WK0,W LSLF WK0 BTFSC ENV_VOL,3 ; bit 3 ADDWF WK0,W ANDLW 0f8H MOVWF WK0 BCF STATUS,C RRF WK0 RRF WK0 RRF WK0 MOVFW WK0 ;MOVFW ENV_VOL ;********************* Set the result to DAC ********************* BANKSEL DACCON1 MOVWF DACCON1 WAIT_TIM0 BANKSEL INTCON BTFSS INTCON,2 ; Wait for TIM0 overflow GOTO WAIT_TIM0 GOTO MAIN ;********************************************* ;********* SUB ROUTINES ********************** ;********************************************* GET_MUSIC BANKSEL 0 ; SetVAR ENV_STATE,D'15' ; Envelope control CLRF ENV_VOL SetVAR ENV_CNT0,D'50' SetVAR ENV_CNT1,EnvTiming ; MOVFW MUSIC_PHASE INCF MUSIC_PHASE,f CALL PATTERN_DEF ; Get one NOTE MOVWF MUSIC_NOTE ADDLW 0 BTFSC STATUS,Z ; if the data is 0 GOTO END_OF_MUSIC MOVFW MUSIC_NOTE CALL TONE_DEF_H ; get freq info (wave count) BANKSEL 0 MOVWF WAVE_DCOUNT MOVFW MUSIC_NOTE CALL TONE_DEF_L ; get freq info (tuning) BANKSEL 0 ADDLW 1 MOVWF WAVE_DREST MOVWF WAVE_REST MOVFW WAVE_DCOUNT MOVWF WAVE_COUNT MOVLW D'16' MOVWF WAVE_PHASE RETURN END_OF_MUSIC CLRF MUSIC_PHASE ; goto top of the music GOTO GET_MUSIC ;********************************************* ;********* TABLES **************************** ;********************************************* ORG 0200h ;************** Pattern define ************************** PATTERN_DEF MOVLP 02H ADDWF PCL,f RETLW D'12' ; DO RETLW D'14' ; RE RETLW D'16' ; MI RETLW D'17' ; FA RETLW D'19' ; SO RETLW D'21' ; RA RETLW D'23' ; SI RETLW D'24' ; DO RETLW D'26' ; RE RETLW D'28' ; MI RETLW D'29' ; FA RETLW D'31' ; SO RETLW D'33' ; RA RETLW D'35' ; SI RETLW D'36' ; DO RETLW 00H ; End of pattern ;************** Tone define ************************** ORG 0300h TONE_DEF_H MOVLP 03H ADDWF PCL,f RETLW D'22' ; 0 C RETLW D'21' ; 1 C# RETLW D'20' ; 2 D RETLW D'19' ; 3 D# RETLW D'17' ; 4 E RETLW D'16' ; 5 F RETLW D'15' ; 6 F# RETLW D'14' ; 7 G RETLW D'14' ; 8 G# RETLW D'13' ; 9 A RETLW D'12' ; 10 A# RETLW D'11' ; 11 B ; RETLW D'10' ; 12 C RETLW D'10' ; 13 C# RETLW D'9' ; 14 D RETLW D'9' ; 15 D# RETLW D'8' ; 16 E RETLW D'7' ; 17 F RETLW D'7' ; 18 F# RETLW D'6' ; 19 G RETLW D'6' ; 20 G# RETLW D'6' ; 21 A RETLW D'5' ; 22 A# RETLW D'5' ; 23 B ; RETLW D'4' ; 24 C RETLW D'4' ; 25 C# RETLW D'4' ; 26 D RETLW D'4' ; 27 D# RETLW D'3' ; 28 E RETLW D'3' ; 29 F RETLW D'3' ; 30 F# RETLW D'2' ; 31 G RETLW D'2' ; 32 G# RETLW D'2' ; 33 A RETLW D'2' ; 34 A# RETLW D'2' ; 35 B ; RETLW D'1' ; 36 C RETLW D'1' ; 37 C# RETLW D'1' ; 38 D RETLW D'1' ; 39 D# RETLW D'1' ; 40 E RETLW D'1' ; 41 F RETLW D'1' ; 42 F# RETLW D'0' ; 43 G RETLW D'0' ; 44 G# RETLW D'0' ; 45 A RETLW D'0' ; 46 A# RETLW D'0' ; 47 B ; TONE_DEF_L MOVLP 03H ADDWF PCL,f RETLW D'12' ; 0 RETLW D'8' ; 1 RETLW D'3' ; 2 RETLW D'0' ; 3 RETLW D'14' ; 4 RETLW D'13' ; 5 RETLW D'14' ; 6 RETLW D'14' ; 7 RETLW D'0' ; 8 RETLW D'2' ; 9 RETLW D'5' ; 10 RETLW D'9' ; 11 ; RETLW D'13' ; 12 RETLW D'3' ; 13 RETLW D'9' ; 14 RETLW D'0' ; 15 RETLW D'6' ; 16 RETLW D'14' ; 17 RETLW D'6' ; 18 RETLW D'14' ; 19 RETLW D'7' ; 20 RETLW D'0' ; 21 RETLW D'10' ; 22 RETLW D'4' ; 23 ; RETLW D'14' ; 24 RETLW D'9' ; 25 RETLW D'4' ; 26 RETLW D'0' ; 27 RETLW D'10' ; 28 RETLW D'6' ; 29 RETLW D'2' ; 30 RETLW D'14' ; 31 RETLW D'11' ; 32 RETLW D'7' ; 33 RETLW D'4' ; 34 RETLW D'1' ; 35 ; RETLW D'14' ; 36 RETLW D'12' ; 37 RETLW D'9' ; 38 RETLW D'7' ; 39 RETLW D'5' ; 40 RETLW D'3' ; 41 RETLW D'0' ; 42 RETLW D'14' ; 43 RETLW D'13' ; 44 RETLW D'11' ; 45 RETLW D'9' ; 46 RETLW D'8' ; 47 ; ;************** Waveform define ************************** WAVE_DEF MOVLP 03H ADDWF PCL,f RETLW D'0' RETLW D'0' RETLW D'1' RETLW D'2' RETLW D'4' RETLW D'5' RETLW D'4' RETLW D'5' RETLW D'12' RETLW D'14' RETLW D'15' RETLW D'15' RETLW D'8' RETLW D'4' RETLW D'2' RETLW D'0' RETLW D'0' ;************** ENVELOPE DEFINE ************************** ENV_DEF MOVLP 03H ADDWF PCL,f RETLW D'0' ;0 RETLW D'0' ;1 RETLW D'1' ;2 RETLW D'1' ;3 RETLW D'1' ;4 RETLW D'4' ;5 RETLW D'4' ;6 RETLW D'8' ;7 RETLW D'8' ;8 RETLW D'12' ;9 RETLW D'15' ;10 RETLW D'12' ;11 RETLW D'10' ;12 RETLW D'8' ;13 RETLW D'6' ;14 RETLW D'4' ;15 RETLW D'2' ;16 RETLW D'2' ;17 END