打印

TMS2812 FFT库调用 问题求解

[复制链接]
3106|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tianyu01|  楼主 | 2011-8-17 12:40 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
fft, TMS, AD, ADC, dc
各位仁兄好!
    现在我在调试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
}

相关帖子

沙发
yoyowodeai| | 2011-8-17 21:31 | 只看该作者
不懂,帮顶=

使用特权

评论回复
板凳
lxn78| | 2011-8-18 14:37 | 只看该作者
呃,这些没用过,还是给你顶起来吧

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

785

帖子

1

粉丝