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.

What Changes i have to do in my source code for reading each channel separately

Problems occurring during ADC10 reading :-

 

Below is my sample code, through which I am reading voltages on four ADC channels, but in all cases I am getting the same voltage levels on all channels, that is one channel reading on the other channels.

 

Initiation :

ADC10CTL1 = SHS_0 + CONSEQ_1;

ADC10CTL0 = SREF_0 + ADC10SHT_0 + REFON + ADC10ON + ENC ;

ADC10DTC1=0x01;

 

conversion Code:

 

int Adc_Conv( int channel ) {

 

ADC10CTL1 = channel;

ADC10CTL0 |= ENC + ADC10SC;

while( ADC10CTL1 & ADC10BUSY );

ADC10CTL0 &= ~ENC;

return ADC10MEM;

}

 

If I read from the ADC Channels:

 

Temp1= Adc_Conv( 0x0400 );

Temp2= Adc_Conv( 0x1400 );

Temp3= Adc_Conv( 0x2400 );

Temp4= Adc_Conv( 0x3400 );

 

 

On all channels I am getting the first ADC Channel Reading , where I have to make change in order to read each channel separately.

  • You should poll for the ADC10 IFG instead of the BUSY bit:

      while (!(ADC10IFG & ADC10CTL0));          // First conversion?
      FirstADCVal = ADC10MEM;                   // Read out 1st ADC value

    See the ADC10 codes (the above snippet is from ADC10_03) from this zip file

  • Thanks for  your valuable suggestion, I tried it by simply replacing   

    while( ADC10CTL1 & ADC10BUSY ); with

    while (!(ADC10IFG & ADC10CTL0)); 

    with ADC10IE enabled ,

    but during debugging it is not going to satify this condition while (!(ADC10IFG & ADC10CTL0)); 

    the cursor is always on while (!(ADC10IFG & ADC10CTL0)); statement , so please suggest how to i proceed?

    Thanks in Advance.

    Regards

    Boni

  • Below is my sample code, through which I am reading voltages on four ADC channels, but in all cases I am getting the same voltage levels on all channels, that is one channel reading on the other channels.

     

    Initiation :

    ADC10CTL1 = SHS_0 + CONSEQ_1;

    ADC10CTL0 = SREF_0 + ADC10SHT_0 + REFON + ADC10ON + ENC ;

     

     

    conversion Code:

     

    int Adc_Conv( int channel ) {

     

    ADC10CTL1 = channel;

    ADC10CTL0 |= ENC + ADC10SC;

    while( ADC10CTL1 & ADC10BUSY );

    ADC10CTL0 &= ~ENC;

    return ADC10MEM;

    }

     

    If I read from the ADC Channels:

     

    Temp1= Adc_Conv( 0x0401 );

    Temp2= Adc_Conv( 0x1401 );

    Temp3= Adc_Conv( 0x2401 );

    Temp4= Adc_Conv( 0x3401 );

     

    for the above code afer the  first conversion, the ADC is not reading the other channels, it is simply sending the previous ADCMEM value, what changes i have to do for reading the other channels , please if any one can help me out how can i read the other channels.. 

     

    Thanks in advance

    Regards

    Boni

  • Hi,

    your ADC10 initialization is wrong!  Pls note, if you want to change ADC10 control bits ENC MUST be LOW (0) (refer to Users Manual page 20-4, par. 20.2.1)!

     

    1.)ADC10CTL1 = SHS_0 + CONSEQ_1;

    You want to have a function and pass the channel which you want to convert as argument, so you sample only one channel and not a sequence of channels

    --> change to:  ADC10CTL1 = INCH0 + CONSEQ_0; // channnel A0 is selected; single channel, single conversion; can be omitted!

     

    2.)ADC10CTL0 = SREF_0 + ADC10SHT_0 + REFON + ADC10ON + ENC ;

    --> change to: ADC10CTL0 = SREF_0 + ADC10SHT_0 +  ADC10ON;

     

    3.) Be shure to set ADC10AE0 correctly 

    (i.e. ADC10AE0 |= 0x0f;                         // P2.3,2,1,0 ADC10 option select)

     

    4.) Maybe you would like to change your routine as follows:

     

    int Adc_Conv( char channel ) 

    {

    ADC10CTL0 &= ~ENC; // ADC10 disable

    while (ADC10CTL1 & BUSY);               // Wait if ADC10 core is active 

     

    switch (channel)

    {

    case 0:

    ADC10CTL1 = INCH0 + CONSEQ_0; // channnel A0 is selected; single channel, single conversion

    break;

     

    case 1:

    ADC10CTL1 = INCH1 + CONSEQ_0; // channnel A1 is selected; single channel, single conversion

    break;

     

    case 2:

    ADC10CTL1 = INCH2 + CONSEQ_0; // channnel A2 is selected; single channel, single conversion

    break;

     

    case 3:

    ADC10CTL1 = INCH3 + CONSEQ_0; // channnel A3 is selected; single channel, single conversion

    break;

     

    default: // wrong channel info passed to function

    ADC10CTL1 = INCH0 + CONSEQ_0; // channnel A0 is selected; single channel, single conversion

    break;

    }

     

    ADC10CTL0 |= ENC + ADC10SC; // sampling and conversion start

    while( ADC10CTL1 & ADC10BUSY ); // wait for conversion to be finished

    ADC10CTL0 &= ~ENC; // ADC10 disable

    return ADC10MEM;

    }

    Refer to the Users Manual for details on ADC10 setup.

    I hope this helps, rgds
    aBUGSworstnightmare

  • Thanks for your suggestion, with this i made simple changes in my code now it works fine,

     

    int  Adc_Conv( int channel ) {
           
           
           
            ADC10CTL1 = channel;
           
            ADC10CTL0 = SREF_0 + ADC10SHT_0 + REFON + ADC10ON ;
           
            ADC10CTL0 |= ENC + ADC10SC ;
           
            ADC10CTL0 &= ~ENC;
           
            ADC10CTL0 &= ~(REFON + ADC10ON);
           
            return ADC10MEM;                   
                               }

     

    but here first three channels are reading fine but the rest (among A0-A7, A0-A2 are working fine) are on floating..continuosly how can i reduce that floating..

    Using sample code msp430x22x4_adc10_10.c  is it possible to read 8 channels i.e (A0-A7) continuosly ? i tried it , as per User's guide suggestions  but it is not working properly

  • Hi Manohar,

    pls refer to Users Manual (slau144e.pdf) page 20-22, par. 20.2.9 GROUNDING AND NOISE CONSIDERATIONS, and be shure to check your ADC10AE0 settings (ADC10AE0 = 0xff; when you use A0 to A7).

    If you need to sample your AD channnels continiously then using the DTC would be ta good solution. The DTC sample  msp430x22x4_adc10_10.c  works fine, but there is one thing to observe: it is the lokation of the data buffer (in the example it starts at 0x200). The problem here is, that the rest of your application is not aware of a buffer in RAM (since the example does nothing than sampling the AD channels this is no problem here).

    Maybe you should think abut defining a location in RAM which you only use as data buffer for your ADC. Here's how you can do it:

    1.) Open the linker command file and search for 

    /****************************************************************************/
    /* SPECIFY THE SYSTEM MEMORY MAP                                            */
    /****************************************************************************/

    MEMORY
    {
        SFR                     : origin = 0x0000, length = 0x0010
        PERIPHERALS_8BIT        : origin = 0x0010, length = 0x00F0
        PERIPHERALS_16BIT       : origin = 0x0100, length = 0x0100
        RAM                     : origin = 0x0200, length = 0x0400

    ...

     

    2.) change this i.e. as follows:

        ADCSAMPLE : origin = 0x0200, length = 0x0014 /* add this line, EXAMPLE ONLY */
        RAM                     : origin = 0x0214, length = 0x03E8 /* change according to space reserved for ADCSAMPLE */

    Now, your RAM (for application) will start at address 0x0214 and 0x0014 bytes (20 bytes) were reserved for your ADC samples. So, this works fine with 'ADC10SA = 0x200; // Data buffer start' from the example).

     

    3.) search the linker command file for:

    /****************************************************************************/
    /* SPECIFY THE SECTIONS ALLOCATION INTO MEMORY                              */
    /****************************************************************************/

    SECTIONS
    {
        .bss       : {} > RAM                /* GLOBAL & STATIC VARS              */
        .sysmem    : {} > RAM                /* DYNAMIC MEMORY ALLOCATION AREA    */
        .stack     : {} > RAM (HIGH)         /* SOFTWARE SYSTEM STACK             */
       /* ADD THE NEXT LINE HERE */
        .adcsample : {} > ADCSAMPLE /* RESERVED FOR ADC SAMPLES    */ 

    THE REST OF THE LINKER COMMAND FILE REMAINS UNCHANGED!!!

     

    4.) You need to define your array for the ADC results and let the linker know were to place it. Here's how to do it (add to your application or i.e to msp430x22x4_adc10_10.c for testing) :

    /*-----------------------------------------------------------------------------
    //   global variables stored in a seperate segment in RAM (ADCSAMPLE)
    //   contains the results of the ADC conversion  (ADRESULTS) 
    //---------------------------------------------------------------------------*/
    #pragma DATA_SECTION (ADRESULTS, ".adcsample");
    #pragma DATA_ALIGN (ADRESULTS, 2);
    unsigned int ADRESULTS[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

    Refer to slau131c.pdf for details on the above!!

    You can now access your ADC samples by

    ADRESULTS[0] --> contains result for A0
    to
    ADRESULTS[7] --> contains result for A7

    ADRESULTS[8] and ADRESULTS[9] are spare in this example. 

    Rgds
    aBUGSworstnightmare

  • Hi,

    Made the suggested changes. But still the channels read  wrong.

    P2.4/TA 2/A4/VREF+/VeREF+/OA1I0

    P2.3/TA 1/A3/VREF−/VeREF−/OA1I1/OA1O

    Configured the above pins as ADCs. But, the ADC channels doesnt read the correct voltage values applied at those particular pins. Getting correct values for other pins though.Please suggest any further changes in configuring ADCs.

    Thanks,

    Manohar.

  • 1) Hi, your question is straight forward ...

       In CTL1 = Include the Channel number using INCH_0,_1, & So on or use the Bit wise operator to find the number of Channels to get the ADC10 Value.

    2)  Simply disable the data which is predefined in Examples or in data sheet to terminate the previous data as follows:

        ADC10CTL0  &= ~ADC10ENC | ADC10IFG;

       include after every adc sample conversions.

**Attention** This is a public forum