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

Can You help me about read_adc.

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



Joined: 09 Feb 2005
Posts: 48

View user's profile Send private message

Can You help me about read_adc.
PostPosted: Thu Feb 24, 2005 9:09 am     Reply with quote

I want to learn the difference of the using optional parameter of read_adc.

is there a any time difference the reading the analog value using

read_adc() or
read_adc(ADC_READ_ONLY )

and also how many time delay needed between two different channel reading?

set_adc_channel(0)
delay_us(40); // is it ok? or 1us ok?
x=read_adc();

set_adc_channel(1)
delay_us(40);
y=read_adc();


Could you help me about this topic
DragonPIC



Joined: 11 Nov 2003
Posts: 118

View user's profile Send private message

PostPosted: Thu Feb 24, 2005 11:04 am     Reply with quote

read_adc() is default to ADC_START_AND_READ. This reads and waits in the called function until a measurement is complete (is determined by the GO/~DONE bit of ADCON0 register.

read_adc(ADC_READ_ONLY ) will read what is in the ADRESH/L registers. This is usually used with read_adc(ADC_START_ONLY ) so can do other important things while waiting for the ADC to finish it's measurement.

10us delay is recommended in CCS manual. (Check the datasheet for the PIC you are using)
_________________
-Matt
Ttelmah
Guest







PostPosted: Fri Feb 25, 2005 4:26 am     Reply with quote

The 'point' about the time delay needed after changing channels, is that it depends on a whole lot of parameters. Inside the chip, the ADC input, is effectively a capacitor, which has to charge to the new voltage. There is a series resistor inside the chip. Both the value of the capacitor and resistor, change slightly with different chip versions. The '10uSec' figure, that comes in several of the data sheets, is the time needed to get within 0.5 bit, on the 10bit ADC, using the full accuracy of the ADC, with a voltage source that has changed from one limit of the ADC to the other, and has a source impedance below typically about 2.5K ohms.
Now (for instance), if you are prepared to accept only 8bit accuracy, you only need to charge for 1/4 this time. Also if your source impedance is lower than the recommended figure, the charge time will improve a little (though the internal resistance in the chip then becomes the limiting factor).
Now on the parameters, another user has given 'what' they mean, but let me give an example of how these could be used. Suppose you want to sample four ADC channels, and have each reading updating at 1000 times a second. The 'simple' approach, would be to have a timer interrupt occuring every 1000th second, and in the timer have something like:
Code:

    static int8 count=0; //must be static so 'count' is retained
    count = (count+1) % 4; //count through 0..3 and start again
    set_adc_channel(count);
    delay_us(10);   //wait for capacitor to charge
    adval[count]=read_adc();  //take the reading - time will depend on
                           //the clock rate chosen.

The problem' with this, is that you will be inside the interrupt for a relatively long time. The reeading itself, make take perhaps 16uSec, so the 'core' of the change channel and read code, is probably going to run to perhaps 30uSec or more. If the chip is doing a lot of other work (perhaps serial etc.), this may be undesirable. Also a slightly longer charge time might well be preferred.
The alternative, would be to have an interrupt at 4* the speed (every 250uSec), and code with something like:
Code:

    static int count=0,state=0;
    switch (state) {
    case 0:
               state=1;
               set_adc_channel(count);
               break;
    case 1:
               state=2;
               read_adc(ADC_START_ONLY);
               break;
    case 2:
               state=3;
               adval[count]=read_ADC(ADC_READ_ONLY);
               break;
    case 3:
               state=0;
               count=(count+1) % 4;
               break;
    }

Now the 'key' to this, is that each loop, only does a very little work. The instruction to set the adc_channel, only takes a couple of uSec. Similarly, the 'ADC_START_ONLY' instruction, only requires triggering a single bit in the processor, while the 'ADC_READ_ONLY', makes no attempt to test if the value is ready, but simply loads the two bytes from the ADC registers. Since the routine is called every 250uSec, the sequence is actually:
Time Action
0 select the channel
250 start the ADC
500 read the ADC
750 advance the channel number
1000 select the channel....

This allows 250uSec for the ADC to settle, then 250 for the reading etc. etc., without wasting time at each stage. :-)

Best Wishes
sraiderk



Joined: 09 Feb 2005
Posts: 48

View user's profile Send private message

PostPosted: Fri Feb 25, 2005 5:06 am     Reply with quote

Thank you very much all person giving responce to my request.

The example sended by Ttelmah is perfect to me for understanding the ADC.
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