hola a todos quisiera una ayuda con este codigo, es un diseño para una transmision OFDM con modulacion QPSK, utilice el codigo de ejemplo de Micrchip (ce_18) para realizar la IFFT -FFT (256 puntos), claro todo el diseño lo simule previamente en matlab.
bueno llevo ya mas de un mes estancado con la funcion IFF- FFT intentando diferentes opciones, mi problema es que quiero verificar si luego de la IFFT puedo recuperar nuevamente mis datos originales que no son mas que (1's y -1's) lo cual es el mapeo de la informacion usando QPSK, pero la salida de la FFT me entrega el resultado parcialmente correcto, esto es que los resultados son correctos exceptuando los index 32,33,34,35, 80,81,82,83, 96,97,98,99, 140,141,142,143, 176,177,178,179, 208,209,210,211,212,213,214,215, 236,237,238,239, osea 32 index de los 256 entregados, de este paso hacia atras todo esta verificado meticulosamente usando la ventana WATCH del MPLAB.
1) use los 2 metodos de twiddle factors generacion y memoria de programa, ambos con el mismo resultado.
2) considere con detalle el escalar la informacion, invertir el orden (BIT REVERSE), y por supuesto que las salidas de las funciones no son de precision infinita por lo tanto hay informacion que se pierde.
3) lo unico que necesito de la informacion de salida de las funciones IFF -FFT es el signo de las amplitudes correcto para luego realizar "soft decision" y recuperar el menasaje original.
no he visto mayor informacion sobre OFDM en estos foros, pero me parece oportuno compartir con ustedes mi codigo completo para referencia de futuros interesados.
alguna idea que pueda estar pasando?
o que otra prueba puedo realizar?
#include "p33FJ128GP802.h"
//............................................................................
//Configuration bits:
//............................................................................
_FGS(GWRP_OFF & GCP_OFF);
_FOSCSEL(FNOSC_FRC);
_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF & POSCMD_XT); // & osci 2 pin function off & Primary oscillator in XT mode
_FWDT(FWDTEN_OFF);
//#define XTFREQ 7370000 //FRC frequency
#define FCY 30400000UL //Instruction Cycle Frequency
//#include <stdlib.h>
//#include <libpic30.h> // library for DELAYS
//#include <stdio.h>
//#include <stdlib.h>
//#include <uart.h>
//#include <string.h>
#include <dsp.h>
#include "fft.h"
//**************************************** GLOBAL VARIABLES ******************************************
char text[6]="Design";
int output;
unsigned int tempcrc=0;
unsigned char temp_data,crc_check1;
int i,k,kk,n,w,h;
float x1I, x1Q;
float frame_qpsk_I[320], frame_qpsk_Q[320];
float pilot=1;
fractional input_IFFT[512];
int LEDS[8]={1,0,1,0,1,0,1,0};
float x_real[8]={1,-1,1,-1,1,-1,1,-1};
float x_imag[8]={1,1,-1,-1,1,1,-1,-1};
fractcomplex sig_CP[320] __attribute__ ((space(ymemory)));
// Extern definitions for the IFFT
fractcomplex sigCmpx_in[FFT_BLOCK_LENGTH] __attribute__ ((space(ymemory)));
extern const fractcomplex twiddleFactors[FFT_BLOCK_LENGTH/2] // Twiddle Factor array in Program memory /
__attribute__ ((space(auto_psv), aligned (FFT_BLOCK_LENGTH*2)));
// Extern definitions for the FFT
fractcomplex sigCmpx_out[FFT_BLOCK_LENGTH] __attribute__ ((space(ymemory)));
//extern const fractcomplex twiddleFactors2[FFT_BLOCK_LENGTH/2] // Twiddle Factor array in Program memory /
//__attribute__ ((space(auto_psv), aligned (FFT_BLOCK_LENGTH*2)));
//**************************************** LOOK UP TABLES **********************************************
unsigned int message[448] =
{
#include "data_CRC.h"
};
/*******************************************************************************************************************
MAPPING AND MODULATION QPSK
********************************************************************************************************************/
void qpsk()
{
//initialising arrays to state zeros
k=0, n=0;
for (k=0; k < 256; k++)
{
frame_qpsk_I[k]=0.0;
frame_qpsk_Q[k]=0.0;
}
k=0;
for (n=0;n<448;n+=2)
{
if ((message[n]==0) && (message[n+1]==1))
{
x1I=1;
x1Q=-1;
}
else if ((message[n]==0) && (message[n+1]==0))
{
x1I=-1;
x1Q=-1;
}
else if ((message[n]==1) && (message[n+1]==0))
{
x1I=-1;
x1Q=1;
}
else if ((message[n]==1) && (message[n+1]==1))
{
x1I=1;
x1Q=1;
}
frame_qpsk_I[k]=x1I;
frame_qpsk_Q[k]=x1Q;
k++;
}
k=0;
n=0;
}
/*******************************************************************************************************************
OFDM: PILOT INSERTION - IFFT - CYCLIC PREFIX
********************************************************************************************************************/
void ofdm()
{
//PILOT INSERTION AND OVERWRITING THE ARRAY frame_qpsk
kk=223;
for (n=248;n>=0;n-=8)
{
h=7;
for (k=(n+h);h>0;h--)
{
frame_qpsk_I[k]=frame_qpsk_I[kk];
frame_qpsk_Q[k]=frame_qpsk_Q[kk];
kk--;
k--;
}
frame_qpsk_I[n]=pilot;
frame_qpsk_Q[n]=pilot;
}
//FILLING THE FRACTIONAL COMPLEX IFFT INPUT ARRAY WITH THE INFORMATION
for (i=0; i<256; i++)
{
sigCmpx_in[i].real=Float2Fract(frame_qpsk_I[i]);
sigCmpx_in[i].imag=Float2Fract(frame_qpsk_Q[i]);
}
fractcomplex *p_cmpx = &sigCmpx_in[0] ;
i=0;
// MAKING input data in the fractional fixed-point range [-0.5, +0.5],
// shift all data samples by 1 bit to the right
for ( i = 0; i < FFT_BLOCK_LENGTH; i++ )
{
(*p_cmpx).real = (*p_cmpx).real>>1;
(*p_cmpx).imag = (*p_cmpx).imag>>1;
(*p_cmpx++);
}
// Source INPUT ORGANISED IN BIT-reversed order of their addresses
BitReverseComplex (LOG2_BLOCK_LENGTH, &sigCmpx_in[0]);
//******* IFFT ************
IFFTComplexIP (LOG2_BLOCK_LENGTH, &sigCmpx_in[0], (fractcomplex *) __builtin_psvoffset(&twiddleFactors[0],1),(int) __builtin_psvpage(&twiddleFactors[0],1));
// Information at this point sigCmpx matches with matlab IFFT output with the scaling of 0.5 if Bitreverse
// instruction is within comments
//INSERTING CYCLIC PREFIX 64 SAMPLES
for (i=0; i<256; i++)
{
sig_CP[i+64]=sigCmpx_in[i];
}
for (i=0; i<64; i++)
{
sig_CP[i]=sigCmpx_in[i+192];
}
//Shifthng to the left
fractcomplex *pointer = &sig_CP[0] ;
for ( i = 0; i < 320; i++ )
{
(*pointer).real = (*pointer).real<<1;
(*pointer).imag = (*pointer).imag<<1;
(*pointer++);
}
//CONVERTING FROM FRACTIONAL TO FLOAT
for (i=0; i<320; i++)
{
frame_qpsk_I[i]=Fract2Float(sig_CP[i].real);
frame_qpsk_Q[i]=Fract2Float(sig_CP[i].imag);
}
}
/*******************************************************************************************************************
RECEIVER
********************************************************************************************************************/
void Receiver()
{
//******* FFT ************
FFTComplex (LOG2_BLOCK_LENGTH, &sigCmpx_out[0], &sigCmpx_in[0], (fractcomplex *) __builtin_psvoffset(&twiddleFactors[0],0),(int) __builtin_psvpage(&twiddleFactors[0],0));
i=0;
// FFT Output ORGANISED IN BIT-reversed order of their addresses
BitReverseComplex (LOG2_BLOCK_LENGTH, &sigCmpx_out[0]);
fractional F=256;
i=0;
// Scale the FFT output by a factor of N=256
VectorScale (FFT_BLOCK_LENGTH, &sigCmpx_out, &sigCmpx_out, F);
i=1;
}
/*******************************************************************************************************************
MAIN FUNCTION
********************************************************************************************************************/
void main(void)
{
/* Configure Oscillator to operate the device at FCY 30.4 MIPS, FOSC 60.8 MHz.
* Fosc= Fin*M/(N1*N2), Fcy=Fosc/2
* Fosc= 7.37M*40/(2*2)=80Mhz for 7.37M input clock */
PLLFBD=31; // M=33
CLKDIVbits.PLLPOST=0; // N2=2
CLKDIVbits.PLLPRE=0; // N1=2
OSCTUN=0;
__builtin_write_OSCCONH(0x03); // Initiate Clock Switch to Primary Oscillator with PLL (NOSC=0b011)
__builtin_write_OSCCONL(0x01);
while (OSCCONbits.COSC != 0b011); // Wait for Clock switch to occur
while(!OSCCONbits.LOCK);
AD1PCFGL = 0X1800; //Set PIN23-24 RB12 FROM ANALOGUE TO DIGITAL
TRISB= 0Xcfff; //Set RB12-RB13 as output
LATB = 0xffff; //Initialize LED pin data to off state
qpsk();
ofdm();
Receiver();
i=0;
for(;;) // forever
{
w=0;
for (w=0; w<8; w++)
{
output=LEDS[w];
if (output==1)
LATBbits.LATB12=0; //Turn LED on
else
LATBbits.LATB13=0; // turn all LEDs OFF
__delay32(1000); // wait 500 ms
LATBbits.LATB12=1;
LATBbits.LATB13=1;
__delay32(1000);
}
}
}