FFT with dsPIC33E returns no frequency

149 Views Asked by At

I'm working with a dsPIC33EP128GP502 and try to run a FFT to measure the dominant frequency on the input. The compiler shows no errors and the ADC itself seems to work... (for single values)

I expect as result some frequency value between 0 Hz and ~96 kHz in the variable peakFrequency. With a noise signal (or no signal at all) the value should be more or less random. With an external applied single tone signal I expect to measure the input frequency +/- ~100 Hz. Sadly, my frequency output is always 0.

The test signals are generated by external signal generators and the ADC works fine if I want to measure single values!

The FFT has to run on the DSP-core of the dsPIC33E due to some performance needs.

Has anyone any experience with the dsPIC33E and an idea were my mistake is?

ADC: TAD -> 629.3 ns, Conversion Trigger -> Clearing sample bit ends sampling and starts conversion, Output Format -> Fractional result, signed, Auto Sampling -> enabled

    #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;
    }

Perhaps anyone can figure out the error/problem in my code!

0

There are 0 best solutions below