This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
您好
我使用 FFT 库、结果看起来不错、但我仍然有一些担忧 。
位于当前运行的代码片段上方。
1、我还不确定函数的顺序是否准确。
2、输入内容是 Q15格式的16位滤波 ADC 数据、在输入 FFT 数据之前、会将数据集转换为 Q30格式、这会造成精度显著降低。
当需要将 FFT 结果转换为 G 值时、如何解释 FFT 结果以将其与 ADC 结果链接回。
我是否应该在调用 rfft_calc 函数后使用_IQ30sqrt 函数?
void FFT_Compute(RFFT_t * this) { RFFT32* rff = this->RFFT; RFFT32_brev(this->Input.ReadyToUseBuff_Q30, &ipcb[0], FFT_SIZE); // Bit reversed this->RFFT->win(rff); // Q31 format (abs(ipcbsrc)/2^16).^2 this->RFFT->calc(rff); // Compute the FFT this->RFFT->split(rff); // Post processing to get the correct spectrum this->RFFT->mag(rff); // Q31 format (abs(ipcbsrc)/2^16).^2 }
感谢您的回复、
在我的 Iqmath.h 中、最大 IQ 分辨率为 IQ30、因为找不到 IQ31。
我将 SEL_Q.asm 文件中的 TF_QFMAT 设置为 Q30。 我希望输入表单是 Q30、而不是31。
G 是重力。
我的输入是在[032767]之间变化的加速计数据。
它们与 Q15兼容、因此我使用 Q15 FIR 和 IIR 函数、稍后我将向左移15位、以使它们与 Q30格式兼容。
但是、Q15的间隔是[-65,536,65535.999..." 然而,Q30的间隔是[-2,1.99999999]。
如果我们考虑 FFT 结果,结果将被映射在 Q30格式的间隔内,我不知道他们的工程单位,是原始值还是分贝等?
因为我的目标是重新解释输出幅度阵列。
BTW、我应该将 sqrt 应用于调用 magnetidu 函数后的结果吗?
是的、我想说左移不是右、抱歉。
我修复了条目。
如我们所说的"原始值"、让我来验证一下我们是否在同一页。
假设我使用理想正弦波馈送 FFT、其振幅值为固定频率下的32 (uint16)。
我之所以说32是因为根据我的转换表、它几乎等于1g。
FFT 是否应显示在该固定频率下振幅轴上的峰值高达32?
或者 我们不能这样说,因为不同的数学计算已应用到输入?
因为现在我将在输出端获得更高的 Int32值。
我将 FFT 输出与输入信号行为相关联所做的是制作一个宽范围 g 值列表、如
1G
2G
3G
...
1023g (上限)、检查输出端提供的 FFT 输出、并将这些输出与表中的 G 值进行映射。
然后、我根据上表对齐了一个抛物线函数、并将该函数插入固件中。
准确性不是最好的、这就是为什么我会问您是否遗漏了一点
Ismail,
您看一下 C2000Ware v5.01.00中的示例、该器件使用正弦输入、并且注释说明了输出中您可以预计到峰值的位置。
谢谢。
Sira
尊敬的 Sira:
//Simulated input signal for(i=0; i < FFT_SIZE; i++){ ipcbsrc[i] = (long)(2147483648*(sin(Rad) + cos(Rad*2.3567))/2); //Q31 Rad = Rad + RadStep; } RFFT32_brev(ipcbsrc, ipcb, FFT_SIZE); // real FFT bit reversing rfft.ipcbptr = ipcb; // FFT computation buffer rfft.magptr = ipcbsrc; // Magnitude output buffer rfft.winptr = (long *)win; // Window coefficient array rfft.init(&rfft); // Twiddle factor pointer initialization rfft.calc(&rfft); // Compute the FFT rfft.split(&rfft); // Post processing to get the correct spectrum rfft.mag(&rfft); // Q31 format (abs(ipcbsrc)/2^16).^2 //asm(" ESTOP0"); for(;;);
如 V1.20.00.00中的示例所示。
我怕,我不能得到它...
Ismail,
请下载 C2000Ware v5.01.00 (当前版本)、其中包含定点 DSP 库的 v1.27.00.00。
谢谢。
Sira
我下载了软件、但仍然无法理解我要做什么。
让我澄清一下我的情况。
我的 FFT 输入是经过滤波的 ADC 数据、是 FIR16的输出、因此我的输出将采用 Q15格式。
RFFT32指出 ipcbptr 需要 Q31格式的输入。
int32_t fft_input = (int32_t)hpfOutput << 15; //16
问题1: 修复了 DSP 纪录片、指出我们可以选择 Q30或 Q31。 我已经检查了我的 IQmathlib.h 并认为 Q30是最高支持的一个(查看下面的 #define 表)。
我应该左移15位还是16位? 我已经在 tf_selq.asm 文件顺便设置了 Q30。
#define QG GLOBAL_Q #define Q30 30 #define Q29 29 #define Q28 28 #define Q27 27 #define Q26 26 #define Q25 25 #define Q24 24 #define Q23 23 .... ....
问题2. 例如、该正弦波是 FIR 滤波器输出。 该信号以200Hz 的频率运行、最高峰值约为8000 ADC 原始值。
我知道8000 ADC 值(我们可以说大约是8000)大约等于200g。 另一方面、我看到 peakmag ~959087在移15位的情况下、如果我移动16位、则等于~3841694、是该值的~4倍。
在示例代码中、显示为
rfft.mag (&R); // Q31格式(abs (ipcbsrc)/2^16)。^2、
如果此等式可以帮助我获取 ADC 峰值,那么它是如何计算的呢?
RFFT32_brev(ipcb, ipcb, FFT_SIZE); // real FFT bit reversing rfft.ipcbptr = ipcb; // FFT computation buffer rfft.magptr = ipcbsrc; // Magnitude output buffer rfft.winptr = (int32_t *)win; // Window coefficient array rfft.init(&rfft); // Twiddle factor pointer initialization rfft.calc(&rfft); // Compute the FFT rfft.split(&rfft); // Post processing to get the correct spectrum rfft.mag(&rfft); // Q31 format (abs(ipcbsrc)/2^16).^2
让我来看看您的问题、特别是 IQMath lib Q 和幅度、然后给您回复。
Ismail,
DSP 库生成的 MAG 是复数幅度的平方。 您可能需要取平方根以得到一个与预期值匹配的数字。
关于对 IQmath.lib 中 Q31的支持、我仍在检查。
谢谢。
Sira
Ismail,
您应该能够使用 Q30或 Q31进行 DSP 计算。
谢谢。
Sira