我正在使用 dsPIC33EP128GP502 并尝试运行 FFT 来测量输入的主频率。编译器没有显示任何错误,并且 ADC 本身似乎可以工作......(对于单个值)
我期望变量中的一些频率值在 0 Hz 和 ~96 kHz 之间peakFrequency
。对于噪声信号(或根本没有信号),该值应该或多或少是随机的。通过外部施加的单音信号,我希望测量输入频率 +/- ~100 Hz。可悲的是,我的频率输出始终为 0。
测试信号由外部信号发生器生成,如果我想测量单个值,ADC 工作正常!
由于某些性能需求,FFT 必须在 dsPIC33E 的 DSP 内核上运行。
有没有人对 dsPIC33E 有任何经验,并且知道我的错误是什么?
ADC:TAD -> 629.3 ns,转换触发 -> 清除采样位结束采样并开始转换,输出格式 -> 小数结果,有符号,自动采样 -> 启用
#include "mcc_generated_files/mcc.h"
#include <xc.h>
#include <dsp.h>
#define FFT_BLOCK_LENGTH 1024
#define LOG2_BLOCK_LENGTH 10
#define AUDIO_FS 192042
int16_t peakFrequencyBin;
uint16_t ix_MicADCbuff;
uint16_t peakFrequency;
fractional fftMaxValue;
fractcomplex twiddleFactors[FFT_BLOCK_LENGTH/2] __attribute__ ((space(xmemory)));
fractcomplex sigCmpx[FFT_BLOCK_LENGTH] __attribute__ ((space(ymemory), aligned(FFT_BLOCK_LENGTH * 2 *2)));
bool timeGetAdcSample = false;
void My_ADC_IRS(void)
{
timeGetAdcSample = true;
}
void readOutput(void)//Sample output
{
for(ix_MicADCbuff=0;ix_MicADCbuff<FFT_BLOCK_LENGTH;ix_MicADCbuff++)
{
ADC1_ChannelSelect(mix_output);
ADC1_SoftwareTriggerEnable();
while(!timeGetAdcSample); //wait for TMR1 interrupt (5.2072 us)
timeGetAdcSample = false;
ADC1_SoftwareTriggerDisable();
while(!ADC1_IsConversionComplete(mix_output));
sigCmpx[ix_MicADCbuff].real = ADC1_Channel0ConversionResultGet();
sigCmpx[ix_MicADCbuff].imag = 0;
}
}
void signalFreq(void)//Detect the dominant frequency
{
readOutput();
FFTComplexIP(LOG2_BLOCK_LENGTH, &sigCmpx[0], &twiddleFactors[0], COEFFS_IN_DATA);/
BitReverseComplex(LOG2_BLOCK_LENGTH, &sigCmpx[0]);
SquareMagnitudeCplx(FFT_BLOCK_LENGTH, &sigCmpx[0], &sigCmpx[0].real);
VectorMax(FFT_BLOCK_LENGTH/2, &sigCmpx[0].real, &peakFrequencyBin);
peakFrequency = peakFrequencyBin*(AUDIO_FS/FFT_BLOCK_LENGTH);
}
int main(void)
{
SYSTEM_Initialize();
TwidFactorInit(LOG2_BLOCK_LENGTH, &twiddleFactors[0], 0);
TMR1_SetInterruptHandler(My_ADC_IRS);
TMR1_Start();
while (1)
{
signalFreq();
UART1_32_Write((uint32_T)peakFrequency); // output via UART
}
return 1;
}
也许任何人都可以找出我的代码中的错误/问题!