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.

TMS320F28335: TMS320F28335

Part Number: TMS320F28335
Other Parts Discussed in Thread: CONTROLSUITE,

Hi,

I'm using Code Composer Studio(CCS) 6.1.2.00015 

And I find a example project called "F2833x Real FFT with ADC Input (Real-time)" from controlSUITE

Here are the example file(s) for this project: C:\ti\controlSUITE\libs\dsp\FPU\v1_40_00_00\examples_ccsv5\2833x_rfft_adc_rt

My question is,  i apply input adc chacnnel A0 then how can calculated  fundamental frquency,Harmonics ? and how to set sampling rate.


Thanks for your help!

  • I'm not sure I understand your question correctly. The sinusoidal frequency you apply to the ADC (through your signal generator, for example) will be the fundamental frequency. Its odd multiples will be the harmonics. The example should tell you what the default sampling rate is.

    Remember that:

    •Digital freq (w) = Analog freq (f) x 2 x pi / fs (Sampling freq)
    •FFT range is from –pi to pi, where digital freq pi corresponds to analog freq fs/2 (anything beyond aliases, per the sampling theorem)
    •Frequency resolution = freq range/ number of bins = fs/2/N = fs/2N
    •So frequencies corresponding to integer multiples of the spectral resolution will appear as perfect peaks in the FFT, otherwise they will be smeared out
    Thanks,
    Sira
  • hello i given 230v-50Hz ac wave using voltae devider to given maximun 3V adc of tms320f28335 and i use code of example that is given below.

    #include "DSP28x_Project.h"     // Device Headerfile and Examples Include File

    #include "math.h"

    #include "float.h"

    #include "FPU.h"

     

    #define RFFT_STAGES     9

    #define RFFT_SIZE       (1 << RFFT_STAGES)

    #define ADC_MODCLK      0x4

    #define ADC_BUF_LEN         RFFT_SIZE   // ADC buffer length

    #define ADC_SAMPLE_PERIOD   3124            // 3124 = (3125-1) = 48 KHz sampling w/ 150 MHz SYSCLKOUT

     

    #define F_PER_SAMPLE        48000.0L/(float)RFFT_SIZE  //Internal sampling rate is 48kHz

     

    RFFT_ADC_F32_STRUCT rfft_adc;

    RFFT_F32_STRUCT rfft;

     

    float32 RFFToutBuff[RFFT_SIZE];                //Calculated FFT result

    float32 RFFTF32Coef[RFFT_SIZE];        //Coefficient table buffer

    float32 RFFTmagBuff[RFFT_SIZE/2+1];      //Magnitude of frequency spectrum

     

    //--- Global Variables

    Uint16 AdcBuf[ADC_BUF_LEN];                            // ADC buffer allocation

     

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

     

    Uint16 DEBUG_TOGGLE = 1;                               // Used in realtime mode investigation

    float32 freq;                       // Frequency of single-frequency-component signal

    // 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 i,j;

     

          

    //--- CPU Initialization

           InitSysCtrl();                                         // Initialize the CPU (FILE: SysCtrl.c)

           InitGpio();                                            // Initialize the shared GPIO pins (FILE: Gpio.c)

           InitPieCtrl();                                         // Initialize and enable the PIE (FILE: PieCtrl.c)

     

    //--- Peripheral Initialization

           InitAdc();                                             // Initialize the ADC (FILE: Adc.c)

           InitPieVectTable();

     

           EALLOW;

              SysCtrlRegs.HISPCP.all = ADC_MODCLK;

              EDIS;

     

    // 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;

     

           GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 0;

        GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1;

     

           EDIS;    // This is needed to disable write to EALLOW protected registers

     

     

     

           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.EPWM_SOCA_SEQ1 = 1;// Enable SOCA from ePWM to start SEQ1

              AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1;  // Enable SEQ1 interrupt (every EOS)

     

           // 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 from CPMA on upcount

           EPwm1Regs.ETPS.bit.SOCAPRD = 1;        // Generate pulse on 1st event

        //   EPwm1Regs.CMPA.half.CMPA = 0x0080;       // Set compare A value

              EPwm1Regs.TBPRD = 0xFFFF;              // Set period for ePWM1

              EPwm1Regs.TBCTL.bit.CTRMODE = 0;               // count up and start

     

           PieCtrlRegs.PIEIER1.bit.INTx6 = 1;

               IER |= M_INT1; // Enable CPU Interrupt 1

     

               EINT;

               ERTM;

     

           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;

        }

      

           //Clean up magnitude buffer

        for (i=0; i < RFFT_SIZE/2; i++)

        {

                   RFFTmagBuff[i] = 0;

        } 

     

    //--- Enable global interrupts

           asm(" CLRC INTM, DBGM");                 // Enable global interrupts and realtime debug

     

    //--- 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

                        

                         j = 1;

                         freq = RFFTmagBuff[1];

                         for(i=2;i<RFFT_SIZE/2+1;i++)

                         {

                               //Looking for the maximum valude of spectrum magnitude

                         if(RFFTmagBuff[i] > freq)

                         {

                               j = i;

                               freq = RFFTmagBuff[i];

                         }

                         }

      

                         freq = F_PER_SAMPLE * (float)j;   //Convert normalized digital frequency to analog frequency

                              

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

                  }

                  asm(" NOP");

           }

    } //end of main()

     

    interrupt void  adc_isr(void)

    {

           static Uint16 *AdcBufPtr = AdcBuf;                            // Pointer to ADC data buffer

           static volatile Uint16 GPIO34_count = 0;               // Counter for pin toggle

     

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

           GpioDataRegs.GPBTOGGLE.bit.GPIO34 = 1;   // 880 micro sec

    //--- 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()

     

    //===========================================================================

    // End of File

    //===========================================================================

     

     Thank you

     

     

  • So sampling frequency fs = 48kHz

    N= FFT size = 512

    So the spectral resolution is fs/2/N = 48000/1024 = 46.875

    Your input frequency is 50Hz, so you should see a peak in your FFT magnitude plot at Index 1. And then its harmonics are 150Hz (50 x3), 250Hz (50x5), etc.

    So you should see smaller peaks at index 3, index 5..

    Thanks,

    Sira 

  • thank you

    But i have some questions in fft code example and that questions are below

    1). What is the deffrence between

    #define ADC_SAMPLE_PERIOD   3124           // 3124 = (3125-1) = 48 KHz sampling w/ 150 MHz SYSCLKOUT

    and

    #define F_PER_SAMPLE       48000.0L/(float)RFFT_SIZE //Internal sampling rate is 48kHz.

    2). And another questions is that in your last replay you say "So the spectral resolution is fs/2/N = 48000/1024 = 46.875" but in that code FFT size is 512

    so why the equation fs/2/N because sampling frequency is 48000. so why taken  fs/2 ?

    Thank you

    vishal

  • 1. 48000 is the ADC sampling frequency in Hz. 48000/RFFT_SIZE is just a ratio, and it is called F_PER_SAMPLE.

    2. To understand this, you need to know the basics of sampling, beginning with the Sampling theorem. The FFT frequency range for bins 0 to N-1 corresponds to frequencies 0 to fs/2.

    Thanks,

    Sira

  • Let me know how else I can help or if we can close the issue (please mark as Resolved).

  • Thank you

    sorry for late replay,

    my doubt in why ADC_SAMPLE_PERIOD   3124? so if you know any formula for calculate ADC_SAMPLE_PERIOD   so say to me and i understand my doubt.

    #define ADC_SAMPLE_PERIOD   3124           // 3124 = (3125-1) = 48 KHz sampling w/ 150 MHz SYSCLKOUT

    Thank you

  • The SYSCLKOUT is 150MHz. You have to set the divider ratio to get the desired ADC sample rate. 150 x 1000000/3125 = 48000

    Suppose you want to change the ADC sample rate to 100kHz.

    Then, 150 x 1000000/ 100000 = 1500.

    So you will need to change the ADC_SAMPLE_PERIOD to 1499. If you trace ADC_SAMPLE_PERIOD in the project, you will see it is ultimately feeding into an ADC configuration register.

    Thanks,

    Sira

  • sorry for late replay 

    thank you

    Now i understood all this thing in Code 

    Thank you