//-----------------------------------------------------------------------------
// IntFFT_BRIN.c
//-----------------------------------------------------------------------------
// This program collects data using ADC0 at <SAMPLE_RATE> Hz and performs
// an FFT on the data. The Real and Imaginary parts of the results are then
// sent to the UART peripheral at <BAUDRATE> bps, where they can be displayed
// or captured using a terminal program.
//
// Note that the FFT performed in this software is optimized for storage space
// (RAM). The resulting Frequency-domain data is not suitable for analyzing
// Signal-to-noise or distortion performance.
//
// This program uses a 22.1184 MHz crystal oscillator multiplied by (9/4)
// for an effective SYSCLK of 49.7664 Mhz. This program also initializes and
// uses UART0 at <BAUDRATE> bits per second.
//
// Target: C8051F12x
// Tool chain: KEIL C51 6.03
//
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include "FFT.h" // Code Tables for FFT routines
#include <stdio.h>
//-----------------------------------------------------------------------------
// Global CONSTANTS and Variable Type Definitions
//-----------------------------------------------------------------------------
#define NUM_BITS 16 // Number of Bits in Data
//-----------------------------------------------------------------------------
// Function PROTOTYPES
//-----------------------------------------------------------------------------
void WindowCalc(INT16 Win_Array[], unsigned char SE_data);
void Int_FFT(INT16 ReArray[], INT16 ImArray[]);
void Bit_Reverse(INT16 BR_Array[]);
//-----------------------------------------------------------------------------
// MAIN Routine
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// MAIN Routine
//-----------------------------------------------------------------------------
// WindowCalc
//-----------------------------------------------------------------------------
//
// Uses the values in WindowFunc[] to window the stored data.
//
// The WindowFunc[] Array contains window coefficients between samples
// 0 and (NUM_FFT/2)-1, and samples from NUM_FFT/2 to NUM_FFT-1 are the mirror
// image of the other side.
// Window values are interpreted as a fraction of 1 (WindowFunc[x]/65536).
// The value at NUM_FFT/2 is assumed to be 1.0 (65536).
//
// If SE_data = 1, the input data is assumed to be single-ended, and is
// converted to a 2¡¯s complement, differential representation, to cancel the DC
// offset.
//
void WindowCalc(INT16 Win_Array[], unsigned char SE_data)
{
INT16 index=0;
#if (WINDOW_TYPE != 0) // Use this section if a window has been specified
IBALONG NewVal;
if (SE_data) // If data is single-ended,
Win_Array[0] ^= 0x8000; // convert it to differential
NewVal.l = (long)Win_Array[0] * WindowFunc[0];
if ((NewVal.l < 0)&&(NewVal.i[0]))
Win_Array[0] = NewVal.i[1] + 1;
else Win_Array[0] = NewVal.i[1];
if (SE_data) // If data is single-ended,
Win_Array[NUM_FFT/2] ^= 0x8000; // convert it to differential
for (index = 1; index < NUM_FFT/2; index++)
{
// Array positions 1 to (NUM_FFT/2 - 1)
if (SE_data) // If data is single-ended,
Win_Array[index] ^= 0x8000; // convert it to differential
NewVal.l = (long)Win_Array[index] * (long)WindowFunc[index];
if ((NewVal.l < 0)&&(NewVal.i[0]))
Win_Array[index] = NewVal.i[1] + 1;
else Win_Array[index] = NewVal.i[1];
// Array positions (NUM_FFT/2 + 1) to (NUM_FFT - 1)
if (SE_data) // If data is single-ended,
Win_Array[NUM_FFT-index] ^= 0x8000; // convert it to differential
NewVal.l = (long)Win_Array[NUM_FFT-index] * (long)WindowFunc[index];
if ((NewVal.l < 0)&&(NewVal.i[0]))
Win_Array[NUM_FFT-index] = NewVal.i[1] + 1;
else Win_Array[NUM_FFT-index] = NewVal.i[1];
}
#endif
#if (WINDOW_TYPE == 0) // Compile this if no window has been specified
if (SE_data) // If data is single-ended,
{ // convert it to differential
for (index = 0; index < NUM_FFT; index++)
{
Win_Array[index] ^= 0x8000; // XOR MSB with ¡®1¡¯ to invert
}
}
#endif
} // END WindowCalc
//-----------------------------------------------------------------------------
// Bit_Reverse
//-----------------------------------------------------------------------------
//
// Sorts data in Bit Reversed Address order
//
// The BRTable[] array is used to find which values must be swapped. Only
// half of this array is stored, to save code space. The second half is
// assumed to be a mirror image of the first half.
//
void Bit_Reverse(INT16 BR_Array[])
{
#if (NUM_FFT >= 512)
WORD swapA, swapB, sw_cnt; // Swap Indices
#endif
#if (NUM_FFT <= 256)
unsigned char swapA, swapB, sw_cnt; // Swap Indices
#endif
INT16 TempStore;
// Loop through locations to swap
for (sw_cnt = 1; sw_cnt < NUM_FFT/2; sw_cnt++)
{
swapA = sw_cnt; // Store current location
swapB = BRTable[sw_cnt] * 2; // Retrieve bit-reversed index
if (swapB > swapA) // If the bit-reversed index is
{
// larger than the current index,
TempStore = BR_Array[swapA]; // the two data locations are
BR_Array[swapA] = BR_Array[swapB]; // swapped. Using this comparison
BR_Array[swapB] = TempStore; // ensures that locations are only
} // swapped once, and never with
// themselves
swapA += NUM_FFT/2; // Now perform the same operations
swapB++; // on the second half of the data
if (swapB > swapA)
{
TempStore = BR_Array[swapA];
BR_Array[swapA] = BR_Array[swapB];
BR_Array[swapB] = TempStore;
}
}
} // END Bit Reverse Order Sort
void Int_FFT(INT16 ReArray[], INT16 ImArray[])
{
#if (NUM_FFT >= 512)
WORD sin_index, g_cnt, s_cnt; // Keeps track of the proper index
WORD indexA, indexB; // locations for each calculation
#endif
#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
WORD group = NUM_FFT/4, stage = 2;
long CosVal, SinVal;
long TempImA, TempImB, TempReA, TempReB, TempReA2, TempReB2;
IBALONG ReTwid, ImTwid, TempL;
// FIRST STAGE - optimized for REAL input data only. This will set all
// Imaginary locations to zero.
//
// Shortcuts have been taken to remove unnecessary multiplications during this
// stage. The angle ¡°x¡± is 0 radians for all calculations at this point, so
// the SIN value is equal to 0.0 and the COS value is equal to 1.0.
// Additionally, all Imaginary locations are assumed to be ¡®0¡¯ in this stage of
// the algorithm, and are set to ¡®0¡¯.
indexA = 0;
for (g_cnt = 0; g_cnt < NUM_FFT/2; g_cnt++)
{
indexB = indexA + 1;
TempReA = ReArray[indexA];
TempReB = ReArray[indexB];
// Calculate new value for ReArray[indexA]
TempL.l = (long)TempReA + TempReB;
if ((TempL.l < 0)&&(0x01 & TempL.b[0]))
TempReA2 = (TempL.l >> 1) + 1;
else TempReA2 = TempL.l >> 1;
// Calculate new value for ReArray[indexB]
TempL.l = (long)TempReA - TempReB;
if ((TempL.l < 0)&&(0x01 & TempL.b[0]))
ReArray[indexB] = (TempL.l >> 1) + 1;
else ReArray[indexB] = TempL.l >> 1;
ReArray[indexA] = TempReA2;
ImArray[indexA] = 0; // set Imaginary locations to ¡®0¡¯
ImArray[indexB] = 0;
indexA = indexB + 1;
//
}
// END OF FIRST STAGE
while (stage <= NUM_FFT/2)
{
indexA = 0;
sin_index = 0;
for (g_cnt = 0; g_cnt < group; g_cnt++)
{
for (s_cnt = 0; s_cnt < stage; s_cnt++)
{
indexB = indexA + stage;
TempReA = ReArray[indexA];
TempReB = ReArray[indexB];
TempImA = ImArray[indexA];
TempImB = ImArray[indexB];
// The following first checks for the special
FFT.rar_C++ FFT_fft_算法_项目
版权申诉
76 浏览量
2022-09-21
22:29:40
上传
评论
收藏 17KB RAR 举报
邓凌佳
- 粉丝: 63
- 资源: 1万+
最新资源
- 图书管理系统(ssm+jsp+mysql5.x)含演示视频含项目文档.zip
- 编译原理深⼊词法分析实践-实验报告
- Disk-Drill数据恢复软件MAC版,支持最新arm架构
- 上班摸鱼神器-纯透明小说阅读工具
- 音频视频转文字3.7.7每天都可以转3小时.apk
- rain-ripples.PNG
- Gitlab: Python项目CI/CD实践 > fastapi-t1 > Dockerfile
- Epic Toon FX 史诗卡通特效 Unity像素游戏素材特效美术资源unitypackage
- 概率论与潮流统计学在时尚产业的应用(文档加Matlab源码)
- springboot的校园失物招领系统源码.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈