fdevid Inserito: 23 settembre 2021 Segnala Share Inserito: 23 settembre 2021 Buongioro a tutti, ho provato a creare/copiare una FFT su awl ma c'è qualcosa che non va ... qualche bravo ingegnere mi saprebbe aiutare ? PS: il dato in ingresso L deve essere in potenza di 2 ma purtroppo non mi funziona FUNCTION_BLOCK FB856 //TITLE = 'FFT' //VERSION : '1.0' //AUTHOR : FD //NAME : FFT //FAMILY : ML VAR_INPUT L : INT ; // Lenght of data END_VAR VAR_OUTPUT END_VAR VAR_IN_OUT x_real: ARRAY[0..512] OF REAL; x_complex: ARRAY[0..512] OF REAL; END_VAR VAR tmp_real : ARRAY[0..512] OF REAL; // temporary storage for real components tmp_complex : ARRAY[0..512] OF REAL; // temporary storage for imaginary components N : INT ; // Lenght of current computed FFT vector w_real : ARRAY[0..64] OF REAL; ; // Twiddle factors real component w_complex : ARRAY[0..64] OF REAL; ; // Twiddle factors imaginary componentt k : INT ; // Loop index ind : INT ; // Index of the first ( even) sum element w_ind : INT ; // Twiddle factor index span : INT ; // Block index LpN : INT ; // Total data lenght divide by current N. Saved for optimization reasons w_r : REAL ; // Selected twiddle factor real component w_c : REAL ; // Selected twiddle factor imaginary component A_r : REAL ; // Even element real componet A_c : REAL ; // Even element imaginary componet B_r : REAL ; // Even element real componet B_c : REAL ; // Even element imaginary componet FOR_TMP : INT ; // Temporary END_VAR (* ------------------------------- *) (* START *) (* ------------------------------- *) BEGIN N := 2; WHILE N <= L DO //(* Twidddle factor precalculation *) FOR k := 0 TO N/8 BY 1 DO w_real[k] := cos(2.0*3.14159265359*int_to_real(k)/int_to_real(N)); w_complex[k] := sin(2.0*3.14159265359*int_to_real(k)/int_to_real(N)); end_for; ind := 0; w_ind := 0; span := 1; LpN := L/N; for k := 0 to L-1 do //(* Selecting RIGHT twiddle factor // Cases are split in two just TO halve condition evaluations *) IF w_ind <= N/2 THEN IF w_ind <= N/8 THEN w_r := w_real[ w_ind ]; w_c := -w_complex[ w_ind ]; ELSIF w_ind <= N/4 THEN w_r := w_complex[ N/4-w_ind ]; w_c := -w_real[ N/4-w_ind ]; ELSE w_r := -w_real[ N/2-w_ind ]; w_c := -w_complex[ N/2-w_ind ]; END_IF; ELSE IF w_ind <= 5*N/8 THEN w_r := -w_real[ w_ind-N/2 ]; w_c := w_complex[ w_ind-N/2 ]; ELSIF w_ind <= 3*N/4 THEN w_r := -w_complex[ 3*N/4-w_ind ]; w_c := w_real[ 3*N/4-w_ind ]; ELSIF w_ind <= 7*N/8 THEN w_r := w_complex[ w_ind-3*N/4 ]; w_c := w_real[ w_ind-3*N/4 ]; ELSE w_r := w_real[ N-w_ind ]; w_c := w_complex[ N-w_ind ]; END_IF; END_IF; A_r := x_real[ ind ]; A_c := x_complex[ ind ]; B_r := x_real[ ind+LpN ]; B_c := x_complex[ ind+LpN ]; //(* Separation of real and imaginary components *) tmp_real[ k ] := A_r + B_r*w_r - B_c*w_c; tmp_complex[ k ] := A_c + B_r*w_c + B_c*w_r; // (* Indexing // Index is the index OF even element. Odd element is always with index // offset OF LpN from even element. *) // ind := ind + 1; IF ind + LpN = L THEN (* Transition from first half to second *) ind := 0; w_ind := w_ind + 1; span := 1; ELSIF ind + LpN = span*LpN*2 THEN (* Transition between spans *) ind := ind + LpN; w_ind := w_ind + 1; span := span + 1; END_IF; END_FOR; N := N*2; //(* Copy all elements from temp to data vector *) FOR k := 0 TO L-1 DO x_real[ k ] := tmp_real[ k ]; x_complex[ k ] := tmp_complex[ k ]; END_FOR; END_WHILE; END_FUNCTION_BLOCK Link al commento Condividi su altri siti More sharing options...
Colonial54 Inserita: 23 settembre 2021 Segnala Share Inserita: 23 settembre 2021 Finalmente qualcosa di succulento. Link al commento Condividi su altri siti More sharing options...
GIO170 Inserita: 7 giugno 2023 Segnala Share Inserita: 7 giugno 2023 Ciao Qualcuno è ruscito a risolvere il problema? i n t potenza2 ( i n t n ) // l a funz i one c o n t r o l l a s e i l numero in argomento e una potenza Link al commento Condividi su altri siti More sharing options...
Livio Orsini Inserita: 7 giugno 2023 Segnala Share Inserita: 7 giugno 2023 la discussione è inattiva da un anno!! Link al commento Condividi su altri siti More sharing options...
Messaggi consigliati