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.

PMSM3_1 - ADC conversion problem (the conversion result jumps within range 0x1000)

 

I am working with the PMSM3_1. I am currently on build 2 (measuring the phase currents)

 

The application note uses the module in the “F280XILEG_VDC.H” to measure the currents.

 

The init() function as supplied by TI looks like this:

void F280X_ileg2_dcbus_drv_init(ILEG2DCBUSMEAS *p)

{

    DELAY_US(ADC_usDELAY);      

 

    AdcRegs.ADCTRL1.all = ADC_RESET_FLAG;             // Reset the ADC Module

           asm(" NOP ");

           asm(" NOP ");   

    AdcRegs.ADCTRL3.bit.ADCBGRFDN = 0x3;              // Power up bandgap/reference circuitry

           DELAY_US(ADC_usDELAY);                     // Delay before powering up rest of ADC

   

    AdcRegs.ADCTRL3.bit.ADCPWDN = 1;                  // Power up rest of ADC

           DELAY_US(ADC_usDELAY);          

 

    AdcRegs.ADCTRL3.bit.ADCCLKPS = 16;                // Set up ADCTRL3 register

    AdcRegs.ADCTRL1.all = ADCTRL1_INIT_STATE;         // Set up ADCTRL1 register

    AdcRegs.ADCTRL2.all = ADCTRL2_INIT_STATE;         // Set up ADCTRL2 register

    AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 2;             // Specify three conversions

    AdcRegs.ADCCHSELSEQ1.all = p->ChSelect;           // Configure channel selection

 

    AdcRegs.ADCREFSEL.all = 39;                       // Set up the ADC reference select register

    AdcRegs.ADCOFFTRIM.all = 65534;                   // Set up the ADC offset trim register

 

    // Set up Event Trigger with CNT_zero enable for Time-base of EPWM1

    EPwm1Regs.ETSEL.bit.SOCAEN = 1;                   // Enable SOCA

    EPwm1Regs.ETSEL.bit.SOCASEL = 1;                  // Enable CNT_zero event for SOCA

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

    EPwm1Regs.ETCLR.bit.SOCA = 1;                     // Clear SOCA flag

 


The read() function looks like this:

void F280X_ileg2_dcbus_drv_read(ILEG2DCBUSMEAS *p)

{

       int16 DatQ15;

       int32 Tmp;

 

        // Wait until ADC conversion is completed

        while (AdcRegs.ADCST.bit.SEQ1_BSY == 1)

        {};

 

        DatQ15 = AdcRegs.ADCRESULT0^0x8000;       // Convert raw result to Q15 (bipolar signal)

        Tmp = (int32)p->ImeasAGain*(int32)DatQ15; // Tmp = gain*dat => Q28 = Q13*Q15

        p->ImeasA = (int16)(Tmp>>13);             // Convert Q28 to Q15

        p->ImeasA += p->ImeasAOffset;             // Add offset

        p->ImeasA *= -1;                          // Positive direction, current flows to motor

 

        DatQ15 = AdcRegs.ADCRESULT1^0x8000;       // Convert raw result to Q15 (bipolar signal)

        Tmp = (int32)p->ImeasBGain*(int32)DatQ15; // Tmp = gain*dat => Q28 = Q13*Q15

        p->ImeasB = (int16)(Tmp>>13);             // Convert Q28 to Q15

        p->ImeasB += p->ImeasBOffset;             // Add offset

        p->ImeasB *= -1;                          // Positive direction, current flows to motor

 

        DatQ15 = (AdcRegs.ADCRESULT2>>1)&0x7FFF;   // Convert raw result to Q15 (unipolar signal)

        Tmp = (int32)p->VdcMeasGain*(int32)DatQ15; // Tmp = gain*dat => Q28 = Q13*Q15

        if (Tmp > 0x0FFFFFFF)                      // Limit Tmp to 1.0 in Q28

           Tmp = 0x0FFFFFFF;

        p->VdcMeas = (int16)(Tmp>>13);             // Convert Q28 to Q15

        p->VdcMeas += p->VdcMeasOffset;            // Add offset

 

        p->ImeasC = -(p->ImeasA + p->ImeasB);      // Compute phase-c current

 

        AdcRegs.ADCTRL2.all |= 0x4040;             // Reset the sequence

}            

 

 


The strange thing is that when I watch ADCRESULT0 and ADCRESULT1 (in the watch-window) supplied with a constant 2.5V (connected to channel ADC0 and ADC1). The values jump between 0x5840 and 0x4890 (on both channels). I have measured the signal using an oscilloscope and I cannot see any dip in the signal.

 

Any thoughts on this strange behavior?


Thanks

 

 

  • Well, if you have a constant voltage connected then you should get a stable reading. How stable are these supplies? Have you checked the noise level of your board? Also, check if you have grounds connected properly. Good luck.

  • I am using a regular power supply, but I can check the signal with an oscilloscope.

    What do you mean by checking the noise level of the board? (I have checked the supply signal to the board and that seems stable as well)

    Thanks

  • Well, you can check the ground voltage itself to have some idea about the noise level. Do you have any switching elelments in your system? If not then most likely noise will be low. In that case check the ground connections. If everything checks out then I guess check your controller itself. I am almost certain these example code works so... keep looking :-)

  • With your code snippet above you did no show us how you have called the init function. So we cannot see how register ADCCHSELSEQ1 is actually initialized. Could it be that you have initialized not the correct input channels?

     

     

  • Hello Frank.

    This is how initialization of the module is done, I have not changed anything. Measuring is done on channel 0,1 and 7.

     

    /* ==================================================================================

    File name:       F280XILEG_VDC.H

                       

    Originator:           Digital Control Systems Group

                                     Texas Instruments

     

    Description: This header file contains source for the F280X Two leg current measurement

    and DC-bus measurement driver.

     

    Target: TMS320F280x family

                 

    =====================================================================================

    History:

    -------------------------------------------------------------------------------------

     04-15-2005           Version 3.20: Using DSP280x v. 1.10 or higher

    ------------------------------------------------------------------------------------*/

     

    #ifndef __F280XILEG_VDC_H__

    #define __F280XILEG_VDC_H__

     

    #include "f280xbmsk.h"

     

    /*-----------------------------------------------------------------------------

    Define the structure of the ILEG2DCBUSMEAS Object

    -----------------------------------------------------------------------------*/

    typedef struct { int16 ImeasAGain;     // Parameter: gain for Ia (Q13)

                     int16 ImeasAOffset;   // Parameter: offset for Ia (Q15)

                     int16 ImeasA;         // Output: measured Ia (Q15)

                     int16 ImeasBGain;     // Parameter: gain for Ib (Q13)

                     int16 ImeasBOffset;   // Parameter: offset for Ib (Q15)

                     int16 ImeasB;         // Output: measured Ib (Q15)

                     int16 VdcMeasGain;    // Parameter: gain for Vdc (Q13)

                     int16 VdcMeasOffset;  // Parameter: offset for Vdc (Q15)

                     int16 VdcMeas;        // Output: measured Vdc (Q15)

                     int16 ImeasC;                      // Output: computed Ic (Q15)    

                     Uint16 ChSelect;      // Parameter: ADC channel selection

                     void (*init)();       // Pointer to the init function

                     void (*read)();       // Pointer to the read function

                   } ILEG2DCBUSMEAS;

     

    typedef ILEG2DCBUSMEAS *ILEG2DCBUSMEAS_handle;

    /*-----------------------------------------------------------------------------

     Note 1 : It is necessary to call the init function to change the ADC

                register settings, for the change in the channel setting for

                ChSelect setting changes to take effect.

                The read function will not detect or act upon this change.

    -----------------------------------------------------------------------------*/

    #define F280X_ILEG2_DCBUS_MEAS_DEFAULTS { 0x1FFF,0x0000,0x0000,             \

                                              0x1FFF,0x0000,0x0000,             \

                                              0x1FFF,0x0000,0x0000,             \

                                              0x0000,0x0710,                    \

                                              (void (*)(Uint32))F280X_ileg2_dcbus_drv_init, \

                                              (void (*)(Uint32))F280X_ileg2_dcbus_drv_read  \

                                             }

     

    #define ILEG2DCBUSMEAS_DEFAULTS F280X_ILEG2_DCBUS_MEAS_DEFAULTS

     

    #define ADCTRL1_INIT_STATE  ADC_SUS_MODE0 + ADC_ACQ_PS_16 + \

                                ADC_CPS_2 + ADC_SEQ_CASC

     

    #define ADCTRL2_INIT_STATE  ADC_EPWM_SOCA_SEQ1

     

    /*------------------------------------------------------------------------------

     Prototypes for the functions in F280XILEG_VDC.C

    ------------------------------------------------------------------------------*/

    void F280X_ileg2_dcbus_drv_init(ILEG2DCBUSMEAS *);

    void F280X_ileg2_dcbus_drv_read(ILEG2DCBUSMEAS *);

     

    #endif // __F280XILEG_VDC_H__