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
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: 19512

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
vever001



Joined: 15 May 2010
Posts: 21

View user's profile Send private message

PostPosted: Tue Dec 14, 2010 4:38 pm     Reply with quote

Thanks a lot for your answers it really helps me Wink

So I suppose I shouldn't use the adc_done interruption since it isn't as precise/accurate as a simple delay.

I have one more question:
Do I need to do something except changing the instruction #device adc=10 to #device adc=8 if I want to use the A/D module as a 8 bit converter ?

Thanks for your help
vever001



Joined: 15 May 2010
Posts: 21

View user's profile Send private message

PostPosted: Tue Dec 14, 2010 7:54 pm     Reply with quote

Are you sure it needs 30 + instructions to quit the instruction handler ?
Because I see the retfie instruction who seems to quit the instruction (handler ?).

Ttelmah wrote:

Tacq, _can_ be programmed into the chips on the latter PICs.


What do you mean by programming the Tacq ?
It is just a delay...I don't really understand and what's the advantage...
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Dec 14, 2010 8:11 pm     Reply with quote

Quote:
Are you sure it needs 30 + instructions to quit the instruction handler ?

See this thread which explains the CCS interrupt handler code:
http://www.ccsinfo.com/forum/viewtopic.php?t=29173

You can see the code for yourself by looking at the the .LST file.
Look at address 0004 for 16F PICs, or at address 0008 for 18F PICs.
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