TODOPIC
Bienvenido(a), Visitante. Por favor, ingresa o regístrate.
¿Perdiste tu email de activación?
20 de Octubre de 2014, 19:48:13

Ingresar con nombre de usuario, contraseña y duración de la sesión
Buscar:     Búsqueda Avanzada
350139 Mensajes en 39276 Temas por 41019 Usuarios
Último usuario: Pategrassin
* Inicio Ayuda Buscar Calendario Ingresar Registrarse
Buscar en TodoPIC
+  TODOPIC
|-+  Microcontroladores PIC
| |-+  dsPIC (Moderadores: pikman, Sispic)
| | |-+  utilizar la FFT para Dspic 33fj128... con CCS compiler 4.093
0 Usuarios y 1 Visitante están viendo este tema. « anterior próximo »
Páginas: [1] Marcar como favorito Imprimir
Autor Tema: utilizar la FFT para Dspic 33fj128... con CCS compiler 4.093  (Leído 2522 veces)
chasmam
PIC10
*
Desconectado Desconectado

Colombia Colombia

Mensajes: 3


« : 11 de Agosto de 2010, 13:41:20 »

hola a todos, estoy utlizando  el algoritmo ya implementado de la  FFT , ejemplo que esta disponible en el CCS compiler 4.093., megustaria saber si alguien ya lo logrado implementar,  tengo una duda en la interpretacion del vector de datos que le estoy enviando y el que estoy recibiendo  por si estan interesados a quie estan las librerias y el codigo, detodas formas lo pueden buscar en los examples de CCS compiler 4.093 en la versiones inferiores no esta implementada esta funcion:




////////////////////////////////////////este es FFT.h

#word CORCON = getenv("SFR:CORCON")
#word MODCON = getenv("SFR:MODCON")
#word XBREV  = getenv("SFR:XBREV")
#word XMODSRT = getenv("SFR:XMODSRT")
#word XMODEND = getenv("SFR:XMODEND")
#word YMODSRT = getenv("SFR:YMODSRT")
#word YMODEND = getenv("SFR:YMODEND")

#define TABLE_SIZE 15
#define FILTER_SIZE 256
#define HALF_SIZE FILTER_SIZE/2
#define FRACT_MULTIPLIER   32768
#define BLOCK_LENGTH 512
#define PI 3.141592654
#define STEP_SIZE ((2*PI)/TABLE_SIZE)

#banky
signed int16 input[BLOCK_LENGTH];

#bankx
signed int16 Twid_factor[BLOCK_LENGTH];





/////////////////////////////////////////////////
esta es la libreria encargarada FFT.C

void load_input(int16 * input);

void load_input(int16 * input)
{
 int i;                                 
signed int16 datos[101]={  //este es el vector de datos que le estoy cargando, un vector de una señal senosoidad creada en     
                                       // matlab  la funcion es : 32768*sin(2*pi*450*t) con una frecuencia establecida de 450hz

0,   10126,   -19261,   26510 ,  -31164 ,  32767 ,  -31164  , 26510 ,  -19261  , 10126,
0,   -10126,   19261,   -26510,   31164 ,  -32768,   31164 ,  -26510,   19261  , -10126   ,
0,   10126 ,  -19261,   26510 ,  -31164 ,  32767 ,  -31164 ,  26510 ,  -19261 ,  10126   ,
0,   -10126,   19261,   -26510,   31164,   -32768,   31164 ,  -26510,   19261 ,  -10126   ,
0,   10126 ,  -19261,   26510 ,  -31164,   32767 ,  -31164 ,  26510 ,  -19261 ,  10126   ,
0,   -10126,   19261,   -26510,   31164,   -32768,   31164,   -26510,   19261 ,  -10126   ,
0,   10126 ,  -19261,   26510 ,  -31164,   32767 ,  -31164,   26510 ,  -19261 ,  10126   ,
0,   -10126,   19261,   -26510,   31164,   -32768,   31164,   -26510,   19261,   -10126   ,
0,   10126 ,  -19261,   26510 ,  -31164,   32767 ,  -31164,   26510 ,  -19261,   10126   ,
0,   -10126,   19261,   -26510,   31164,   -32768 ,  31164,   -26510 ,  19261,   -10126   ,
0};

   
 for(i=0;i<110;i++)
 {
 input=datos;
 
 }
 // dummy routine
}


/*
void Call_bit_reverse(int16 * ptrn);
This function will perform bit reverse operation on the source vector.
Current implementation is set for 256 point complex vector.
*/
#inline
void Call_bit_reverse(int16 * ptrn);

/*
void fft_complex(int * ptrn, int * twid);
This function will perform FFT transform on the complex source vector.
The input is expected in bit reversed ordering. The Call_bit_reverse()
function must be called before calling the fft_complex function.
This performs an in-place FFT and replaces the source with the output
vector.
*/
void fft_complex(int * ptrn, int * twid);

void Call_bit_reverse(int16 * ptrn)
{
    int * ptrin;
   
    ptrin = ptrn;
    #asm
    MOV  #0x08,W0
   
    PUSH   MODCON
    PUSH   XBREV
    MOV   #0x0300,W3         ; uses W3 for bit reverse
    MOV   W3,MODCON
    MOV   #0x8000,W3         ; enable bit reverse addresing
    MOV   #0x1,W4            ; shifting base
    SL   W4,W0,W4         
    IOR   W4,W3,W3
    MOV   W3,XBREV                         

    MOV ptrin , W2
    MOV   W2,W3            ; W3: bit reverse addressing
                           ; W2: sequential addressing
    MOV   #2,W6            ; load size of data in W6
    MOV   #4,W7            ; load size of complex data in W

    DEC   W4,W4            ; W4 = N-1
    do   W4,Finish_BR      // Loop N times
    CP   W3,W2            // W3-W2 ?
    BRA LE,  Next_Loop         // W3 <= W2 goto to next
                 
                 
   // Swap complex value pairs.
    MOV.d   [W2],W0            // W0 = real[n], W1 = imag[n]
    MOV   [W3],[W2]         // replace real part sequential
    MOV   [W3+W6],[W2+W6]         // replace imag part sequential
    MOV.d   W0,[W3]            // replace real/imag bit reverse

Next_Loop:   
    ADD   W2,W7,W2         // W2 += sizeof(fractcomplex)
                           // sequential update

Finish_BR:
    MOV   [W3],[W3++]        // bit reverse update
                            // (only on data writes!!!)
    NOP                       
   #endasm   
}


// FFT routine
// Data is expected in bit-reversed ordering and output will be in
// natural ordering
// Call the Call_bit_reverse() function before calling the fft_complex function
void fft_complex(int * ptrn, int * twid)
{
    int * ptrin;
    int * twid_fac;
   
   
    ptrin = ptrn;     // Save address of local variables
    twid_fac = twid;  // Save address of Twiddle factors
   
    #asm
    MOV ptrin, W1        // W1 contains pointer to source
    MOV twid_fac, W8     // W8 contains pointer to Twid factors
   
    MOV log2n,W0        // W0 = Number of stages

    MOV   #0x80,W3        // Twiddle factor Offset
                     

   // Preform all k stages, k = 1:log2N.
   // W3 = 0x80, so 0x7F butterflies in 1st stage
   // and N/2 groups  (W9 = N/2) for factors WN(0), WN(1), ..., WN(N/2-1).
    MOV log2n,W13
            // W13= num stages
    MOV #0x01,W9  // W9 = 1, only 1 group per butterfly at the start         

FFT_Stage:

   // Perform all butterflies in each stage

   
   SL   W9,#2,W12         // W12= lower offset
    MOV W9,W2
   SL   W9,W9
               
   MOV   W1,W10         // W10 = source vector

   // Perform butterflies in each stage.
   DEC   W3,W4            // W4 = 7F, 3F, 1F .....
   do   W4,Bfly_Done      // do 0x7F times.. 0x3F times and so on...

    //  Set offset for source vector
   ADD   W12,W10,W11         // W11 = source vector + lower offset
               
   // Twiddle factors., 0x200, 0x100, 0x80, and so on ...
   SL   W3,#2,W0    // W0 contains offset, which will be 4 times actual number
                 // since there are 4 bytes per twiddle factor

   // Perform each group of butterflies, one for each twiddle factor.
   //
    DEC   W2,W4  // W4 is 0,1,3,7,15   and so on ...
   do   W4,Group_Done      // number of groups to be done

   // Butterfly --> A = (P1r - P2r)*Wr - P1i - P2i)*Wi
   //               B = (P1r - P2r)*Wi + (P1i - P2i)*Wr
   // The above butterfly is performed in 4 steps,
   // Step 1:  A = (P1r - P2r)*Wr  (use MPY instruction)
   // Step 2:  A = A - (P1i - P2i)*Wi  (use MSC instruction, multiply and subtract
   // Step 3:  B = (P1r - P2r)*Wi  (use MPY instruction)
   // Step 4:  B = B + (P1i - P2i)*Wr (use MAC instruction, multiply and accumulate)
   
   CLR B
   CLR   A,[W8]+=2,W6,[W10]+=2,W4   // W8 = *twid_fac, W10 = ptrin
                  // W6 = Twdif factor real -> Wr
                   // Twidd factor imaginary -> Wi
                  // W4 = P1r 
                   
   SUB   W4,[W11++],W4         // W4 = P1r - P2r
                 
   MPY   W4*W6,A,[W8]-=2,W7,[W10]-=2,W5   // Step 1: A = (P1r - P2r)*Wr
                  // W7 = Wi
                  // twid_fac-> Wr
                  // W5 = P1i
   // Update twiddle pointer.
   ADD   W0,W8,W8         

   MPY   W4*W7,B       //Step 3: B  = (P1r - P2r)*Wi
   SUB   W5,[W11--],W5         // W5 = P1i - P2i

   MSC   W5*W7,A,[W11]+=2,W7 // Step 2:  A  =  A   - (P1i - P2i)*Wi
                  // W7 = P2r
                 
   MAC   W5*W6,B,[W11]-=2,W5    // Step 4:  B  = B +(P1i - P2i)*Wr
                  // W5 = P2i
               
   SAC.R   A,#1,[W11++]      // Overwrite P2   = 1/2*A

   SAC.R   B,#1,[W11++]      // Overwrite P2 = 1/2*B

   LAC   [W10++],A         ; A  = P1r
                 
   LAC   [W10--],B         ; B  = P1i

   ADD   W7,A            ; A  = P1r + P2r
   ADD   W5,B            ; B  = P1i + P2i
   SAC.R   A,#1,[W10++]   // Overwrite P1   = 1/2*A
                 
Group_Done:
   SAC.R   B,#1,[W10++]    // Overwrite P1   = 1/2*B

               
   ADD   W12,W10,W10         // Set W10 to address of next P1
Bfly_Done:
   MOV   twid_fac,W8         //  Twiddle pointer in W8

   // Twid factor update
   LSR   W3,W3         

   DEC   W13,W13         // decrement log2n   
   
   BRA NZ, FFT_Stage  // More stages (log2n-1 !=0)
   
All_Stages_Done:         // stages over

    #ENDASM
}


////////////////////////////////////////////////////////////


//este es la libreria en cargada de crear los    twid factors   twid_factor.c

/ Function to initialize the twiddle factors
void Init_Twid_factors(void);

// Function to convert Float numbers to fractional format
int Float2Fract(float num);

// Function to initialize the twiddle factors
void Init_Twid_factors(void)
{
   float TwidComplex_R, TwidComplex_I;
   // Twid_factor defined in fft.h file : for 128 Twid factors, real + imaginary
   int i,j;                 
   int numFactors;
   int log2N=8;
   float arg;

   numFactors = (1<<log2N)/2;   
   j=0; // pointer for twid factor
   for (i = 0; i < numFactors; i++ )
   {
        arg = 2.0*PI*i/numFactors;       
        TwidComplex_R =  cos (arg);
        Twid_factor[j] = Float2Fract(TwidComplex_R);
        j = j+2; // Increment pointer to point to imaginary part
        TwidComplex_I = -sin (arg);
        Twid_factor = Float2Fract(TwidComplex_I);
    }
}



// Function to convert Float numbers to fractional format
int Float2Fract(float num)
{

   int return_val;
   float temp;

   temp = num*FRACT_MULTIPLIER;  // This multiplier is for 1.15 format

   if(temp>0)
   return_val = floor(temp);
   else
   return_val = ceil(temp);

   return return_val;
}


/////////////////////////// y este es el principal  main


#if defined(__PCD__)
#include <33FJ128MC202.h>
#fuses HS, NOWDT, NOPROTECT, PR
#use delay(clock=4000000)
#else
#error This example works only for PCD. Please select the PCD Compiler
#endif

int log2N=8;   // Number of stages of the FFT : 8 for 256 point FFT
   
#include <math.h>
#include "fft.h"
#include "twid_factors.c"
#include "fft.c"
 
 
void main(void)
{
   int * ptrin;
   int * twid;
   int c[512],t=0;

 //ghgfh
     
   
   Init_Twid_factors();


   ptrin =&input[0];
   twid =&Twid_factor[0];
 

   // Call routine to load input values into buffer   
   load_input(&input[0]);
   
   // Call function to reverse the bit order of the data
   // before processing calculating the FFT
   Call_bit_reverse(ptrin);

   // Call the FFT routine
   fft_complex(ptrin, twid);
   
   while(1)
  {
   
    for(t=0;t<512;t++){
      c[t]=abs(input[t]); 
         
    }

           
           
           }
   
 }


en el vector c[t] vuelvo y leo los datos  pero esta ya estan tratados, y creo que en este mismo vector es el que saca
el vetor de la fft , pero no estoy seguro, ayuda porfavor, gracias!!!




En línea
dspmaster
PIC10
*
Desconectado Desconectado

Colombia Colombia

Mensajes: 1


« Respuesta #1 : 13 de Mayo de 2011, 04:03:54 »

Las rutinas alli desarrolladas se hacen in-place, esto quiere decir que tanto el vector de entrada como el vector donde se hace la inversion por acarreo y se entrega la FFT son los mismos. esto hace que utilicemos menos memoria de datos. Ademas este codigo de ejemplo creo que no funciona bien,  comenzando porque en la rutina del bit_reverse se utilizan la instruccion PUSH para salvar 2 registros (MODCON y XBREV), pero estos nunca son restaurados con POP haciendo que el stack pointer se descontrole totalmente.
Hace algun tiempo revise todo ese codigo y logre comprender como hacian casi por completo la rutina de la FFT, excepto en la ecuación Butterfly que es el nucleo del algoritmo, asi que decidi modificar solo esa parte como la estudie en algunos libros y la rutina funciona muy bien, en algunos dias puedo publicar algunas rutinas que te pueden ser utiles como la configuracion del ADC para muestrear a una tasa fija y las de la FFT y bit_reverse corregidas, asi como un ejemplo de como utilizarlas para generar un sencillo analizador de espectro en una GLCD128x64.

En línea
claydergc
PIC10
*
Desconectado Desconectado

Peru Peru

Mensajes: 7


« Respuesta #2 : 15 de Diciembre de 2012, 02:21:32 »

Hola,

Me encuentro bajo el mismo dilema, aunque yo estoy trabajando con la version 4.130 de CCS. Han logrado hacer correr correctamente la funcion fft que da el compilador CCS?

Saludos.
En línea
TODOPIC
   

 En línea
Páginas: [1] Imprimir 
« anterior próximo »
Ir a:  

Impulsado por MySQL Impulsado por PHP Powered by SMF 1.1.20 | SMF © 2006-2008, Simple Machines XHTML 1.0 válido! CSS válido!
Página creada en 0.201 segundos con 23 consultas.
anything