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

Analysis of the ADC converter of the 18F458
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
vever001



Joined: 15 May 2010
Posts: 21

View user's profile Send private message

Analysis of the ADC converter of the 18F458
PostPosted: Wed Dec 08, 2010 12:15 pm     Reply with quote

Hello all,

I need to test the ADC of a 18F458.
So I will put an analog signal on the AN0 pin, then the ADC will convert it, and then I use a MCP4921 or so to get an analog signal.
So I can compare the original analog signal and the result (the output of the MCP4921) to see what happens when I increase the frequency.

But I have a problem to understand the read_adc() function...
So the function start the conversion, wait the conversion to finish (so I don't have to put a delay between 2 conversions ?) and store the value in a variable.

But then the conversion time will fluctuate...right?
So what do I need to do if I want a stable sampling rate ?
I saw the ADC_START_ONLY and ADC_READ_ONLY parameters...Can I use this ?

Thanks a lot for your help Wink
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Dec 08, 2010 12:34 pm     Reply with quote

Quote:
But then the conversion time will fluctuate...right?


The 18F458 data sheet says:
Quote:

The A/D conversion time per bit is defined as TAD. The
A/D conversion requires 12 TAD per 10-bit conversion.

3. Wait the required acquisition time.
4. Start conversion:
• Set GO/DONE bit (ADCON0)
5. Wait for A/D conversion to complete, by either:
• Polling for the GO/DONE bit to be cleared
OR
• Waiting for the A/D interrupt

I don't see any time period that fluctuates.

The following diagram in the 18F458 data sheet shows the A/D timing.
I don't see any variable latency time period in it:
Quote:
FIGURE 27-23: A/D CONVERSION TIMING
vever001



Joined: 15 May 2010
Posts: 21

View user's profile Send private message

PostPosted: Wed Dec 08, 2010 1:21 pm     Reply with quote

ok. Sorry I thought the read_adc() function was waiting until the conversion is finished (so the time of 2 conversion woudn't be the same as it is a successive approximation ADC) but in fact it always waits 12 Tad. Right ?

So I need to do like this :


Code:
setup_adc_ports(AN0);
set_adc_channel(0);
setup_adc(ADC_CLOCK_DIV_32);

while(1)
{
 delay_us(20);         //wait for the acquisition time
 value=read_adc();
 delay_us(4);          //A minimum wait of 2 TAD(=1,6µs) is
                             //required before next acquisition starts.
}


Is it correct ?

Thanks a lot Wink
vever001



Joined: 15 May 2010
Posts: 21

View user's profile Send private message

PostPosted: Wed Dec 08, 2010 2:15 pm     Reply with quote

Also I would like to see, if it's possible, the assembly code for the read_adc() function.
I searched in the folders of PICC but without success...

Thanks Wink
gpsmikey



Joined: 16 Nov 2010
Posts: 588
Location: Kirkland, WA

View user's profile Send private message

PostPosted: Wed Dec 08, 2010 2:39 pm     Reply with quote

There may be a better way, but you can compile a code sample with the read_adc() function in it then view the .lst file generated by the compiler to see what it was generating for that function (at least that is the way I have done it in the past).

mikey
_________________
mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Wed Dec 08, 2010 4:07 pm     Reply with quote

A 'successive approximation' ADC, still has to handle all ten bits. You start with the high bit. Is the signal above or below half range. then halve the half range, and so on. Ten bits takes ten clocks, whatever the value of the signal. The 12 clocks includes the first that disconnects the capacitor from the input signal, and the last that reconnects this, and latches the result. There is not a 'have I got there already' test to abort the scan if the value is already 'right' earlier in the cycle.

Best Wishes
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Dec 08, 2010 4:10 pm     Reply with quote

Read Robert Scott's (CCS forum member) explanation of Acquisition Time
here:
http://www.microchip.com/forums/tm.aspx?m=201318

I made a test program (shown below) to test the effect of changing
the acquisition time. This program reads 10 consequtive A/D samples
and stores them in an array. When that's done, it displays the samples.
I run the PIC at 40 MHz to keep the loop overhead time as low as possible
so it doesn't add very much to the acquisition time by itself. I have a
delay_us() statement to do the acquisition time.

To provide the input voltage to the A/D, I connect pin B0 to pin A1 (AN1)
with a jumper wire. I don't use pin A0 for analog input because my
PicDem2-Plus board has a trimpot on that pin. So I use pin A1 instead.
I then toggle pin B0 after each A/D reading is taken. So basically, the
input capacitor inside the A/D must charge or discharge fully each time
a new A/D reading is taken. This allows me to test the extreme case of
a large scale change in the A/D input voltage for each reading. Probably
a real A/D example would have a more slowly changing input voltage.

Also, the output impedance of pin B0 must be considered to be very low
compared to a more "normal" (unbuffered) A/D input signal source.

The results are:

For no A/D acquisition time (except the loop overhead):
Quote:

0
451
0
451
0
451
0
451
0
451


For 1us acquisition time:
Quote:

0
564
0
563
0
564
0
564
0
564


5us acquisition time:
Quote:

0
1005
0
1005
0
1005
0
1005
0
1005


6us acquisition time. Note that we are now getting full-scale readings.
Based on the forumula in the 18F452 data sheet, it should take 7.3us
to do this (assuming Pin B0 has 0 output impedance). The loop overhead
basically accounts for the 1.3us difference.
Quote:

0
1023
0
1023
0
1023
0
1023
0
1023



Here is the test program:
Code:

#include <18F452.h>
#device adc=10
#fuses H4,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=40000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

#define SAMPLES 10
//======================================
void main(void)
{
int8 i;
int16 results[SAMPLES];

setup_adc_ports(AN0_AN1_AN3);
setup_adc(ADC_CLOCK_DIV_64);
set_adc_channel(1);

output_low(PIN_B0);

// Take several consecutive A/D readings.
// Store them in an array.
for(i = 0; i < SAMPLES; i++)
   {
    delay_us(1);   // Set acquisition time delay here
    results[i] = read_adc();
    output_toggle(PIN_B0);
   }

// Now display the results.
for(i = 0; i < SAMPLES; i++)
   {
    printf("%lu \n\r", results[i]);
   }

printf("\n\r");

while(1);
}
vever001



Joined: 15 May 2010
Posts: 21

View user's profile Send private message

PostPosted: Thu Dec 09, 2010 9:24 am     Reply with quote

Thanks a lot PCM Programmer !

You're a genius and your explanations and examples are always amazing.

I understand much better now.

Thanks Wink
vever001



Joined: 15 May 2010
Posts: 21

View user's profile Send private message

PostPosted: Thu Dec 09, 2010 1:30 pm     Reply with quote

Just one more question:

Why are you using 64 for the divider of the adc clock ?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Dec 09, 2010 1:44 pm     Reply with quote

It's right out of the PIC data sheet. For 40 MHz operation, use div by 64.
Code:
TABLE 17-1: TAD vs. DEVICE OPERATING FREQUENCIES

AD Clock Source (TAD)   Maximum Device Frequency
Operation  ADCS2:ADCS0  PIC18FXX2   PIC18LFXX2
 2 TOSC    000           1.25 MHz    666 kHz
 4 TOSC    100           2.50 MHz    1.33 MHz
 8 TOSC    001           5.00 MHz    2.67 MHz
16 TOSC    101          10.00 MHz    5.33 MHz
32 TOSC    010          20.00 MHz   10.67 MHz
64 TOSC    110          40.00 MHz   21.33 MHz
RC         011             -           -
vever001



Joined: 15 May 2010
Posts: 21

View user's profile Send private message

PostPosted: Thu Dec 09, 2010 5:42 pm     Reply with quote

Omg sorry I forgot you were using a 40Mhz ocillator

Sorry for the inconvenience Rolling Eyes

Anyway thanks a lot !
vever001



Joined: 15 May 2010
Posts: 21

View user's profile Send private message

PostPosted: Tue Dec 14, 2010 12:21 pm     Reply with quote

Hi,

I read the assembler code in the lst file and I have this:

Code:
....................     valeur_adc=read_adc();     
0182:  BSF    FC2.2
0184:  BTFSC  FC2.2
0186:  BRA    0184
0188:  MOVFF  FC3,05
018C:  MOVFF  FC4,06


So there are no delays in this function except the time for the conversion (12*Tad) right ?
Someone told me the read_adc function have already the acquisition time but I suppose he was mistaken ? But apparently his conversion works...that's strange...how is it possible ?

Also the datasheet of the 18F458 says that there has to be a delay of 2*Tad before the next acquisition...but I don't see it in your code. Is this delay really necessary ?

Thanks a lot Wink
vever001



Joined: 15 May 2010
Posts: 21

View user's profile Send private message

PostPosted: Tue Dec 14, 2010 2:44 pm     Reply with quote

Sorry I forgot to say that he's using the adc_done interruption...

But this doesn't change anything I think...He doesn't have the acquisition delay.

But apparently the conversion is correct till 13KHz...?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Dec 14, 2010 3:48 pm     Reply with quote

According to the data sheet, the 2ad wait time is necessary. But it doesn't
have to be in two separate delay_us() statements. It can all be summed
up together in one delay statement.
Ttelmah



Joined: 11 Mar 2010
Posts: 19513

View user's profile Send private message

PostPosted: Tue Dec 14, 2010 3:53 pm     Reply with quote

If you use the ADC interrupt, you will get enough delay 'by accident'....
Since it takes some 30+ instruction times to get into the int handler, and this will only happen when the actual conversion has completed, and the capacitor is re-connected to the outside world, then another 30+ instructions to get out of the handler, you will probably get the time needed at all but the fastest clock rates.
Tacq, _can_ be programmed into the chips on the latter PICs.

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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