TMS2812 FFT库调用 问题求解

2019-03-24 12:27发布

各位仁兄好!
    现在我在调试FFT的时候遇见好多问题,前面都解决掉了,就是FFT转换成幅值mag的时候怎么都不正确。
    我的调用方法如下(刚刚从网上直接修改的网友代码,和我的大同小异):
#include "DSP281x_Device.h" // DSP281x Headerfile Include File
#include "DSP281x_Examples.h" // DSP281x Examples Include File /* for test fft */
#include "fft.h"   // Prototype statements for functions found within this file.
    interrupt void adc_isr(void);   // Global variables used in this example:
    Uint16 LoopCount;
    Uint16 ConversionCount;
    Uint16 Voltage1[128];   #define N 128 //FFT Length
#pragma DATA_SECTION(ipcb, "FFTipcb");
#pragma DATA_SECTION(mag,"FFTmag");
RFFT32 fft=RFFT32_128P_DEFAULTS; long ipcb[N+2]; //In place computation buffer(这里直接用的RFFT,所以长度是N+2)
long mag[N/2+1]; //Magnitude buffer
const long win[N/2]=HAMMING128; //Window coefficient array
RFFT32_ACQ acq=FFTRACQ_DEFAULTS; //Instance the module   main()
{
    int i;       InitSysCtrl();//初始化cpu
    DINT;//关中断
    InitPieCtrl();//初始化pie寄存器   /* Initialize acquisition module */
    acq.buffptr=ipcb;
    acq.tempptr=ipcb;
    acq.size=N;
    acq.count=N;
    acq.acqflag=1;   /* Initialize FFT module */
    fft.ipcbptr=ipcb;
    fft.magptr=mag;// 这里是调用新的存储空间存储幅值
    fft.init(&fft);     IER = 0x0000;//禁止所有的中断
    IFR = 0x0000;       InitPieVectTable();//初始化pie中断向量表   // Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
    EALLOW; // This is needed to write to EALLOW protected register
    PieVectTable.ADCINT = &adc_isr;
    EDIS; // This is needed to disable write to EALLOW protected registers       AdcRegs.ADCTRL1.bit.RESET = 1; // Reset the ADC module
    asm(" RPT #10 || NOP"); // Must wait 12-cycles (worst-case) for ADC reset to take effect
    AdcRegs.ADCTRL3.all = 0x00C8; // first power-up ref and bandgap circuits
    AdcRegs.ADCTRL3.bit.ADCBGRFDN = 0x3; // Power up bandgap/reference circuitry
    AdcRegs.ADCTRL3.bit.ADCPWDN = 1; // Power up rest of ADC // Enable ADCINT in PIE
    PieCtrlRegs.PIEIER1.bit.INTx6 = 1;
    IER |= M_INT1; // Enable CPU Interrupt 1
    EINT; // Enable Global interrupt INTM
    ERTM; // Enable Global realtime interrupt DBGM       LoopCount = 0;
    ConversionCount = 1;   // Configure ADC
    AdcRegs.ADCMAXCONV.all = 0x0001; // Setup 2 conv's on SEQ1
    AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0; // Setup ADCINA3 as 1st SEQ1 conv.
    AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1; // Setup ADCINA2 as 2nd SEQ1 conv.
    AdcRegs.ADCTRL2.bit.EVA_SOC_SEQ1 = 1; // Enable EVASOC to start SEQ1
    AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // Enable SEQ1 interrupt (every EOS)   // Configure EVA
// Assumes EVA Clock is already enabled in InitSysCtrl();
    EvaRegs.T2CMPR = 0x0000; // Setup T1 compare value 这里改了 我的采样是6.4k的,用的t2计数器,具体设置应该没错
    EvaRegs.T1PR = ; // Setup period register
    EvaRegs.GPTCONA.bit.T1TOADC = 1; // Enable EVASOC in EVA
    EvaRegs.T1CON.all = 0x1042; // Enable timer 1 compare (upcount mode)   // Wait for ADC interrupt
    while(1)
    {
        //LoopCount++;
        if (acq.acqflag==0) // If the samples are acquired
        {
            DINT;
            //RFFT32_brev(ipcb,ipcb,N);
            //RFFT32_brev(ipcb,ipcb,N); // Input samples in Real Part
            // 这里不知道为什么 会调用两次(FFT库的调用例子是这样做的)
           
            fft.win(&fft);             //RFFT32_brev(ipcb,ipcb,N);
            //RFFT32_brev(ipcb,ipcb,N); // Input samples in Real Part
            // 这里不知道为什么 会调用两次(FFT库的调用例子是这样做的)             fft.calc(&fft);
            fft.split(&fft);
            fft.mag(&fft);
            for(i=0;i<N;i++)
            {
                mag=sqrt(mag);
                //这里调用后mag只有在i==0,i==1的时候有比较大的值,其他点都很小,
                //我用的是50hz的正弦信号,理论上mag[0]应该是DC分量(好像是N倍的关系),
                //mag[1]应该是50hz的信号幅值(N/2倍的关系),但是实际计算出来不对,
                //我不送信号和送信号的时候这里的计算值基本上不变,我再调节信号幅值后,
                //mag[1]是变化的(不稳定),理论上这里出来的值是稳定的,信号的幅值,
                //实际不是,请网友们帮我看看问题出在哪里。我实在是头大了。
            }
            acq.acqflag=1; // Enable the next acquisition
            EINT;
        }
    }
} interrupt void adc_isr(void)
{
    Voltage1[ConversionCount] = AdcRegs.ADCRESULT0>>4;     if(acq.acqflag==1)
    {
        acq.input=((unsigned long)Voltage1[ConversionCount])<<16;
        acq.update(&acq);
    }
// Reinitialize for next ADC sequence
    AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; // Reset SEQ1
    AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; // Clear INT SEQ1 bit
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge interrupt to PIE
}
  此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
3条回答
dontium
2019-03-24 19:39
< :TI_MSP430_内容页_SA7 --> FFT库应该看,FFT的原理更需要看!我对FFT知道得较少,但觉得你的问题可以在学习FFT知识后得到解答

一周热门 更多>

相关问题

    相关文章