;;variable mode cv quantizer for 16F684 ;usting external 20mhz clock ;Input 0-5VDC on pin 10, ;PIN 9: mode select, Major, Major Pentatonic, Minor, Minor Pentatonic, Blues Pentatonic, Whole tones, Chromatic ; output PWM on Pin 5 ; ; ;Rev2.0 ;5-31-2010 ; ;equates start here TMR0 EQU 01H STATUS EQU 3 ZEROBIT EQU 2 CARRY EQU 0 PORTC EQU 07h TMR2 EQU 11h T2CON EQU 12h PR2 EQU 92h CCPR1L EQU 13h CCP1CON EQU 15h ADRESL EQU 9Eh ADRESH EQU 1Eh ANSEL EQU 91h VOLTHI EQU 40h VOLTLO EQU 41h PIR1 EQU 0Ch ADCON0 EQU 1Fh TRISC EQU 87h ADCON1 EQU 9Fh PORTA EQU 05h OSCCON EQU 8Fh STEPCOUNT EQU 42h MODECOUNT EQU 43h MODEHI EQU 44h MODELO EQU 45h MODESEL EQU 46h MODE_TEMP EQU 47h MAXOUT EQU 48h OUT_LO_TEMP EQU 49h PCL EQU 2 ;equates end here ;************************* List P=16F684 ORG 0 GOTO START ;*********************** ;first set up PWM START MOVLW B'00000100' MOVWF T2CON BSF STATUS,5 MOVLW B'00100000' MOVWF TRISC BCF STATUS,5 CLRF PORTC CLRF PORTA BSF STATUS,5 movlw D'255' movwf PR2 BCF STATUS,5 MOVLW B'00000000' MOVWF CCPR1L BSF STATUS,5 MOVLW B'11011111' MOVWF TRISC BCF STATUS,5 MOVLW B'00001100' MOVWF CCP1CON BCF STATUS,5 CLRF PORTC ;now setup the ADC MOVLW B'00010001' MOVWF ADCON0 BSF STATUS,5 MOVLW B'01100000' MOVWF ADCON1 MOVLW B'00000011' MOVWF TRISC MOVLW B'00110000' MOVWF ANSEL BCF STATUS,5 ;start main loop ;get AD reading BEGIN CLRF STEPCOUNT ;first clear the counters for our lookup tables CLRF MODECOUNT MOVLW B'00010001' ;DO AD READING FOR VOLTAGE TO QUANTIZE MOVWF ADCON0 BSF ADCON0,1 WAIT BTFSC ADCON0,1 GOTO WAIT MOVF ADRESH,W MOVWF VOLTHI MOVLW B'00010101' MOVWF ADCON0 BSF ADCON0,1 ;DO AD READING FOR MODE BTFSC ADCON0,1 ;STORE IT IN MODESEL GOTO $-1 MOVF ADRESH,W MOVWF MODESEL MODESCAN MOVFW MODECOUNT ;this compares the voltage from CALL MODEMAX ;MODESEL to a number in the MODEMAX lookup table MOVWF MODE_TEMP ;when it doesn't result in a carry bit MOVFW MODESEL ;we increase the modecount counter so SUBWF MODE_TEMP,W ;we can try the next number to compare BTFSC STATUS,0 ;it to. Eventually we find one that GOTO SETMODE ;works and we go to MODESET INCF MODECOUNT GOTO MODESCAN SETMODE MOVFW MODECOUNT ;We call FIND_MODE_LO AND FIND_MODE_HI CALL FIND_MODE_HI ;in order to set the mode bits for later MOVWF MODEHI ;we're using the MODECOUNT for these tables too MOVFW MODECOUNT ;next we start comparing input voltages CALL FIND_MODE_LO MOVWF MODELO GOTO FIRST MODEMAX ADDWF PCL,F RETLW .36 RETLW .73 RETLW .108 RETLW .144 RETLW .180 RETLW .216 RETLW .255 FIND_MODE_LO ADDWF PCL,F RETLW B'10110101' RETLW B'10010101' RETLW B'10101101' RETLW B'10101001' RETLW B'11101001' RETLW B'01010101' RETLW B'11111111' FIND_MODE_HI ADDWF PCL,F RETLW B'00001010' RETLW B'00000010' RETLW B'00000101' RETLW B'00000100' RETLW B'00000100' RETLW B'00000101' RETLW B'00001111' CHECKC1 INCF STEPCOUNT ;increase the stepcount, each step is a musical half-tone RRF MODEHI ;shift the mode bits to see what we're dealing with RRF MODELO BCF MODEHI,3 BTFSC STATUS,0 BSF MODEHI,3 FIRST BTFSS MODELO,0 ;first see if we're on a step that is active according to our mode bits GOTO CHECKC1 ;if not, we try again with the step count increased and the mode bits shifted MOVF STEPCOUNT,W ;if so, we call STEPLEVEL to see what voltage we're comparing our input to CALL STEPLEVEL MOVWF MAXOUT ;we store this in MAXOUT, but MAXOUT isn't where we need it yet CALL CMAX ;we need to call CMAX in order to see what the halfway point is between this note and the next highest note is, so we have a smooth ADDWF MAXOUT ;transition between notes. The value we get from CMAX is added to MAXOUT which sets the maximum voltage on the input which would trigger this note. BTFSC STATUS,0 ;we then check if this addition resulted in a number higher than 255. CALL SETMAX ;if it has, that's bad news for us, we call setmax which will set MAXOUT to 255. Otherwise the top notes won't show up. MOVF VOLTHI,W SUBWF MAXOUT,W ;now we compare our MAXOUT value with VOLTHI which represents the input voltage BTFSS STATUS,0 GOTO CHECKC1 ;if the input voltage was higher than MAXOUT we go back up to CHECK1 and try the next note MOVF STEPCOUNT,W ;if it's lower or equal to MAXOUT we need to set our PWM to the appropriate note CALL STEPLEVEL MOVWF CCPR1L ;we call STEPVALUE again and move our result to CCPR1L which controls the 8 most significant bits of the PWM MOVF STEPCOUNT,W CALL OUT_LO ;now we call OUT_LO which will retreive the two least significant bits for the PWM MOVWF OUT_LO_TEMP BSF CCP1CON,5 ;we now set the two bits in CCP1CON which correspond to these bits. BTFSS OUT_LO_TEMP,1 BCF CCP1CON,5 BSF CCP1CON,4 BTFSS OUT_LO_TEMP,0 BCF CCP1CON,4 GOTO BEGIN ;then we start alllllll over again. SETMAX MOVLW .255 MOVWF MAXOUT RETURN STEPLEVEL ADDWF PCL,F RETLW .0 RETLW .4 RETLW .9 RETLW .13 RETLW .17 RETLW .21 RETLW .25 RETLW .30 RETLW .34 RETLW .38 RETLW .43 RETLW .47 RETLW .51 RETLW .55 RETLW .59 RETLW .64 RETLW .68 RETLW .72 RETLW .76 RETLW .81 RETLW .85 RETLW .89 RETLW .93 RETLW .98 RETLW .102 RETLW .106 RETLW .110 RETLW .115 RETLW .119 RETLW .123 RETLW .128 RETLW .132 RETLW .136 RETLW .140 RETLW .145 RETLW .149 RETLW .153 RETLW .157 RETLW .162 RETLW .166 RETLW .170 RETLW .174 RETLW .179 RETLW .183 RETLW .187 RETLW .191 RETLW .196 RETLW .200 RETLW .204 RETLW .208 RETLW .213 RETLW .217 RETLW .221 RETLW .225 RETLW .230 RETLW .234 RETLW .238 RETLW .242 RETLW .246 RETLW .251 RETLW .255 OUT_LO ADDWF PCL,F RETLW B'00000000' RETLW B'00000001' RETLW B'00000010' RETLW B'00000011' RETLW B'00000000' RETLW B'00000001' RETLW B'00000010' RETLW B'00000011' RETLW B'00000000' RETLW B'00000001' RETLW B'00000010' RETLW B'00000011' RETLW B'00000000' RETLW B'00000001' RETLW B'00000010' RETLW B'00000011' RETLW B'00000000' RETLW B'00000001' RETLW B'00000010' RETLW B'00000011' RETLW B'00000000' RETLW B'00000001' RETLW B'00000010' RETLW B'00000011' RETLW B'00000000' RETLW B'00000001' RETLW B'00000010' RETLW B'00000011' RETLW B'00000000' RETLW B'00000001' RETLW B'00000010' RETLW B'00000011' RETLW B'00000000' RETLW B'00000001' RETLW B'00000010' RETLW B'00000011' RETLW B'00000000' RETLW B'00000001' RETLW B'00000010' RETLW B'00000011' RETLW B'00000000' RETLW B'00000001' RETLW B'00000010' RETLW B'00000011' RETLW B'00000000' RETLW B'00000001' RETLW B'00000010' RETLW B'00000011' RETLW B'00000000' RETLW B'00000001' RETLW B'00000010' RETLW B'00000011' RETLW B'00000000' RETLW B'00000001' RETLW B'00000010' RETLW B'00000011' RETLW B'00000000' RETLW B'00000001' RETLW B'00000010' RETLW B'00000011' RETLW B'00000000' RETLW B'00000001' RETLW B'00000010' RETLW B'00000011' RETLW B'00000000' RETLW B'00000001' RETLW B'00000010' RETLW B'00000011' RETLW B'00000000' RETLW B'00000001' RETLW B'00000010' RETLW B'00000011' CMAX BTFSC MODELO,1 RETLW .2 BTFSC MODELO,2 RETLW .4 BTFSC MODELO,3 RETLW .6 BTFSC MODELO,4 RETLW .9 BTFSC MODELO,5 RETLW .11 BTFSC MODELO,6 RETLW .13 BTFSC MODELO,7 RETLW .15 BTFSC MODEHI,0 RETLW .17 BTFSC MODEHI,1 RETLW .19 BTFSC MODEHI,2 RETLW .21 BTFSC MODEHI,3 RETLW .23 BTFSC MODELO,0 RETLW .26 END