Sei sulla pagina 1di 5

/*

------------------------------------------------------------------
int adc_mode(unsigned int digits,unsigned char mode,void *buffer)
------------------------------------------------------------------
typedef struct ADC_BUFFER
{
int n; //n. canali attivi (1...4)
int size; //size di ogni buffer (short ints)
int level[2]; //livello di riempimento del buffer 1...4
short *buf[2][4]; //puntatore ai buffers fisici
}ADC_BUFFER;

modo ADC
per default = modo medie, 12 bits, ADC rate = 7 (7.5 MHz)

mode = 4...64 -> rate=12MHz...3MHz.: clock adc=60MHz/(mode+1)


channel rate=clock adc/31 total rate=channel rate/n.canali+2

1 canale mode 4 rate=12MHz/31/3=129 KHz.


2 canali mode 4 rate=12MHz/31/4=96 KHz.
3 canali mode 4 rate=12MHz/31/5=77 KHz.
4 canali mode 4 rate=12MHz/31/6=64 KHz.

2 canali mode 9 rate=6MHz./31/4=48 KHz.

digits = 10...16 (0=no change)

mode = 0 -> buffered (struct buffer)


prima di invocare questo modo occorre assegnare i primi
n canali dell' ADC (n=adc_buffer->n)
occorre dichiarare ed allocare adc_buffer e settarne
i campi n e size (ed eventualmente i buffers)
in questo caso il parametro digits assume la seguente funzione:
digits=0 -> acquisizione continua a frequenza dell' ADC
digits=n (10...) acquisizione a timer ogni n microsecondi.
in questo modo possono essere acquisiti al massimo 4 canali ADC.

Tempi di esecuzione FFT:


SIZE=1024 t=36 mSec. camp.20KHz=51 mSec
SIZE=512 t=17 mSec camp.20KHz=25 mSec
SIZE=256 t=8 mSec camp.20KHz=12 mSec
------------------------------------------------------------------
*/

// -------------------------------
// variabili
// -------------------------------
#define BUFSIZ 512 //dimensione di ogni buffer
#define BUFNUM 2 //numero di buffers
ADC_BUFFER buf; //struttura double buffer
short adc[BUFNUM][BUFSIZ]; //vettore di svuotamento buffers adc
int done=0; //flag buffers svuotati
char hold=0; //acquisizione bloccata
int rv[BUFNUM][BUFSIZ]; //vettore reali (ampiezza)
int iv[BUFNUM][BUFSIZ]; //vettore immaginari (fase)
char filter=1; //apply hammer window
// -------------------------------
// -------------------------------
// prototipi delle funzioni
// -------------------------------
void init_scheda_radio(void);
void init_scheda_ethernet(void);
void svuota_buffers(void);
void inizializza_buffers(void);
void fft_buffers(void);
void do_fft(int n);
// -------------------------------

// -------------------------------
void init_scheda_radio(void)
// -------------------------------
{
assign_input(1,P2,11);
assign_input(2,P0,4);
assign_input(3,P0,5);
assign_input(4,P0,17);
assign_input(5,P1,18);
assign_input(6,P1,20);

assign_output(1,P1,3);
assign_output(2,P1,5);
assign_output(3,P0,16);
assign_output(4,P2,21);
assign_output(5,P0,15); //carica batteria
assign_output(6,P1,31); //220v a
assign_output(7,P1,30); //220v b

assign_adc(1,P0,25);
assign_adc(2,P0,26);
assign_adc(3,P0,23); //tensione batteria
adc_mode(12,16,0);
assign_pwm(1,P1,-6);
assign_pwm(2,P1,2);

LPC_IOCON->P0_24 |= 0x08;
LPC_IOCON->P1_30 |= 0x08;
LPC_IOCON->P1_31 |= 0x08;
}
// -------------------------------

// -------------------------------
void init_scheda_ethernet(void)
// -------------------------------
{
assign_input(1,P1,20);
assign_input(2,P1,18);
assign_input(3,P0,17);
assign_input(4,P2,22);
assign_input(5,P2,26);
assign_input(6,P2,27);
assign_input(7,P2,23);
assign_input(8,P1,2);

assign_output(1,P2,25);
assign_output(2,P2,21);
assign_output(3,P1,3);
assign_output(4,P1,5);
assign_output(5,P0,16);
assign_output(6,P1,6);
assign_output(7,P0,15); //carica batteria

assign_adc(1,P0,23);
assign_adc(2,P0,24);
assign_adc(3,P0,25);
assign_adc(4,P0,26); //tensione batteria
adc_mode(12,16,0);

LPC_IOCON->P1_30 |= 0x08;
LPC_IOCON->P1_31 |= 0x08;
}
// -------------------------------

// -------------------------------
void svuota_buffers(void)
// -------------------------------
{
int i,j;
if (buf.n==0) return; //se n. di buffers non ancora definito esce
for (i=0;i<2;i++) //esamina i 2 doppi buffers ciascuno composto da
buf.n (ovvero BUFNUM) canali di BUFSIZ short ints
{
if (buf.level[i]>=buf.size) //se doppio buffer pieno (2 buffers di n canali)
{
if (!done) //se svuotato il precedente ...
{
for (j=0;j<buf.n;j++)
{
memcpy(adc[j],buf.buf[i][j],buf.size*2); //salva canali (short int
quindi *2)
}
done=1; //segnala buffer nuovamente riempito
}
buf.level[i]=0; //consente nuovo riempimento da interrupt adc
}
}
}
// -------------------------------

// -------------------------------
void inizializza_buffers(void)
// -------------------------------
{
int tbuf; //tempo di riempimento di un buffer
// assign_adc(1,P0,xx); //assegno pin primo canale adc
// assign_adc(2,P0,xx); //assegno pin secondo canale adc
// ecc... (occorre assegnare BUFNUM adc pins (gi� fatto in init_scheda_xx))
buf.n=BUFNUM; //2 canali da acquisire
buf.size=BUFSIZ; //BUFSIZ campioni per canale
// acquisizione a tempi fissi (clock su Timer 3) questo modo consente di
campionare a frequenza diversa da quella di acquisizione dell' ADC
adc_mode(12,4,NONE); //assegno frequenza di campionamento
adc: adc 12 bit, clock adc=60MHz/(4+1)=12MHz.
//acquisiz=12MHz/31=386.5KHz.
canali=BUFNUM(+2) acquisiz= 96.6KHz. max (se free running e BUFNUM=2)
adc_mode(50 USec,DOUBLE_BUFFERED,&buf); //assegno modo tempi fissi double
buffered: sample every 50 Usec. su buf (20 KHz.) (deve essere minore di freq. max)
tbuf=(50 * BUFSIZ)/1000; //i buffers verranno riempiti in
50USec*BUFSIZ (25 msec se BUFSIZ=512) indipendente da BUFNUM
remove_timer(svuota_buffers);
exec_timer(svuota_buffers,tbuf/2,1); //attivo routine di svuotamento
buffers acquisiti (verr� eseguita 2 volte pi� spesso del T di riempimento)
hold=0; //consente utilizzo dei buffers
}
// -------------------------------

// -------------------------------
void fft_buffers(void)
// -------------------------------
{
if (done) //se buffers pieni ...
{
if (!hold) //se buffers gi� usati
{
hold=1; //blocca ulteriori acquisizioni e inizia fft
do_fft(BUFNUM);
hold=2; //buffers usabili (fai quello che vuoi con il contenuto dei
buffers rv[0...BUFNUM-1][0...BUFSIZ/2-1])
}
done--; //consente nuovo riempimento
}
}
// -------------------------------

// -------------------------------
void do_fft(int n)
// -------------------------------
{
int i,j;
for(j=0;j<n;j++)
{
for (i=0;i<BUFSIZ;i++)
{
rv[j][i]=adc[j][i];
iv[j][i]=0;
}
ifft(rv[j],iv[j],BUFSIZ,filter<<1,1); //real,immag
ipowr(rv[j],iv[j],rv[0],iv[j],BUFSIZ/2,1); //real,imag->ampl,phase
}
}

/*
in main:
init_scheda_radio();
inizializza_buffers();

while(1) //o altro (potrebbe essere in un altro task)


{
fft_buffers(); //se sono arrivati nuovi dati fanne la FFT e metti hold=2
if (hold==2)
{
// fai quello che vuoi con spettro FFT (contenuto dei buffers rv[0...BUFNUM-
1][0...BUFSIZ/2-1])
hold=0; //avanti con nuove acquisizioni
}
}
*/

Potrebbero piacerti anche