📄 int_fft.lst
字号:
C51 COMPILER V8.02 INT_FFT 05/09/2008 21:51:23 PAGE 1
C51 COMPILER V8.02, COMPILATION OF MODULE INT_FFT
OBJECT MODULE PLACED IN Int_FFT.OBJ
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE Int_FFT.c BROWSE DEBUG OBJECTEXTEND
line level source
1 #include "common.h"
2 #include "Int_FFT.h"
3 #include "adc0.h"
4 //-----------------------------------------------------------------------------
5 // Int_FFT
6 //-----------------------------------------------------------------------------
7 //
8 // Performs a Radix-2 Decimation-In-Time FFT on the input array ReArray[]
9 //
10 // During each stage of the FFT, the values are calculated using a set of
11 // "Butterfly" equations, as listed below:
12 //
13 // Re1 = Re1 + (Cos(x)*Re2 + Sin(x)*Im2)
14 // Re2 = Re1 - (Cos(x)*Re2 + Sin(x)*Im2)
15 // Im1 = Im1 + (Cos(x)*Im2 - Sin(x)*Re2)
16 // Im2 = Im1 - (Cos(x)*Im2 - Sin(x)*Re2)
17 //
18 // The routine implements this calculation using the following values:
19 //
20 // Re1 = ReArray[indexA], Re2 = ReArray[indexB]
21 // Im1 = ImArray[indexA], Im2 = ImArray[indexB]
22 // x = the angle: 2*pi*(sin_index/NUM_FFT), in radians. The necessary values
23 // are stored in code space in the SinTable[] array.
24 //
25 //
26 // Key Points for using this FFT routine:
27 //
28 // 1) It expects REAL data (in ReArray[]), in 2's complement, 16-bit binary
29 // format and assumes a value of 0 for all imaginary locations
30 // (in ImArray[]).
31 //
32 // 2) It expects the REAL input data to be sorted in bit-reversed index order.
33 //
34 // 3) SIN and COS values are retrieved and calculated from a table consisting
35 // of 1/4 of a period of a SIN function.
36 //
37 // 4) It is optimized to use integer math only (no floating-point operations),
38 // and for storage space. The input, all intermediate stages, and the
39 // output of the FFT are stored as 16-bit INTEGER values. This limits the
40 // precision of the routine. When using input data of less than 16-bits,
41 // the best results are produced by left-justifying the data prior to
42 // windowing and performing the FFT.
43 //
44 // 5) The algorithm is a Radix-2 type, meaning that the number of samples must
45 // be 2^N, where N is an integer. The minimum number of samples to process
46 // is 4. The constant NUM_FFT contains the number of samples to process.
47 //
48 //
49
50 int xdata Real[NUM_FFT] _at_ DATA_BEGIN;
51 int xdata Imag[NUM_FFT] _at_ (DATA_BEGIN + (NUM_FFT * 2));
52
53 void Int_FFT(int ReArray[], int ImArray[])
54 {
55 1
C51 COMPILER V8.02 INT_FFT 05/09/2008 21:51:23 PAGE 2
56 1 #if (NUM_FFT >= 512)
57 1 unsigned int sin_index, g_cnt, s_cnt; // Keeps track of the proper index
58 1 unsigned int indexA, indexB; // locations for each calculation
59 1 #endif
60 1
61 1 #if (NUM_FFT <= 256)
unsigned char sin_index, g_cnt, s_cnt; // Keeps track of the proper index
unsigned char indexA, indexB; // locations for each calculation
#endif
65 1
66 1 unsigned int group = NUM_FFT/4, stage = 2;
67 1 long CosVal, SinVal;
68 1 long TempImA, TempImB, TempReA, TempReB, TempReA2, TempReB2;
69 1 IBALONG ReTwid, ImTwid, TempL;
70 1
71 1 // FIRST STAGE - optimized for REAL input data only. This will set all
72 1 // Imaginary locations to zero.
73 1 //
74 1 // Shortcuts have been taken to remove unnecessary multiplications during this
75 1 // stage. The angle "x" is 0 radians for all calculations at this point, so
76 1 // the SIN value is equal to 0.0 and the COS value is equal to 1.0.
77 1 // Additionally, all Imaginary locations are assumed to be '0' in this stage of
78 1 // the algorithm, and are set to '0'.
79 1
80 1 indexA = 0;
81 1 for (g_cnt = 0; g_cnt < NUM_FFT/2; g_cnt++)
82 1 {
83 2 indexB = indexA + 1;
84 2
85 2 TempReA = ReArray[indexA];
86 2 TempReB = ReArray[indexB];
87 2
88 2 // Calculate new value for ReArray[indexA]
89 2 TempL.l = (long)TempReA + TempReB;
90 2 if ((TempL.l < 0)&&(0x01 & TempL.b[3]))
91 2 TempReA2 = (TempL.l >> 1) + 1;
92 2 else TempReA2 = TempL.l >> 1;
93 2
94 2 // Calculate new value for ReArray[indexB]
95 2 TempL.l = (long)TempReA - TempReB;
96 2 if ((TempL.l < 0)&&(0x01 & TempL.b[3]))
97 2 ReArray[indexB] = (TempL.l >> 1) + 1;
98 2 else ReArray[indexB] = TempL.l >> 1;
99 2
100 2 ReArray[indexA] = TempReA2;
101 2
102 2 ImArray[indexA] = 0; // set Imaginary locations to '0'
103 2 ImArray[indexB] = 0;
104 2
105 2 indexA = indexB + 1;
106 2 }
107 1
108 1 // END OF FIRST STAGE
109 1
110 1
111 1 while (stage <= NUM_FFT/2)
112 1 {
113 2 indexA = 0;
114 2 sin_index = 0;
115 2
116 2 for (g_cnt = 0; g_cnt < group; g_cnt++)
117 2 {
C51 COMPILER V8.02 INT_FFT 05/09/2008 21:51:23 PAGE 3
118 3 for (s_cnt = 0; s_cnt < stage; s_cnt++)
119 3 {
120 4 indexB = indexA + stage;
121 4
122 4 TempReA = ReArray[indexA];
123 4 TempReB = ReArray[indexB];
124 4 TempImA = ImArray[indexA];
125 4 TempImB = ImArray[indexB];
126 4
127 4 // The following first checks for the special cases when the angle "x" is
128 4 // equal to either 0 or pi/2 radians. In these cases, unnecessary
129 4 // multiplications have been removed to improve the processing speed.
130 4
131 4 if (sin_index == 0) // corresponds to "x" = 0 radians
132 4 {
133 5
134 5 // Calculate new value for ReArray[indexA]
135 5 TempL.l = (long)TempReA + TempReB;
136 5 if ((TempL.l < 0)&&(0x01 & TempL.b[3]))
137 5 TempReA2 = (TempL.l >> 1) + 1;
138 5 else TempReA2 = TempL.l >> 1;
139 5
140 5 // Calculate new value for ReArray[indexB]
141 5 TempL.l = (long)TempReA - TempReB;
142 5 if ((TempL.l < 0)&&(0x01 & TempL.b[3]))
143 5 TempReB2 = (TempL.l >> 1) + 1;
144 5 else TempReB2 = TempL.l >> 1;
145 5
146 5 // Calculate new value for ImArray[indexB]
147 5 TempL.l = (long)TempImA - TempImB;
148 5 if ((TempL.l < 0)&&(0x01 & TempL.b[3]))
149 5 TempImB = (TempL.l >> 1) + 1;
150 5 else TempImB = TempL.l >> 1;
151 5
152 5 // Calculate new value for ImArray[indexA]
153 5 TempL.l = (long)TempImA + TempImB;
154 5 if ((TempL.l < 0)&&(0x01 & TempL.b[3]))
155 5 TempImA = (TempL.l >> 1) + 1;
156 5 else TempImA = TempL.l >> 1;
157 5
158 5 }
159 4 else if (sin_index == NUM_FFT/4) // corresponds to "x" = pi/2 radians
160 4 {
161 5
162 5 // Calculate new value for ReArray[indexB]
163 5 TempL.l = (long)TempReA - TempImB;
164 5 if ((TempL.l < 0)&&(0x01 & TempL.b[3]))
165 5 TempReB2 = (TempL.l >> 1) + 1;
166 5 else TempReB2 = TempL.l >> 1;
167 5
168 5 // Calculate new value for ReArray[indexA]
169 5 TempL.l = (long)TempReA + TempImB;
170 5 if ((TempL.l < 0)&&(0x01 & TempL.b[3]))
171 5 TempReA2 = (TempL.l >> 1) + 1;
172 5 else TempReA2 = TempL.l >> 1;
173 5
174 5 // Calculate new value for ImArray[indexB]
175 5 TempL.l = (long)TempImA + TempReB;
176 5 if ((TempL.l < 0)&&(0x01 & TempL.b[3]))
177 5 TempImB = (TempL.l >> 1) + 1;
178 5 else TempImB = TempL.l >> 1;
179 5
C51 COMPILER V8.02 INT_FFT 05/09/2008 21:51:23 PAGE 4
180 5 // Calculate new value for ImArray[indexA]
181 5 TempL.l = (long)TempImA - TempReB;
182 5 if ((TempL.l < 0)&&(0x01 & TempL.b[3]))
183 5 TempImA = (TempL.l >> 1) + 1;
184 5 else TempImA = TempL.l >> 1;
185 5
186 5 }
187 4
188 4 else
189 4 {
190 5 // If no multiplication shortcuts can be taken, the SIN and COS
191 5 // values for the Butterfly calculation are fetched from the
192 5 // SinTable[] array.
193 5
194 5 if (sin_index > NUM_FFT/4)
195 5 {
196 6 SinVal = SinTable[(NUM_FFT/2) - sin_index];
197 6 CosVal = -SinTable[sin_index - (NUM_FFT/4)];
198 6 }
199 5 else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -