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.

Sample and store a sine wave using ADC of piccolo mcu controlstick(f28027)

hi,

 

I am very new to dsp and just trying to do the basic stuff on Piccolo MCU control stick (F28027) by sampling a sine wave(1 KHz) and storing the results so that it can be reconstructed using matlab. 

I tried to execute the adc_soc program in control suite but that takes only one sample.

1. How to sample it continuously for a period of time?

2. Where to store data? if data is stored in an array then how to access it to analyse in Matlab. Is there any way to print it on a serial port or excel file directly?

3. Converting ADC result from hex to voltage, how to find VREFLO and VREFHI? 

4. Does the amplitude of incoming signal should be less than 3.3V always?

 

This control stick looks apt for my project. So please give me directions to learn this.

 

Thanks,

Neha

  • Can somebody help me a little?

    please reply..it is really important..

     

  • you need to set AdcRegs.INTSEL1N2.bit.INT1CONT  = 1; and also AdcRegs.ADCINTSOCSEL1.bit.SOC0 =1; so that the signal ADCINT1 will keep triggering a start of conversion on whatever channel you configured SOC0 to work on.

    you can save each adcresult to an array. Open this array in the memory window (View-> memory->type in array name in the window) and there is a little save icon that looks like a chip with an arrow in it. you can save whatever chunk of memory you want to disk as a .dat file and then have matlab read it

  • Can anybody tell me why this code is not sampling a 110Khz sine wave. I am trying to store 100 samples.

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

    // Prototype statements for functions found within this file.

    interrupt void adc_isr(void);

    void Adc_Config(void);

    // Global variables used in this example:

    Uint16 LoopCount;

    Uint16 ConversionCount;

    Uint16 Voltage1[100];

    //Uint16 Voltage2[100];

    main()

    {

    // Step 1. Initialize System Control:

    // PLL, WatchDog, enable Peripheral Clocks

    // This example function is found in the DSP2803x_SysCtrl.c file.

       InitSysCtrl();

     

    // Step 2. Initialize GPIO:

    // This example function is found in the DSP2802x_Gpio.c file and

    // illustrates how to set the GPIO to it's default state.

    // InitGpio();  // Skipped for this example

     

    // Step 3. Clear all interrupts and initialize PIE vector table:

    // Disable CPU interrupts

       DINT;

     

    // Initialize the PIE control registers to their default state.

    // The default state is all PIE interrupts disabled and flags

    // are cleared.

    // This function is found in the DSP2802x_PieCtrl.c file.

       InitPieCtrl();

     

    // Disable CPU interrupts and clear all CPU interrupt flags:

       IER = 0x0000;

       IFR = 0x0000;

     

    // Initialize the PIE vector table with pointers to the shell Interrupt

    // Service Routines (ISR).

    // This will populate the entire table, even if the interrupt

    // is not used in this example.  This is useful for debug purposes.

    // The shell ISR routines are found in DSP2802x_DefaultIsr.c.

    // This function is found in DSP2802x_PieVect.c.

       InitPieVectTable();

     

    // 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.ADCINT1 = &adc_isr;

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

     

    // Step 4. Initialize all the Device Peripherals:

    // This function is found in DSP2802x_InitPeripherals.c

    // InitPeripherals(); // Not required for this example

       InitAdc();  // For this example, init the ADC

     

    // Step 5. User specific code, enable interrupts:

     

    // Enable ADCINT1 in PIE

       PieCtrlRegs.PIEIER1.bit.INTx1 = 1; // Enable INT 1.1 in the PIE

       IER |= M_INT1; // Enable CPU Interrupt 1

       EINT;           // Enable Global interrupt INTM

       ERTM;           // Enable Global realtime interrupt DBGM

     

       LoopCount = 0;

       ConversionCount = 0;

     

    // Configure ADC 

     

    EALLOW;

    //AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1; //ADCINT1 trips after AdcResults latch

    AdcRegs.INTSEL1N2.bit.INT1E     = 1; //Enabled ADCINT1

    AdcRegs.INTSEL1N2.bit.INT1CONT  = 1; //enable ADCINT1 Continuous mode

    AdcRegs.INTSEL1N2.bit.INT1SEL = 1; //setup EOC2 to trigger ADCINT1 to fire

    AdcRegs.ADCSOC0CTL.bit.CHSEL = 4; //set SOC0 channel select to ADCINA4

    AdcRegs.ADCSOC1CTL.bit.CHSEL = 4; //set SOC1 channel select to ADCINA4

    //AdcRegs.ADCSOC2CTL.bit.CHSEL = 2; //set SOC2 channel select to ADCINA2

    AdcRegs.ADCSOC0CTL.bit.TRIGSEL = 5; //set SOC0 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1

    AdcRegs.ADCSOC1CTL.bit.TRIGSEL = 5; //set SOC1 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1

    //AdcRegs.ADCSOC2CTL.bit.TRIGSEL = 5; //set SOC2 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1, then SOC2

    AdcRegs.ADCSOC0CTL.bit.ACQPS = 6; //set SOC0 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)

    AdcRegs.ADCSOC1CTL.bit.ACQPS = 6; //set SOC1 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)

    //AdcRegs.ADCSOC2CTL.bit.ACQPS = 6; //set SOC2 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)

    AdcRegs.ADCINTSOCSEL1.bit.SOC0  = 1;

    AdcRegs.ADCINTSOCSEL1.bit.SOC1  = 1;

    EDIS;

     

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

     

    // Wait for ADC interrupt

       for(;;)

       {

          LoopCount++;

       }

    }

     

    interrupt void  adc_isr(void)

    {

      Voltage1[ConversionCount] = AdcResult.ADCRESULT1;  //discard ADCRESULT0 as part of the workaround to the 1st sample errata for rev0

     // Voltage2[ConversionCount] = AdcResult.ADCRESULT2;

     

      // If 200 conversions have been logged, start over

      if(ConversionCount == 100)

      {

         ConversionCount = 0;

      }

      else ConversionCount++;

     

      //AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //Clear ADCINT1 flag reinitialize for next SOC

      PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;   // Acknowledge interrupt to PIE

     

      return;

    }

    Thanks
    Neha

     

  • Which ADC channel are you supposed to be sampling the sine wave on?  Also if you set a breakpoint in adc_isr, does execution stop there and are new values being written to the Voltage1 array?

     

  • I am using ADCIN4 ie pin 5 of piccolo control stick. I am trying to understand the concept of EOC but it is not cleared yet in my mind.

    YES, the adc_isr stops if I set a breakpoint @conversioncount=0; and new values are written but all the values(16 bit unsigned integer) are in the same range or sometime all the 100 values are just zero.

     

  • it could be that continuous sampling is too fast and you are seeing only a small part of the sine wave

    you probably want to sample the sine wave at about 4x ~400 KHz. It would be better to have EPWM1A in upcount mode triggering SOC0 every 2.5 ms.

    Setup EPWM1a to have a CLKDIV of 0x00 and HSPCLKDIV of 0x00 so that the epwm module runs at SYSCLK(60MHz) and then set  TBPRD to 60MHz/400KHz ~ 150 and then have it trigger an SOC on each period match

     

    If you want to know more about the ADC check out the training wiki: http://processors.wiki.ti.com/index.php/Category:C2000_Training . The multi day workshops has some examples and slides that may be of useful