Fórum témák

» Több friss téma
Cikkek » Fourier transzformáció
Fourier transzformáció
Szerző: deguss, idő: Feb 3, 2008, Olvasva: 48381, Oldal olvasási idő: kb. 2 perc
Lapozás: OK   6 / 6

dsPIC30F4013

Kipróbálván az FFT algoritmust egy DSP-n, a következő oldalon levőket kaptam. De előtte egy kis áttekintés:

Harvard architektúrájú DSP, 12 analóg bemenettel, 2 full-duplex UART-tal, 16× belső PLL-el, max 30MIPS, hogy csak a fontosabb paramétereket említsem.

Erre programoztam egy FFT-t, a C30-as compiler függvényeit és példaprogramjait felhasználva. Nem volt igazi nagy munka, hiszen szinte minden függvény már megvolt, csak meg kellett őket hívni.
Maga az FFT-számítás, a butterfly algoritmusok meg a keresztbeszorzás mind-mind assembly nyelven van leprogramozva a kis programmemóriát megcélozva.
A forrást nem fogom sorrol-sorra bemutatni, inkább egy ilyen áttekintést próbálok nyújtani:

  1. // 1.) SAMPLING
  2. UARTsendString("Sampling with 256 samples started.\n\0");
  3. T1CON = 0x8000; //prescaler of T1 decrease to 1-divide
  4. for (i=0; i
  5. //these operations take appr. 50 ASM commands, we have time by 32000s/sec for 625
  6. TMR1=0;
  7. sigCmpx[i].real = ADC10read(0);//read analogue for each sample
  8. // 0V ... 0x0000, 5V ... 0x0FFF (4095)
  9. while (TMR1 < 0x0271); //wait 31.5 us. Refer to dsPICcalc.xls!
  10. }
  11. T1CON = 0x8030; //prescaler of T1 restore to 256-divide
  12. UARTsendString("Sampling with 256 samples finished.\n\0");
  13.  
  14. // 2.) Sending sample buffer on UART
  15. UARTsendString("[INPUTBUFFER]\n\0");
  16. for (i=0; i
  17. UARTint2Str(sigCmpx[i].real); //send each value to UART
  18. UARTsendByte(0x0A); //terminate with \r
  19. }
  20. UARTsendString("[ENDINPUTBUFFER]\n\0");
  21.  
  22.  
  23. // 3.) SCALING
  24. // The FFT function requires input data to be in the fractional fixed-point range [-0.5, +0.5]
  25. for (i=0; i
  26. *p_real = *p_real >>1 ; // So, we shift all data samples by 1 bit to the right.
  27. *p_real++; // Should you desire to optimize this process,
  28. //perform data scaling when first obtaining the time samples or within the BitReverseComplex function
  29. }
  30.  
  31. // 4.) CLEARING complex parts
  32. p_real = &sigCmpx[(FFT_BLOCK_LENGTH/2)-1].real; // Set up pointers to convert real array to a complex array!!!
  33. p_cmpx = &sigCmpx[FFT_BLOCK_LENGTH-1]; // The input array initially has all the real input,
  34. // samples followed by a series of zeros
  35.  
  36. for (i=FFT_BLOCK_LENGTH; i>0; i--){ // Convert the Real input sample array to a Complex input sample array
  37. (*p_cmpx).real = (*p_real--); // We will simpy write zero to the imaginary part of each sample
  38. (*p_cmpx--).imag = 0x0000;
  39. }
  40.  
  41. // 5.) FFT (algorythmus in ASM)
  42. FFTComplexIP(LOG2_BLOCK_LENGTH, &sigCmpx[0], (fractcomplex *)
  43. __builtin_psvoffset(&twiddleFactors[0]), (int) __builtin_psvpage(&twiddleFactors[0]));
  44.  
  45. // 6.) BIT reversing:
  46. //Store output samples in bit-reversed order of their addresses
  47. BitReverseComplex (LOG2_BLOCK_LENGTH, &sigCmpx[0]);
  48.  
  49.  
  50. // 7.) CALCULATING REAL part vector (Z = Re^2 + Im^2 )
  51. // not neccessary, may lead to reset of CPU
  52. // Compute the square magnitude of the complex FFT output array so we have a Real output vetor
  53. // SquareMagnitudeCplx(FFT_BLOCK_LENGTH, &sigCmpx[0], &sigCmpx[0].real);
  54.  
  55. // 8a.) SEARCH the largest spectral component - AMPLITUDE
  56. // Find the frequency Bin ( =index into the SigCmpx[] array) that has the largest energy
  57. VectorMax(FFT_BLOCK_LENGTH/2, &sigCmpx[0].real, &peakFrequencyBin);
  58.  
  59. // 8b.) FREQUENCY of the largest spectral component
  60. // Compute the frequency (in Hz) of the largest spectral component
  61. peakFrequency = peakFrequencyBin*(SAMPLING_RATE/FFT_BLOCK_LENGTH);
  62.  
  63. // 9.) REPORT UART
  64. UARTsendString("Fourier Transform and calculations finished!\n\0");
  65. UARTsendString("Largest spectral component Amax = \0");
  66. UARTint2Str(sigCmpx[peakFrequencyBin]);
  67. UARTsendString("\nFrequency of the largest spectral component fmax = \0");
  68. UARTint2Str(peakFrequency);
  69. UARTsendString("\n\0");
  70.  
  71. //Sending output buffer on UART
  72. UARTsendString("[OUTPUTBUFFER]\n\0");
  73. for (i=0; i
  74. UARTint2Str(sigCmpx[i].real); //send real and
  75. UARTsendByte(0x0A); //terminate with \n
  76. UARTint2Str(sigCmpx[i].imag); //imaginary part to UART
  77. UARTsendByte(0x0A); //terminate with \n
  78. }
  79. UARTsendString("[ENDOUTPUTBUFFER]\n\0");

Mivel egy előadást is tartottam a témából, a programot angol nyelven kellett felkommenteznem, de remélem érthető mi-mit csinál. Egy 1000 szavas angol alap-szókinccsel már érthető szerintem.

Jóságok:

Egy egyszerű számolási segítség timerekhez, baud-rate számításhoz, meg a PLL és hasonló dolgokban való eligazodáshoz: Egy MS-Excel munkafüzet

Az előadás német nyelven, ha valakit érdekelne FFT.pdf

A kidolgozás, egyenletek, színtiszta matek: FFT_math.pdf

Zárszó:

Remélem sikerült röviden és átfogóan körbejárni a témát, hangsúlyozom, hogy a cikk nem tér ki minden részletre, és nem válaszol meg minden felmerülő kérdést, arra ott a fórum.
Ha valaki kedvet érez és kibővítené a cikket akármilyen ide kapcsolódó anyaggal, azt szívesen fogadom, természetesen neve feltüntetése mellett.

Sok sikert fejlesztés során! deguss 2008

 

Következő: »»   6 / 6
Értékeléshez bejelentkezés szükséges!
Bejelentkezés

Belépés

Hirdetés
XDT.hu
Az oldalon sütiket használunk a helyes működéshez. Bővebb információt az adatvédelmi szabályzatban olvashatsz. Megértettem