; FFT Color Organ ; 12/99 ; Luhan Monat device PIC16F84,hs_osc,wdt_on,protect_off VERSION = 11 ADCS = ra.0 ;A/D chip select ADCLK = ra.1 ;A/D clock ADDAT = ra.2 ;A/D data org 12 w_save ds 1 s_save ds 1 data ds 1 del1 ds 1 del2 ds 1 count ds 1 sumlo ds 1 sumhi ds 1 qsumlo ds 1 qsumhi ds 1 temp ds 1 samps ds 1 dfacto ds 1 ref ds 1 chans ds 5 ;current level of each channel org 0 goto start org 4 inter movwf w_save ;save w register swapf status,w ;reverse nibble of status movwf s_save ;in status save bcf status,5 ;now, force to primary registers :end swapf s_save,w ;re-reverse status data movwf status ;restore to status register swapf w_save ;pre-swap w saved swapf w_save,w ;swap into w without affection status bcf INTCON,1 ;clear rb,0 int flag reti ;enable global interrupt start bsf STATUS,5 ;alt regs movlw 00000000b ; movwf TRISB movlw 00100b movwf TRISA bcf STATUS,5 movlw 128 movwf ref ; find each channel level. ; in between each evalualtion, see if time to turn on each ; channel output (effectively PWM). cycle movlw 40 call eval movwf chans movlw 0ffh call lites movlw 70 call eval movwf chans+1 movlw 0fCh call lites movlw 130 call eval movwf chans+2 movlw 0F0h call lites movlw 180 call eval movwf chans+3 movlw 0C0h call lites movlw 250 call eval movwf chans+4 movlw 080h call lites goto cycle ; as each channel volume achieves higher order bits, ; turn that channel on sooner in the sequence. lites clrf rb movwf temp andwf chans,w btfss z bsf rb,1 movf temp,w andwf chans+1,w btfss z bsf rb,2 movf temp,w andwf chans+2,w btfss z bsf rb,3 movf temp,w andwf chans+3,w btfss z bsf rb,4 movf temp,w andwf chans+4,w btfss z bsf rb,5 ret ; delay loop proportional to 'w' squared ; location of watch dog timer reset wsq movwf del1 :xx movwf del2 :yy clrwdt nop nop nop nop nop decfsz del2 goto :yy decfsz del1 goto :xx ret ; find level in one channel ; returns w-squared value (effectively making response exponential) eval call dtmf bcf c rrf sumhi rrf sumlo rrf sumhi rrf sumlo rrf sumhi rrf sumlo bcf c rrf qsumhi rrf qsumlo rrf qsumhi rrf qsumlo rrf qsumhi rrf qsumlo movf sumlo,w call square movwf data movf qsumlo,w call square addwf data,w ret ; perfoms FFT on audio signal - returns w-sqwared value. ; note: low sample count creates wide bandwidth. dtmf movwf dfacto movlw 2 ;increase bandwidth(11) movwf samps clrf sumlo clrf sumhi clrf qsumlo clrf qsumhi :x2 call :xgo call sadsum call :xgo call sadqsm call :xgo sublw 0 call sadsum call :xgo sublw 0 call sadqsm decfsz samps goto :x2 ret :xgo movf dfacto,w call micro call atod subwf ref,w ret micro movwf del1 :mdx nop nop nop nop ; nop nop nop ;lower freq response(11) decfsz del1 goto :mdx ret ; adds 2's compliment value in 'w' to sumlo/sumhi. sadsum movwf temp btfss temp,7 goto :add1 addwf sumlo btfss c decf sumhi ret :add1 addwf sumlo btfsc c incf sumhi ret ; same as above for qsumlo/qsumhi. sadqsm movwf temp btfss temp,7 goto :add1 addwf qsumlo btfss c decf qsumhi ret :add1 addwf qsumlo btfsc c incf qsumhi ret ; reads ADC0831 serial d/a atod bcf ADCS ;CS low clrf data ;clear data byte bsf ADCLK ;first clock bcf ADCLK bsf ADCLK ;second clock bcf ADCLK movlw 8 ;set bit count movwf count ;into count bcf status,0 ;clear carry bit atod2 rlf data ;hi order is first bsf ADCLK ;clock hi btfsc ADDAT ;test input bit bsf data,0 ;if hi - set data bit bcf ADCLK ;clock low decfsz count ;8 times goto atod2 bsf ADCS ;CS hi movf data,w ;data in w ret ; (for test purposes only) pulse movwf temp bsf rb,0 :p2 decfsz temp goto :p2 bcf rb,0 ret org 100h ; performes squaring operation on 'w' - returns 8 bit value in 'w'. square movwf temp btfsc temp,7 comf temp movf temp,w clrf PCLATH bsf PCLATH,0 addwf PCL retw 000,000,000,000,000,000,000,000 retw 001,001,001,001,002,002,003,003 retw 004,004,005,005,006,006,007,008 retw 009,009,010,011,012,013,014,015 retw 016,017,018,019,020,021,022,023 retw 025,026,027,028,030,031,033,034 retw 036,037,039,040,042,043,045,047 retw 049,050,052,054,056,058,060,062 retw 064,066,068,070,072,074,076,078 retw 081,083,085,087,090,092,095,097 retw 100,102,105,107,110,112,115,118 retw 121,123,126,129,132,135,138,141 retw 144,147,150,153,156,159,162,165 retw 169,172,175,178,182,185,189,192 retw 196,199,203,206,210,213,217,221 retw 225,228,232,236,240,244,248,252 end QEDm