0

我正在使用 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;
    }

也许任何人都可以找出我的代码中的错误/问题!

4

0 回答 0