CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

ADC-MCP342x

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
kmp84



Joined: 02 Feb 2010
Posts: 354

View user's profile Send private message

ADC-MCP342x
PostPosted: Fri Apr 03, 2015 3:09 am     Reply with quote

Hello !

I have used "CCS MCP432x.c" ADC driver and I have the following problem:
In the code of driver have the following section
Code:

     do
     {
       status = i2c_read(MCP342X_STREAM, 1);  //read Status
     } while(bit_test(status, 7)); //until RDY = 0

Which significantly slows down the cycle of my program.
I tried to replace "while(..)" with other operator but it is not refreshing ADC value.
How can I solve this problem?

Thanks for attention!
Ttelmah



Joined: 11 Mar 2010
Posts: 19546

View user's profile Send private message

PostPosted: Fri Apr 03, 2015 3:35 am     Reply with quote

Do something else while you are waiting....

You have to wait.
It is waiting for the chip to signal back that it has completed.

What you can do though, is do another job inside the loop, provided it has nothing to do with the ADC, to 'use the time', till the ADC signals it is ready.
kmp84



Joined: 02 Feb 2010
Posts: 354

View user's profile Send private message

PostPosted: Fri Apr 03, 2015 3:57 am     Reply with quote

It is not a good idea, because it is another compilation unit included in main project.
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Fri Apr 03, 2015 7:44 am     Reply with quote

Mr. T gave you good advice. \

you don't say which precise part you are using , but
If there is a sequential time dependent aspect to your program
you have no choice but to make it a part of main() .

or pick another part that offers the resolution you need
AND is faster than a slow poke delta-sigma design of this low end converter family.
kmp84



Joined: 02 Feb 2010
Posts: 354

View user's profile Send private message

PostPosted: Fri Apr 03, 2015 8:10 am     Reply with quote

asmboy wrote:
Mr. T gave you good advice. \

you don't say which precise part you are using , but
If there is a sequential time dependent aspect to your program
you have no choice but to make it a part of main() .

or pick another part that offers the resolution you need
AND is faster than a slow poke delta-sigma design of this low end converter family.

I use ccs mcp342x.C driver (In my case MCP3428-4ch,16 bit ADC) and modbus_example_slave.
The delay while wating adc is about half socond.
Ttelmah



Joined: 11 Mar 2010
Posts: 19546

View user's profile Send private message

PostPosted: Fri Apr 03, 2015 9:08 am     Reply with quote

If the ADC needs you to wait, then you have several choices:

1) Rethink your code approach as already outlined.
2) Use a faster ADC.
3) Buffer the ADC. Add a tiny little PIC to just handle the ADC, and let this do the waiting.

1 is the easiest, you just need to change the way your code is modularized, and have the call to test available from the main, start the ADC, and then in your main do other jobs, occasionally calling the test.
houssam313



Joined: 02 May 2015
Posts: 1

View user's profile Send private message

PostPosted: Sat May 02, 2015 4:01 pm     Reply with quote

Hi,
It is better to use state machine technique in the library :
Code:

signed int32 read_adc_mcp(unsigned int8 address=MCP342X_ADDRESS)
{
  switch (ADC_State)
   {
    ///////////////////////////////////////////////////////////////////////////   
    case 0:
           #if MCP342X_MODE == MCP342X_ONE_SHOT
            i2c_start(MCP342X_STREAM);  //send I2C start
            i2c_write(MCP342X_STREAM, MCP342X_DEVICE_CODE | (address << 1));  //send write command
            i2c_write(MCP342X_STREAM, MCP342X_START_CONVERSTION | MCP342X_MODE | MCP342X_BITS | MCP342X_GAIN);  //initiate conversion
            i2c_stop(MCP342X_STREAM);  //send I2C stop
           #endif
           ADC_State = 1;
           return ADC_SENTINEL_VALUE;
           break;
    ///////////////////////////////////////////////////////////////////////////   
    case 1:
            i2c_start(MCP342X_STREAM);  //send I2C start
            i2c_write(MCP342X_STREAM, MCP342X_DEVICE_CODE | (address << 1) | 1);  //send read command
         
           #if MCP342X_BITS == MCP342X_18BITS
            result.b[2] = i2c_read(MCP342X_STREAM, 1);  //read MSB 18 Bit mode
           #endif
            result.b[1] = i2c_read(MCP342X_STREAM, 1);  //read 2nd MSB 18 Bit mode, read MSB 16, 14 or 12 Bit mode
            result.b[0] = i2c_read(MCP342X_STREAM, 1);  //read LSB
           
           status = i2c_read(MCP342X_STREAM, 1);       //read Status
           if(bit_test(status,7))  //if RDY = 1, New conversion not ready
            ADC_State = 2;
           else
            ADC_State = 3;
           return ADC_SENTINEL_VALUE;
           break;
    ///////////////////////////////////////////////////////////////////////////   
    case 2:
             status = i2c_read(MCP342X_STREAM, 1);  //read Status
           if(bit_test(status, 7)) //until RDY = 0
             return ADC_SENTINEL_VALUE;
           
           status = i2c_read(MCP342X_STREAM, 0);  //read Status, do nack
           i2c_stop();  //send I2C stop
     
           i2c_start(MCP342X_STREAM);  //send I2C start
           i2c_write(MCP342X_STREAM, MCP342X_DEVICE_CODE | (address << 1) | 1);  //send read command
     
          #if MCP342X_BITS == MCP342X_18BITS
           result.b[2] = i2c_read(MCP342X_STREAM, 1);  //read MSB 18 Bit mode
          #endif
           result.b[1] = i2c_read(MCP342X_STREAM, 1);  //read 2nd MSB 18 Bit mode, read MSB 16, 14 or 12 Bit mode
           result.b[0] = i2c_read(MCP342X_STREAM, 1);  //read LSB
           
            ADC_State = 3;
           return ADC_SENTINEL_VALUE;
           break;
    ///////////////////////////////////////////////////////////////////////////       
    case 3:
            status = i2c_read(MCP342X_STREAM, 0);  //read Status, do nack
            i2c_stop();  //send I2C stop
           
           #if MCP342X_BITS == MCP342X_18BITS
            if(bit_test(result.b[2],1))  //if 18 Bit mode check sign bit
              result.b[3] = 0xFF;
            else
              result.b[3] = 0;
           #endif
           
            ADC_State = 0;
           #if MCP342X_BITS == MCP342X_18BITS
            return(result.sint32);
           #else
            return(result.sint16);
           #endif
          break;
    ///////////////////////////////////////////////////////////////////////////   
    default:
           break;
   }

also define the ADC_SENTINAL_VALUE as
Code:


#define ADC_SENTINEL_VALUE 0xFFFFFFFE

And to use it in main loop
Code:

 while(true)
   {
   ad1 = read_adc_mcp();
   if(ad1 != ADC_SENTINEL_VALUE)
      printf("val=%lu\r\n",ad1);
      output_low(LED);
    //  delay_ms(DELAY);
      output_high(LED);
    //  delay_ms(DELAY);
   }

I Wish I help u Smile
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group