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.

TLC2578

Other Parts Discussed in Thread: TLC2578, TLC3578

Dear Sir;

We have procured the samples of TLC2578 ADC. Currently we are facing the problems in SPI communication with the ADC.Could you please do the following needful,

1. C source file for SPI communication through MSP430 microcontroller with TLC2578.

2. When ADC's analog channel one is selected (which is connected to ground) for sample and conversion, The converted o/p was 0x9790 and 0x97A0.
When the same analog channel connected to +4.7volts , ADC converted value was 0x97C0.
When connected to -13volts , the converted o/p was 0x9740
Why the converted results are not proper and varying .

3 whether REFP should be connected to +10 volts ,when the ADC analog channel inputs are connected to +/-10 voltage inputs.

4. Whether AVdd and AGnd should be connected to +/-10 volts respectively , while analog channel inputs are working with
+/-10 volts.


  • Hi Atul,

    The TLC2578 is a lower bit version of the TLC3578.  A little sample code is attached which you can modify for the difference in resolution.

    8686.TLC3578.c
    /****************************************************************/
    /* FILENAME: main.c                            		        */
    /* DESCRIPTION: This program uses the MSP430F449 to read 500 	*/
    /*    samples from the TLC3578 EVM board.                       */
    /*    The samples are display on the LCD Screen of the HPA449.  */
    /*    Refer to the .map file created by the compiler for the    */
    /*    address in memory for adc_data                            */
    /*    AUTHOR: T. Hendrick, Data Acquisition Products,           */
    /*            Dallas Texas                                      */
    /*    CREATED 2004(C) BY TEXAS INSTRUMENTS INCORPORATED.  	*/
    /*    VERSION: 01 						*/
    /****************************************************************/
    #include <msp430x44x.h>
    #include <math.h>
    #include "SBLCDA2.h"
    
    #define Resonator (0)
    
    /***************************************************************/
    
    #define Samples 200
    #define UD_P1_C               (0xD1)
    #define UD_P2_H               (0x76)
    
    /**************** Function prototypes ***********************************/
    /*                                                                      */
    void init_sys(void);                /* MSP430 Initialisation routine    */
    void setupClock(int);
    void init_adc(void);                /* adc initialisation routine       */
    void delay(int);                   /* Software delay                   */
    void TX_complete(void);                /* Transmit / Receive ready         */
    void RX_complete(void);                /* Transmit / Receive ready         */
    void adc_convert(int);             /* Do the adc conversion            */
    void adc_convertCH1(int);             /* Do the adc conversion            */
    void display(void);                 /* Indicate Program complete        */
    void InitializeLCD( void );
    void clearDisplay( void );
    void clearMajor( void );
    void sortMajor( unsigned int );
    void sortFloat( double );
    void displaySpecial( long int );
    void displayMinor( int, int );
    void displayHPA449(void);
    void displayTest(int, int);	
    /*                                                                      */
    /************************************************************************/
    
    /************************************************************************/
    /*                                                                      */
    /* Global variable declarations                                         */
    /*                                                                      */
    /************************************************************************/
    
    int    adc_data[Samples];        // Storage for converted data
    int    adc_dataCH2[Samples];        // Storage for converted data
    int    byte0, byte1, byte2, byte3, trash;
    
    int i, j, min, max, CH = 0;
    double result, value;
    
    /************************************************************************/
    /*                                                                      */
    /* Local Functions                                         */
    /*                                                                      */
    /************************************************************************/
    double display_volts(int *codes, int ct)
    {
    	int i;
    	double sum=0, average=0;
    	for (i=0;i<ct;i+=10)
    	  sum += ((codes[i]*.001220703125)-10);
    	average = sum/(ct/10);
    	return average;
    }
    /************************************************************************/
    /*                                                                      */
    /* main() variable declarations                                         */
    /*                                                                      */
    /************************************************************************/
      #define   ADC_FS            0x20  //p3.5
      #define   ADC_CS            0x80  //p3.7
    
    void main(void)
    {
      setupClock(Resonator);
      init_sys();                   	// Initialise the MSP430
      init_adc();
      InitializeLCD();
      clearDisplay();
      displaySpecial(SoftBaugh);
    
          do {
    
             for(i=0; i<Samples; i++)
             {
              adc_convert(i);            // Do conversions from each channel
              delay(0);
              adc_convertCH1(i);            // Do conversions from each channel
              //displayTest(CH, i);
             }
             clearMajor();
             displaySpecial(SoftBaugh|AR);
             }
    
           while (1);              //
    }			      	
    
    /************************************************************/
    /* Prototype - init_sys                                     */
    /*                                                          */
    /*  Description                                             */
    /*  This prototype initialises the MSP430F149               */
    /************************************************************/
    void init_sys(void)
    {
        /* Local function prototype         */
    void setupports(void);  /* Local function prototype         */
    void setupSPI(void);    /* Local function prototype         */
    
    setupports();
    setupSPI();
      _EINT();                              // Enable interrupts
    }
    /************************************************************/
    /* Prototype - setupClock                                     */
    /*                                                          */
    /*  Description                                             */
    /*  This prototype sets-up the XT2 oscillator and tests     */
    /*  that it has settled before moving on                    */
    /************************************************************/
    void setupClock (int RES)
    {
        switch (RES)
        {
            case  0:
              { WDTCTL = WDTPW + WDTHOLD;
                /* D=2, N=121, no mod */
                SCFQCTL=121;
                // SCFI0 = 0100 0100
                SCFI0=0x44;
                // DCOPLUS=1, XTS_FLL=0
                // XCAPXPF=00
                FLL_CTL0=0x80;
                // SMCLK=0, XT2OFF=1, SELMX=00, SELS=0, FLL_DIVX=10
                // FLL_CTL1= 0010 0010
                FLL_CTL1=0x22;
              }
              break;
            case  1:
              { WDTCTL = WDTPW + WDTHOLD;           // Stop watchdog timer
                FLL_CTL0&=XT2OFF;                    // Switch on the XT2 osc.
                FLL_CTL1|=SELM_XT2+SELS;                // Select XT2 osc. for
                // Test the osc. flag bit
                do {
                    IFG1 &= ~OFIFG;            // Clear the OFIFG bit
                    } while (OFIFG&IFG1);      //
              }
              break;
        }
    }
    
    /************************************************************/
    /* Prototype - setupports                                   */
    /*  Description                                             */
    /*  This prototype sets-up the GPIO ports as appropriate    */
    /************************************************************/
    void setupports (void)
    {
    // SPI port for ADC
    P3SEL = BIT3 + BIT2 + BIT1;                     // Bits 3, 2 & 1 are assigned as SPI specific pins
    P3DIR = ADC_FS + ADC_CS;                           // Set the ADC_CS bit as an output
    P3OUT = ADC_FS + ADC_CS;                            // De-assert ADC_CS for the adc - HIGH
    
    //SetupInterrupts
    P1IFG |= 0x00;
    P1IES |= 0x40;
    P1IE |= 0x40;
    }
    
    /************************************************************/
    /* Prototype - setupSPI                                     */
    /*                                                          */
    /*  Description                                             */
    /*  This prototype sets-up the P3 for communication via SPI */
    /************************************************************/
    void setupSPI (void)
    
    /************************************************************/
    /* System definitions                                       */
    /************************************************************/
    #define     SPI0en       0x40
    #define     SPI1en       0x10
    
    {
    ME1 |= USPIE0;                      // Module Enable - SPI
                                        //
    U0CTL &= ~SWRST;                    // Make sure the RESET bit is off
    U0CTL |= CHAR + SYNC + MM;          // USART0 module operation
                                        // CHAR = 1 => 8-bit data
                                        // SYNC = 1 => SPI selected
                                        // MM = 1 => master mode,
                                        //     MSP is the master
    U0TCTL |= SSEL0 + SSEL1 + STC;      // USART0 Tranmit control register
                                        // SSEL0 = 1 & SSEL1 = 1
                                        // => SMCLK is used for baud-rate generation
                                        // STC = 1 => 3-pin SPI mode selected
    
    U0BR0  = 0x02;                      // Divide SMCLK by 4 => transfer clock
    U0BR1  = 0x00;                      //
    U0MCTL = 0x00;                      // Modulation control - not used. Ensure
                                        // all these bits are reset
    }
    
    /************************************************************/
    /* Prototype - init_adc                                     */
    /*                                                          */
    /*  Description                                             */
    /*  This prototype sets-up the TLV2553 ADC                  */
    /************************************************************/
    void init_adc (void)
    {
    P3OUT |= (ADC_FS);                             // Assert ADC_CS LOW
    P3OUT &= ~(ADC_CS);                       // Assert ADC_CS* LOW
    while ((IFG1 & UTXIFG0) == 0);
    trash = U0RXBUF;
    U0TXBUF = 0xA2;                     // Start SCLK to ADC
    
    while ((IFG1 & UTXIFG0) == 0);
    trash = U0RXBUF;
    U0TXBUF = 0x00;                     // Start SCLK to ADC
    
    while ((IFG1 & UTXIFG0) == 0);
    trash = U0RXBUF;
    U0TXBUF = 0x00;                     // Start SCLK to AD
    
    while ((IFG1 & UTXIFG0) == 0);
    trash = U0RXBUF;
    U0TXBUF = 0x00;                     // Start SCLK to AD
    delay(10);
    P3OUT |= (ADC_CS); 		    // De-assert ADC_CS* HIGH
    }
    
    /************************************************************/
    /* Prototype - delay                                        */
    /*  Description                                             */
    /*  This prototype gives a delay of around 1 second         */
    /************************************************************/
    void delay(int time)
          {
          unsigned int i;
          for (i = 0; i < time; i++);
          }
    
    /************************************************************/
    /* Prototype - convert                                      */
    /*  Description                                             */
    /*  This prototype does the adc conversion                  */
    /************************************************************/
    void adc_convert (int cnt)
    {
    P3OUT &= ~(ADC_CS);                             // Assert ADC_CS LOW
    while ((IFG1 & UTXIFG0) == 0);
          byte0 = U0RXBUF;		  // Store this data in the hi-byte variable.
          U0TXBUF = 0x00; //CH<<4;                     // Send clocks to the ADC, this shifts
    
    while ((IFG1 & UTXIFG0) == 0);
          byte1 = U0RXBUF;		  // Store this data in the hi-byte variable.
          U0TXBUF = 0x00;                     // Send clocks to the ADC, this shifts
    
    while ((IFG1 & UTXIFG0) == 0);
          byte2 = U0RXBUF;		  // Store this data in the hi-byte variable.
          U0TXBUF = 0x00;                     // Send clocks to the ADC, this shifts
    
    while ((IFG1 & UTXIFG0) == 0);
          byte3 = U0RXBUF;		  // Store this data in the hi-byte variable.
          U0TXBUF = 0x00;                     // Send clocks to the ADC, this shifts
    
    
    delay(10);                                          // sampling.
    //      RX_complete();
    P3OUT |= (ADC_CS);                              // De-assert ADC_CS HIGH
    
         adc_data[cnt] = ((byte2 << 8 | byte3 )>>2 & 0x3FFF);
    
    }
    
    void adc_convertCH1 (int cnt)
    {
    P3OUT &= ~(ADC_CS);                             // Assert ADC_CS LOW
    while ((IFG1 & UTXIFG0) == 0);
          byte0 = U0RXBUF;		  // Store this data in the hi-byte variable.
          U0TXBUF = 0x01; //CH<<4;                     // Send clocks to the ADC, this shifts
    
    while ((IFG1 & UTXIFG0) == 0);
          byte1 = U0RXBUF;		  // Store this data in the hi-byte variable.
          U0TXBUF = 0x00;                     // Send clocks to the ADC, this shifts
    
    while ((IFG1 & UTXIFG0) == 0);
          byte2 = U0RXBUF;		  // Store this data in the hi-byte variable.
          U0TXBUF = 0x00;                     // Send clocks to the ADC, this shifts
    
    while ((IFG1 & UTXIFG0) == 0);
          byte3 = U0RXBUF;		  // Store this data in the hi-byte variable.
          U0TXBUF = 0x00;                     // Send clocks to the ADC, this shifts
    
    delay(10);                                          // sampling.
    //      RX_complete();
    P3OUT |= (ADC_CS);                              // De-assert ADC_CS HIGH
    
         adc_dataCH2[cnt] = ((byte2 << 8 | byte3 )>>2 & 0x3FFF);
    
    
    }
    void displayTest(int channel, int cnt)
    {
        switch (channel)
        {
    
            case  0:
                 displayMinor(5,UD_P1_C);
                 displayMinor(4,UD_P2_H);
                 displayMinor(3,UR_ZERO);
                 displayMinor(2,UR_ZERO);
                 sortFloat(display_volts(adc_data,Samples));
                break;
            case  1:
                 displayMinor(5,UD_P1_C);
                 displayMinor(4,UD_P2_H);
                 displayMinor(3,UR_ZERO);
                 displayMinor(2,UR_ONE);
                 sortMajor(adc_data[cnt]);
                break;
            case  2:
                 displayMinor(5,UD_P1_C);
                 displayMinor(4,UD_P2_H);
                 displayMinor(3,UR_ZERO);
                 displayMinor(2,UR_TWO);
                 sortFloat(display_volts(adc_data,Samples));
                break;
            case  3:
                 displayMinor(5,UD_P1_C);
                 displayMinor(4,UD_P2_H);
                 displayMinor(3,UR_ZERO);
                 displayMinor(2,UR_THREE);
                 sortFloat(display_volts(adc_data,Samples));
                break;
            case  4:
                 displayMinor(5,UD_P1_C);
                 displayMinor(4,UD_P2_H);
                 displayMinor(3,UR_ZERO);
                 displayMinor(2,UR_FOUR);
                 sortMajor(adc_data[cnt]);
                break;
            case  5:
                 displayMinor(5,UD_P1_C);
                 displayMinor(4,UD_P2_H);
                 displayMinor(3,UR_ZERO);
                 displayMinor(2,UR_FIVE);
                 sortMajor(adc_data[cnt]);
                break;
            case  6:
                 displayMinor(5,UD_P1_C);
                 displayMinor(4,UD_P2_H);
                 displayMinor(3,UR_ZERO);
                 displayMinor(2,UR_SIX);
                 sortFloat(display_volts(adc_data,Samples));
                break;
            case  7:
                 displayMinor(5,UD_P1_C);
                 displayMinor(4,UD_P2_H);
                 displayMinor(3,UR_ZERO);
                 displayMinor(2,UR_SEVEN);
                 sortFloat(display_volts(adc_data,Samples));
                break;
         }
    
    }
    
    #pragma vector=PORT1_VECTOR
    __interrupt void CH_switch (void)
    {
      _DINT();
      clearMajor();
      P1IFG &= ~BIT6;
      CH = CH + 1;
      if (CH >= 8) CH = 0;
      delay(1000);
      _EINT();
    }
    

     

    There is not much of a difference between 0x9790, 0x97A0 and 0x9740, so without seeing a schematic and or timing of the communication, I'm not so sure I can redily help you explain why you see these conversion results.

    The VREFP is limited to 4.0V, please take a look at the datasheet, page 6.  For a +/-10V input range, the reference voltage should range between 3.96 and 4.04V.  The AGND is ground, it should not be taken negative and the positive rail cannot exceed 5.5V.  This is also mentioned in the datasheet on page four I believe.