#device PIC16F688, ADC=8 // Spectrum Analyzer & Scope Aug, 2008 #fuses hs,mclr,put,noprotect,nocpd,nobrownout,nowdt,nofcmen,noieso // nothing special needed here #use delay(clock=20000000) // compilerspecific delays for 8MHz struct{int1 e:1;int1 rs:1;int x:4;}d; // C0=E,C1=RS,C2-C5=D5-D9,4bit,Single Line #byte d=0x07 // span struct over port const int font[256]={ // fonttable, 8 symbols skipped(max array size) 0b00000000,0b00011100,0b00100010,0b01000001,0b00000000,/* ( */ 0b00000000,0b01000001,0b00100010,0b00011100,0b00000000,/* ) */ 0b00010100,0b00001000,0b00111110,0b00001000,0b00010100,/* * */ 0b00001000,0b00001000,0b00111110,0b00001000,0b00001000,/* + */ 0b00000000,0b00000101,0b00000110,0b00000000,0b00000000,/* , */ 0b00001000,0b00001000,0b00001000,0b00001000,0b00001000,/* - */ 0b00000000,0b00000011,0b00000011,0b00000000,0b00000000,/* . */ 0b00000010,0b00000100,0b00001000,0b00010000,0b00100000,/* / */ 0b00111110,0b01000101,0b01001001,0b01010001,0b00111110,/* 0 */ 0b00000001,0b00100001,0b01111111,0b00000001,0b00000001,/* 1 */ 0b00100001,0b01000011,0b01000101,0b01001001,0b00110001,/* 2 */ 0b01000010,0b01000001,0b01010001,0b01101001,0b01000110,/* 3 */ 0b00001100,0b00010100,0b00100100,0b01111111,0b00000100,/* 4 */ 0b01110010,0b01010001,0b01010001,0b01010001,0b01001110,/* 5 */ 0b00011110,0b00101001,0b01001001,0b01001001,0b00000110,/* 6 */ 0b01000000,0b01000111,0b01001000,0b01010000,0b01100000,/* 7 */ 0b00110110,0b01001001,0b01001001,0b01001001,0b00110110,/* 8 */ 0b00110000,0b01001001,0b01001001,0b01001010,0b00111100,/* 9 */ 0b00000000,0b00110110,0b00110110,0b00000000,0b00000000,/* : */ 0b00000000,0b00110101,0b00110110,0b00000000,0b00000000,/* ; */ 0b00001000,0b00010100,0b00100010,0b01000001,0b00000000,/* < */ 0b00010100,0b00010100,0b00010100,0b00010100,0b00010100,/* = */ 0b00000000,0b01000001,0b00100010,0b00010100,0b00001000,/* > */ 0b00100000,0b01000000,0b01000101,0b01001000,0b00110000,/* ? */ 0b00100110,0b01001001,0b01001111,0b01000001,0b00111110,/* @ */ 0b00111111,0b01000100,0b01000100,0b01000100,0b00111111,/* A */ 0b01111111,0b01001001,0b01001001,0b01001001,0b00110110,/* B */ 0b00111110,0b01000001,0b01000001,0b01000001,0b00100010,/* C */ 0b01111111,0b01000001,0b01000001,0b00100010,0b00011100,/* D */ 0b01111111,0b01001001,0b01001001,0b01001001,0b01000001,/* E */ 0b01111111,0b01001000,0b01001000,0b01001000,0b01000000,/* F */ 0b00111110,0b01000001,0b01001001,0b01001001,0b00101111,/* G */ 0b01111111,0b00001000,0b00001000,0b00001000,0b01111111,/* H */ 0b01000001,0b01000001,0b01111111,0b01000001,0b01000001,/* I */ 0b00000010,0b00000001,0b01000001,0b01111110,0b01000000,/* J */ 0b01111111,0b00001000,0b00010100,0b00100010,0b01000001,/* K */ 0b01111111,0b00000001,0b00000001,0b00000001,0b00000001,/* L */ 0b01111111,0b00100000,0b00011000,0b00100000,0b01111111,/* M */ 0b01111111,0b00010000,0b00001000,0b00000100,0b01111111,/* N */ 0b00111110,0b01000001,0b01000001,0b01000001,0b00111110,/* O */ 0b01111111,0b01001000,0b01001000,0b01001000,0b00110000,/* P */ 0b00111110,0b01000001,0b01000101,0b01000010,0b00111101,/* Q */ 0b01111111,0b01001000,0b01001100,0b01001010,0b00110001,/* R */ 0b00110001,0b01001001,0b01001001,0b01001001,0b01000110,/* S */ 0b01000000,0b01000000,0b01111111,0b01000000,0b01000000,/* T */ 0b01111110,0b00000001,0b00000001,0b00000001,0b01111110,/* U */ 0b01111100,0b00000010,0b00000001,0b00000010,0b01111100,/* V */ 0b01111110,0b00000001,0b00001110,0b00000001,0b01111110,/* W */ 0b01100011,0b00010100,0b00001000,0b00010100,0b01100011,/* X */ 0b01110000,0b00001000,0b00000111,0b00001000,0b01110000,/* Y */ 0b01000011,0b01000101,0b01001001,0b01010001,0b01100001};/* Z */ const signed int mul[16][16]={49,42,35,28,21,14,7,0,-7,-14,-21,-28,-35,-42,-49,-56,42,36,30,24,18,12,6,0,-6,-12,-18,-24,-30, -36,-42,-48,35,30,25,20,15,10,5,0,-5,-10,-15,-20,-25,-30,-35,-40,28,24,20,16,12,8,4,0,-4,-8,-12,-16,-20,-24,-28,-32,21,18,15, 12,9,6,3,0,-3,-6,-9,-12,-15,-18,-21,-24,14,12,10,8,6,4,2,0,-2,-4,-6,-8,-10,-12,-14,-16,7,6,5,4,3,2,1,0,-1,-2,-3,-4,-5,-6,-7, -8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,-14,-12,-10,-8,-6,-4,-2,0,2,4,6,8,10,12,14,16,-21, -18,-15,-12,-9,-6,-3,0,3,6,9,12,15,18,21,24,-28,-24,-20,-16,-12,-8,-4,0,4,8,12,16,20,24,28,32,-35,-30,-25,-20,-15,-10,-5,0,5, 10,15,20,25,30,35,40,-42,-36,-30,-24,-18,-12,-6,0,6,12,18,24,30,36,42,48,-49,-42,-35,-28,-21,-14,-7,0,7,14,21,28,35,42,49,56, -56,-48,-40,-32,-24,-16,-8,0,8,16,24,32,40,48,56,64}; const int sin[64]={8,8,9,10,11,11,12,13,13,14,14,15,15,15,15,15,15,15,15,15,15,15,14,14,13,13,12,11,11,10,9,8,8,7,6,5,4,4,3, 2,2,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,2,2,3,4,4,5,6,7}; const int cos[64]={15,15,15,15,15,15,14,14,13,13,12,11,11,10,9,8,8,7,6,5,4,4,3,2,2,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,2,2,3,4,4,5, 6,7,7,8,9,10,11,11,12,13,13,14,14,15,15,15,15,15}; //const int log[16]={1,2,3,4,5,6,7,8,9,10,11,13,15,18,23,32}; const int log[16]={0,1,2,3,4,5,6,7,8,9,10,11,13,16,23,32}; volatile int i,mode,buf[40]; #int_ra // button press interrupt entry point void button_isr(){int p;if(mode==3)mode=0; else mode++;for(p=0;p<200;p++)while(!input(41));} // wtf debounce, toggle modi, void dnib(int n){d.x=n;delay_cycles(1);d.e=1;delay_us(6);d.e=0;} // neat lcd driver void dbyt(int r,n){d.rs=d.e=0;delay_us(38);d.rs=r;dnib(n>>4);dnib(n&15);} // min delay may vary with lcd void dput(int c){dbyt(1,c);} void graph(int pen){int col,line,block=0,c=0; // draw graphic blocks for(dbyt(0,64);block<39;block+=5,c+=2,dbyt(1,i)){ // set LcdCGram-start, cycle trough lcdblocks for(line=7;line-->0;dbyt(1,i)){ // write bytes to dislay if(pen==0){for(col=0;col<5;(i<<=1)+=bit_test(buf[col++ +block],line));} // create patterns by crosscomparing columns with linecounter if(pen==1){for(col=0;col<5;(i<<=1)+=(line==((buf[col++ +block]))));} // decimalcompare line+buf &shift hits to CGram if(pen==2){col=(line<=buf[c]);(i<<=1)+=col;(i<<=1)+=col; // create dft bars col=(line<=buf[c+1]);(i<<=2)+=col;(i<<=1)+=col;}}}} void gput(int key){int line,col=0; // calc marquee for(col=0;col<5;graph(0),delay_ms(47),col++){ // cycle cols per symbol for(line=0;line<39;buf[line]=buf[++line]);buf[39]=(key==32?(0):font[(key-40)*5+col]);}} //rotate, fix space, plot new col void scope(){i=0; while(++i&&(read_adc()<132));while(++i&&(read_adc()>120)); // redneck trigger for(read_adc(1),i=0;i<40;buf[i++]=7-((196-read_adc(6))>>4),read_adc(1))delay_us(220);graph(1);} // fetch& scale AD to 7 pixel // fill buffer// for(i=0;i<40;buf[i++]/=37); void dft(){int off,ch;signed int16 cx[32]; // discrete fourier transformation for(read_adc(1),i=0;i<32;i++){buf[i]=(read_adc(6)>>4);read_adc(1);delay_us(44);cx[i]=0;}// 4 fill buffer, clear complex for(i=0;i<32;i++){ // cycle samples for(ch=0;ch<16;ch++){ // channels cx[ch]+=mul[buf[i]][sin[off=(i*log[ch])%64]]; // calc imag&real with log-(co)sine entrypoints cx[ch|16]+=mul[buf[i]][cos[off]];}} // use table for multiplication for(i=0;i<16;i++){buf[i]=(abs(cx[i])+abs(cx[i|16]))>>6;}graph(2);} // pseudocalc power and plot void main(){mode=1;setup_oscillator(0);setup_timer_1(0x85|0x30); setup_comparator(0xff07);setup_adc(0x50);setup_adc_ports(4);set_adc_channel(2); // no comp, setup analog port set_tris_a(0b00000110);port_a_pullups(0b00000010);set_tris_c(0);d.rs=d.e=0; // config pins, pullup for button delay_ms(20);for(i=1;i<=3;++i){dnib(3);delay_ms(5);}dnib(2); // lcd warmup dbyt(0,32);dbyt(0,12);dbyt(0,1);dbyt(0,6);delay_ms(32); // lcd init 32/40 single/multiline dbyt(0,128);dbyt(1,91);for(i=0;i<8;i++)dbyt(1,i);dbyt(1,93); // set graph-position [and brackets] enable_interrupts(0x0BC0);enable_interrupts(0x020B08); // interrupt for button for(i=0;i<40;buf[i++]=0);printf(gput,"SPECTRUM ANALYZER "); // clear buffer, splash screen while(1){ dbyt(0,138);printf(dput,"%c%Lu ",126,get_timer1());set_timer1(0); // lcd use example: measure refresh if(mode)dft();else scope();}}