主题中讨论的其他器件:C2000WARE
您好
我使用 FFT 库、结果看起来不错、但我仍然有一些担忧 。
位于当前运行的代码片段上方。
1、我还不确定函数的顺序是否准确。
2、输入内容是 Q15格式的16位滤波 ADC 数据、在输入 FFT 数据之前、会将数据集转换为 Q30格式、这会造成精度显著降低。
当需要将 FFT 结果转换为 G 值时、如何解释 FFT 结果以将其与 ADC 结果链接回。
我是否应该在调用 rfft_calc 函数后使用_IQ30sqrt 函数?
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 函数后的结果吗?
Ismail,
您需要左移、从 Q15到 Q30、而不是右移。
平方根来获得幅度。 幅度值是原始值。
谢谢。
Sira
是的、我想说左移不是右、抱歉。
我修复了条目。
如我们所说的"原始值"、让我来验证一下我们是否在同一页。
假设我使用理想正弦波馈送 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
Ismail,
DSP 库生成的 MAG 是复数幅度的平方。 您可能需要取平方根以得到一个与预期值匹配的数字。
关于对 IQmath.lib 中 Q31的支持、我仍在检查。
谢谢。
Sira
Ismail,
您应该能够使用 Q30或 Q31进行 DSP 计算。
谢谢。
Sira