This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

关于28335 ADC+FFT

Other Parts Discussed in Thread: CONTROLSUITE

您好,我对controsuite中的ti\controlSUITE\libs\dsp\FPU\v1_40_00_00\examples_ccsv5\2833x_rfft_adc_rt例程进行了一些修改,ad采样配置为单通道每次采样中断,在adc_isr中每次新采样的数据放在数组的最后一位,同时原来数组中的元素都向左移动一位,去掉第一个元素,当中断进行了128次后,FFTFLAG置1,进行fft,现在的问题是FFTFLAG始终保持1不变,无法清零,ADC可以正常运行,但fft无法运行,请各位高手帮我看看,代码如下:

//#include "DSP28x_Project.h"
#include "DSP2833x_Device.h"     //// DSP2833x Headers
#include "DSP2833x_Examples.h"   //// DSP2833x Examples
#include "fpu_rfft.h"
#include "AD9956.h"


#define RFFT_STAGES     10
#define RFFT_SIZE       (1 << RFFT_STAGES)

#define ADC_BUF_LEN         RFFT_SIZE   // ADC buffer length

RFFT_ADC_F32_STRUCT rfft_adc;
RFFT_F32_STRUCT rfft;


float RFFToutBuff[RFFT_SIZE];                //Calculated FFT result
float RFFTF32Coef[RFFT_SIZE];        //Coefficient table buffer
float RFFTmagBuff[RFFT_SIZE/2+1];      //Magnitude of frequency spectrum

//--- Global Variables
uint16_t AdcBuf[ADC_BUF_LEN];                   // ADC buffer allocation

volatile uint16_t FFTStartFlag = 0;         // One frame data ready flag


int counter = 0;                                        // ADC interrupt counter



/***************************************************************************/
// Prototype statements for functions found within this file.
interrupt void adc_isr(void);
/**********************************************************************
* Function: main()
*
* Description: Main function for C2833x Real-time RFFT
**********************************************************************/
void main(void)
{
    uint16_t i,j;


//--- CPU Initialization
    InitSysCtrl();                      // Initialize the CPU (FILE: SysCtrl.c)
//  InitPieCtrl();                      // Initialize and enable the PIE (FILE: PieCtrl.c)
//  InitCpuTimers();                    // Initialize CPU Timers



//--- 初始化FFT
    rfft_adc.Tail = &rfft.OutBuf;               //Link the RFFT_ADC_F32_STRUCT to
                                                //RFFT_F32_STRUCT. Tail pointer of
                                                //RFFT_ADC_F32_STRUCT is passed to
                                                //the OutBuf pointer of RFFT_F32_STRUCT
    rfft.FFTSize  = RFFT_SIZE;                  //Real FFT size
    rfft.FFTStages = RFFT_STAGES;               //Real FFT stages
    rfft_adc.InBuf = &AdcBuf[0];                //Input buffer
    rfft.OutBuf = &RFFToutBuff[0];              //Output buffer
    rfft.CosSinBuf = &RFFTF32Coef[0];           //Twiddle factor
    rfft.MagBuf = &RFFTmagBuff[0];              //Magnitude output buffer

    RFFT_f32_sincostable(&rfft);                //Calculate twiddle factor

    //Clean up output buffer
    for (i=0; i < RFFT_SIZE; i++)
    {
         RFFToutBuff[i] = 0;
         AdcBuf[i] = 0;
    }

    //Clean up magnitude buffer
    for (i=0; i < RFFT_SIZE/2; i++)
    {
         RFFTmagBuff[i] = 0;
    }

//--- 初始化中断
    InitPieCtrl();

//--- 初始化中断向量表
    InitPieVectTable();

//// ISR Functions
    EALLOW;
    PieVectTable.ADCINT = &adc_isr;
    EDIS;

//// Initialize the CPU Timers
    InitCpuTimers();



//--- 全局中断设定
    PieCtrlRegs.PIEIER1.bit.INTx6 = 1;
    PieCtrlRegs.PIEIER1.bit.INTx7 = 1;

//// Enable CPU INT1
    IER = 1;

//// Enable global Interrupts and higher priority real-time debug events
    EINT;   // Enable Global interrupt INTM
    ERTM;   // Enable Global RealTime interrupt DBGM

//// Specific ADC setup
    InitAdc();
    AdcRegs.ADCMAXCONV.all = 0x0000;            // Setup 1 ADCMAXCONV on SEQ1
    AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x02;     // Choose ADCINA2 to sample
    AdcRegs.ADCTRL1.bit.ACQ_PS = 7;
    AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;     // Enable SOCA from ePWM to start SEQ1
    AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1;       // Enable SEQ1 interrupt
    AdcRegs.ADCTRL3.bit.ADCCLKPS = 3;
//// Assumes ePWM1 clock is already enabled in InitSysCtrl()
    EPwm1Regs.ETSEL.bit.SOCAEN = 1;             // Enable SOC on A group
    EPwm1Regs.ETSEL.bit.SOCASEL = 4;            // Select SOC from CPMA on countup
    EPwm1Regs.ETPS.bit.SOCAPRD = 1;             // 第一次触发ADC
    EPwm1Regs.CMPA.half.CMPA = 0x003E;          // 比较直62
    EPwm1Regs.TBPRD = 0x0176;                   // 周期374 200kHz
    EPwm1Regs.TBCTL.bit.CTRMODE = 0;            // 向上计数

//--- Main Loop
    while(1)                            // endless loop - wait for an interrupt
    {
        if(FFTStartFlag)                // If one frame data ready, then do FFT
        {

            RFFT_adc_f32u(&rfft_adc);   // This version of FFT doesn't need buffer alignment
            RFFT_f32_mag(&rfft);        // Calculate spectrum amplitude

                FFTStartFlag = 0;               //Start collecting the next frame of data
        }

    }
} //end of main()



interrupt void  adc_isr(void)
{

    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;             // Must acknowledge the PIE group

//--- Manage the ADC registers
    AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;                   // Reset SEQ1 to CONV00 state
    AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;                 // Clear ADC SEQ1 interrupt flag

        int z;
//  读取数据和数据更新
    for(z=1;z<ADC_BUF_LEN;z++)
    {
        AdcBuf[z-1] = AdcBuf[z];
    }
    AdcBuf[ADC_BUF_LEN-1] = AdcMirror.ADCRESULT0;               // Read the result

    counter++;

    if(counter == 128)
    {
        counter = 0;
        FFTStartFlag = 1;                               // One frame data ready
    }
} //end of main()

//===========================================================================
// End of File
//===========================================================================

  • 您好,我想使用28335的ad采样模块和fpu/dsp/rfft对采样数据进行实时时频分析,但是在实际应用中如果按照例程C:\ti\controlSUITE\libs\dsp\FPU\v1_40_00_00\examples_ccsv5\2833x_rfft_adc_rt中采样512点所需时间较长,不满足实时性需求。我希望每采样128点后删除AdcBuf中最早的128点数据并补充上最新的128点采样数据,这样每次进行FFT的间隔就是采样128点所需的时间。但是我不知道adc中断程序,可使得数组更新高效的运行。请各位多多指教。

    adc中断程序

    interrupt void adc_isr(void)
    {
    static uint16_t *AdcBufPtr = AdcBuf; // Pointer to ADC data buffer
    static volatile uint16_t GPIO34_count = 0; // Counter for pin toggle

    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Must acknowledge the PIE group

    //--- Manage the ADC registers
    AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; // Reset SEQ1 to CONV00 state
    AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; // Clear ADC SEQ1 interrupt flag

    //--- Read the ADC result
    *AdcBufPtr++ = AdcMirror.ADCRESULT0; // Read the result

    //--- Brute-force the circular buffer
    if( AdcBufPtr == (AdcBuf + ADC_BUF_LEN) )
    {
    AdcBufPtr = AdcBuf; // Rewind the pointer to the beginning
    FFTStartFlag = 1; // One frame data ready
    }

    //--- Example: Toggle GPIO18 so we can read it with the ADC
    if(DEBUG_TOGGLE == 1)
    {
    GpioDataRegs.GPATOGGLE.bit.GPIO18 = 1; // Toggle the pin
    }

    //--- Example: Toggle GPIO34 at a 0.5 sec rate (connected to the LED on the ControlCARD).
    // (1/48000 sec/sample)*(1 samples/int)*(x interrupts/toggle) = (0.5 sec/toggle)
    // ==> x = 24000
    if(GPIO34_count++ > 24000) // Toggle slowly to see the LED blink
    {
    GpioDataRegs.GPBTOGGLE.bit.GPIO34 = 1; // Toggle the pin
    GPIO34_count = 0; // Reset the counter
    }

    return;
    } //end of main()

  • 您好,我对controsuite中的ti\controlSUITE\libs\dsp\FPU\v1_40_00_00\examples_ccsv5\2833x_rfft_adc_rt例程进行了一些修改,ad采样配置为单通道每次采样中断,在adc_isr中每次新采样的数据放在数组的最后一位,同时原来数组中的元素都向左移动一位,去掉第一个元素,当中断进行了128次后,FFTFLAG置1,进行fft,现在的问题是FFTFLAG始终保持1不变,无法清零,ADC可以正常运行,但fft无法运行,请各位高手帮我看看,代码如下:

    //#include "DSP28x_Project.h"
    #include "DSP2833x_Device.h"     //// DSP2833x Headers
    #include "DSP2833x_Examples.h"   //// DSP2833x Examples
    #include "fpu_rfft.h"
    #include "AD9956.h"
    
    
    #define RFFT_STAGES     10
    #define RFFT_SIZE       (1 << RFFT_STAGES)
    
    #define ADC_BUF_LEN         RFFT_SIZE   // ADC buffer length
    
    RFFT_ADC_F32_STRUCT rfft_adc;
    RFFT_F32_STRUCT rfft;
    
    
    float RFFToutBuff[RFFT_SIZE];                //Calculated FFT result
    float RFFTF32Coef[RFFT_SIZE];        //Coefficient table buffer
    float RFFTmagBuff[RFFT_SIZE/2+1];      //Magnitude of frequency spectrum
    
    //--- Global Variables
    uint16_t AdcBuf[ADC_BUF_LEN];					// ADC buffer allocation
    
    volatile uint16_t FFTStartFlag = 0;			// One frame data ready flag
    
    
    int counter = 0;                                        // ADC interrupt counter
    
    
    
    /***************************************************************************/
    // Prototype statements for functions found within this file.
    interrupt void adc_isr(void);
    /**********************************************************************
    * Function: main()
    *
    * Description: Main function for C2833x Real-time RFFT
    **********************************************************************/
    void main(void)
    {
    	uint16_t i,j;
    
    
    //--- CPU Initialization
    	InitSysCtrl();						// Initialize the CPU (FILE: SysCtrl.c)
    //	InitPieCtrl();						// Initialize and enable the PIE (FILE: PieCtrl.c)
    //	InitCpuTimers();                    // Initialize CPU Timers
    
    
    
    //--- 初始化FFT
        rfft_adc.Tail = &rfft.OutBuf;				//Link the RFFT_ADC_F32_STRUCT to
       												//RFFT_F32_STRUCT. Tail pointer of
       												//RFFT_ADC_F32_STRUCT is passed to
       												//the OutBuf pointer of RFFT_F32_STRUCT
        rfft.FFTSize  = RFFT_SIZE;				    //Real FFT size
        rfft.FFTStages = RFFT_STAGES;			    //Real FFT stages
        rfft_adc.InBuf = &AdcBuf[0];				//Input buffer
        rfft.OutBuf = &RFFToutBuff[0];   			//Output buffer
        rfft.CosSinBuf = &RFFTF32Coef[0];	        //Twiddle factor
        rfft.MagBuf = &RFFTmagBuff[0];		        //Magnitude output buffer
    
        RFFT_f32_sincostable(&rfft);  				//Calculate twiddle factor
    
     	//Clean up output buffer
        for (i=0; i < RFFT_SIZE; i++)
        {
        	 RFFToutBuff[i] = 0;
        	 AdcBuf[i] = 0;
        }
    
       	//Clean up magnitude buffer
        for (i=0; i < RFFT_SIZE/2; i++)
        {
       		 RFFTmagBuff[i] = 0;
        }
    
    //--- 初始化中断
        InitPieCtrl();
    
    //--- 初始化中断向量表
        InitPieVectTable();
    
    //// ISR Functions
        EALLOW;
        PieVectTable.ADCINT = &adc_isr;
        EDIS;
    
    //// Initialize the CPU Timers
        InitCpuTimers();
    
    
    
    //--- 全局中断设定
        PieCtrlRegs.PIEIER1.bit.INTx6 = 1;
        PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
    
    //// Enable CPU INT1
        IER = 1;
    
    //// Enable global Interrupts and higher priority real-time debug events
        EINT;   // Enable Global interrupt INTM
        ERTM;   // Enable Global RealTime interrupt DBGM
    
    //// Specific ADC setup
        InitAdc();
       	AdcRegs.ADCMAXCONV.all = 0x0000;            // Setup 1 ADCMAXCONV on SEQ1
       	AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x02;     // Choose ADCINA2 to sample
       	AdcRegs.ADCTRL1.bit.ACQ_PS = 7;
       	AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;     // Enable SOCA from ePWM to start SEQ1
       	AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1;       // Enable SEQ1 interrupt
        AdcRegs.ADCTRL3.bit.ADCCLKPS = 3;
    //// Assumes ePWM1 clock is already enabled in InitSysCtrl()
       	EPwm1Regs.ETSEL.bit.SOCAEN = 1;             // Enable SOC on A group
       	EPwm1Regs.ETSEL.bit.SOCASEL = 4;            // Select SOC from CPMA on countup
       	EPwm1Regs.ETPS.bit.SOCAPRD = 1;             // 第一次触发ADC
        EPwm1Regs.CMPA.half.CMPA = 0x003E;	        // 比较直62
        EPwm1Regs.TBPRD = 0x0176;                   // 周期374 200kHz
       	EPwm1Regs.TBCTL.bit.CTRMODE = 0;		    // 向上计数
    
    //--- Main Loop
    	while(1)							// endless loop - wait for an interrupt
    	{
    		if(FFTStartFlag)				// If one frame data ready, then do FFT
    		{
    
    			RFFT_adc_f32u(&rfft_adc);   // This version of FFT doesn't need buffer alignment
    			RFFT_f32_mag(&rfft);		// Calculate spectrum amplitude
    
    		        FFTStartFlag = 0;			   	//Start collecting the next frame of data
    		}
    
    	}
    } //end of main()
    
    
    
    interrupt void  adc_isr(void)
    {
    
       	PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;				// Must acknowledge the PIE group
    
    //--- Manage the ADC registers
    	AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;					// Reset SEQ1 to CONV00 state
    	AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;					// Clear ADC SEQ1 interrupt flag
    
            int z;
    //  读取数据和数据更新
    	for(z=1;z<ADC_BUF_LEN;z++)
    	{
    		AdcBuf[z-1] = AdcBuf[z];
    	}
    	AdcBuf[ADC_BUF_LEN-1] = AdcMirror.ADCRESULT0;				// Read the result
    
    	counter++;
    
    	if(counter == 128)
    	{
    		counter = 0;
    		FFTStartFlag = 1;								// One frame data ready
    	}
    } //end of main()
    
    //===========================================================================
    // End of File
    //===========================================================================
    
    

  • 为更加有效地解决您的问题,我们建议您将问题发布在E2E英文技术论坛上https://e2e.ti.com/support/microcontrollers/c2000/f/171,将由资深的工程师为您提供帮助。我们的E2E英文社区有TI专家进行回复,并得到全球各地工程师的支持,分享他们的知识和经验。