Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Periferiche Pineapple
Periferiche Pineapple
------------------------------------------------------------------
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)
// -------------------------------
// 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();