View previous topic :: View next topic |
Author |
Message |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Dec 08, 2010 4:10 pm |
|
|
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
|
|
Posted: Thu Dec 09, 2010 9:24 am |
|
|
Thanks a lot PCM Programmer !
You're a genius and your explanations and examples are always amazing.
I understand much better now.
Thanks |
|
|
vever001
Joined: 15 May 2010 Posts: 21
|
|
Posted: Thu Dec 09, 2010 1:30 pm |
|
|
Just one more question:
Why are you using 64 for the divider of the adc clock ? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Dec 09, 2010 1:44 pm |
|
|
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
|
|
Posted: Thu Dec 09, 2010 5:42 pm |
|
|
Omg sorry I forgot you were using a 40Mhz ocillator
Sorry for the inconvenience
Anyway thanks a lot ! |
|
|
vever001
Joined: 15 May 2010 Posts: 21
|
|
Posted: Tue Dec 14, 2010 12:21 pm |
|
|
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 |
|
|
vever001
Joined: 15 May 2010 Posts: 21
|
|
Posted: Tue Dec 14, 2010 2:44 pm |
|
|
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
|
|
Posted: Tue Dec 14, 2010 3:48 pm |
|
|
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
|
|
Posted: Tue Dec 14, 2010 3:53 pm |
|
|
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
|
|
Posted: Tue Dec 14, 2010 4:38 pm |
|
|
Thanks a lot for your answers it really helps me
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
|
|
Posted: Tue Dec 14, 2010 7:54 pm |
|
|
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
|
|
Posted: Tue Dec 14, 2010 8:11 pm |
|
|
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. |
|
|
|