// Arduino Mega2560(16MHz), 256KB Flash, 8KB SRAM, 4KB EEPROM // Timer0(8)....CKscf(400kHz)...OC0A // Timer1(16)...ADATE(50us)...OCR1B // Timer2(8)....LCD timing // Timer5(16)...LEDout, EXTout #define DAF 0 #define RAF 1 #define FAF 2 #define DTF1 3 #define DTF2 4 #define DTF3 5 #define M 400 #define N 3100 #define Fs 10000 #define Ft1 50 #define Ft2 100 #define Ft3 200 #define NG 20 #define MUTE 500 #include PROGMEM prog_uint8_t dB[]={255,40,35, 30, 25, 20, 15, 10, 5, 0}; PROGMEM prog_uint16_t Mag[]={0,41,73,129,230,410,728,1295,2303,4095}; volatile uint8_t swcntr; uint8_t Ef, G, G0, Gf, MODE=0, admux=0; uint32_t S; int16_t X[N], E, E0, P, Pmax, R, Fa, Q, Qmax, mute=MUTE; #include "aafxlib.h" void setup(){ uint8_t tmp; DDRB=0x17; PORTB=0x01; // xxxoxooo DDRC=0x3f; PORTC=0x00; // xxoooooo DDRD=0x7f; PORTD=0x80; // rooooooo DDRL=0x18; PORTL=0x00; // xxxooxxx TCCR0A=0x00;TCCR0B=0x03;// WGM0=000, CS0=011(CK/32) TCCR2A=0x42;TCCR2B=0x01;// COM2A=01, WGM2=010(CTC/OCRA), CS2=001(CK/1) OCR2A=20; // CKscf=400kHz TCCR1A=0x00;TCCR1B=0x09;// WGM1=0100(CTC), CS1=001(CK/1) OCR1A=OCR1B=799; // 50us TCCR5A=0xa3;TCCR5B=0x09;// WGM5=0111(10bit FastPWM), CS5=001(CK/1) ADCSRA=0xad; // ADEN=1, ADATE=1, ADIE=1,ADPS=110(ADCK/32) ADCSRB=0x05; // if(TCNT1==OCR1B) ADC start ADMUX=0xe0; // REFS=11(2.56V), ADLAR=1, MUX=000000(CH0) SPCR=0x50; SPSR=0x00; // SPE=1,DORD=0,MSTR=1,CPOL=0,CPHA=0,SPR=00(fck/4) tmp=SPSR; tmp=SPDR; TIMSK0&=~(1<0){ // SWオンなら P=0; if(++MODE>DTF3) MODE=DAF; // DAF→RAF→FAF→DTF1→DTF2→DTF3... while(swcntr>0); // SWオフを待つ E0=~E; R=0; S=0; P=0; mute=MUTE; } if(Ef){ mute=MUTE; lcdfbk(); Ef=0; } if(Gf){ mute=MUTE; lcddb(G); Gf=0; } } // admux ... 00(E) → 01(A) → 10(G) → 11(A) ISR(ADC_vect){ // ADC complete(50us) uint8_t A, w1; int16_t A16,b; int32_t x1, x2; TIFR1|=0x06; // clear OCF1B, OCF1A A16=ADCL; A16=((uint16_t)(A=ADCH)<<2)+(A16>>6); //000000dddddddddd(0〜1023) if(admux & 0x01){ // 01 or 11 ... 100us ADMUX=(admux&0x02)?0xe0:0xe1; // 次はCH0/CH1 if(MODE==DAF){ // *** DAF/DVF *** daout10(X[P]); // Pmaxサンプル前のデータを出力 X[P]=A16; if(++P>=Pmax) P=0; }else if(MODE==RAF){ // *** RAF/RVF *** if(R==0) daout12(A16<<2); else{ b=((int32_t)((A16<<2)-2048)*(100-R)+(int32_t)X[P]*R)/100; //b:-2048..2047 daout12(b+2048); X[P]=b; if(++P>=500) P=0; } }else if(MODE==FAF){ // *** FAF *** if(Fa==0) daout12(A16<<2); else{ P+=(uint16_t)M/(Fs/Fa); if(P>=M) P-=M; daout12(((int32_t)pgm_read_byte(&W[P])-128)*(A16-512)/32+2047); // -128..127 -512..511 } }else if(MODE>=DTF1){ // *** DTF1..3 *** w1=pgm_read_byte(&W[R]); // 0..255 x1=X[P]; x2=X[(P>12);// 0..M*2 A16-=512; if(A16<0) A16=-A16; // A16: 0..512 S+=A16; // S: 0..512*M/2 if(++R>=M/2){ // 矩形窓で絶対値のM/2個の平均を計算 X[P]=(S>>8); // 0..M if(++P>=Pmax) P=0; R=0; S=0; } Q+=((MODE==DTF1)?(M/(Fs/Ft1)):(MODE==DTF2)?(M/(Fs/Ft2)):(M/(Fs/Ft3))); if(Q>=M) Q-=M; // W[]のポインタ(FtにするQのステップ) } }else if(admux & 0x02){ // 10 val of A1(VR)...0..255 ADMUX=0xe2; // 次はCH2 G=(uint16_t)A*10/256; // G: 0..9 dbout(pgm_read_word(&Mag[G])); if(G!=G0){ Gf=1; G0=G; } }else{ // 00 ADMUX=0xe2; // 次はCH2 if(MODE==DAF) E=Pmax=(uint16_t)(A>>3)*100;// E,Pmax:0,100,..,3100 else if(MODE==RAF) E=R =(uint16_t)A*8/256*10; // E,R: 0,10,20,...,70 else if(MODE==FAF) E=Fa=(uint16_t)A*11/256*50; // E,Fa: 0,50,...,500 else if(MODE>=DTF1) E=Pmax=(A>>3)+2; // E,Pmax: 2..33 if(E!=E0){ Ef=1; E0=E; } } admux++; if((PIND&0x80)==0) swcntr=200; else if(swcntr>0) swcntr--; }