View previous topic :: View next topic |
Author |
Message |
homfray
Joined: 19 Nov 2003 Posts: 45 Location: Oxford
|
PCH: read_ADC() and General Timing Issues |
Posted: Thu Mar 25, 2004 4:50 am |
|
|
I am acquiring data using 5 AI's on the 18F452 and unsure about the timing and delays required.
Code: | set_adc_channel(0); |
Am I right in thinking that this bit of code makes a link between the specific input channel and the ADC and deselects all the others. After this command I then need a delay as it is after this point in the code that the Hold Capaciter starts to charge. After the capaciter settles it then varies proportional to the voltage on the input.
AM I CORRECT IN THINKING I NEED A DELAY AFTER SET_ADC_CHANNEL and that can be worked out by Amplifier settling time + Holding Capaciter Charging Time + Temperature Coefficient (for my example it is around 11us)
Code: | adcValue = Read_ADC(); |
At this point the it starts the successive approximation technique which takes ten cycles and once this is complete it then captures that value. Am I correct in thinking that inherent in the above line of code, it waits for the acquisition to take place and to be captured before moving to the next line of code(it must access the acqusition interupt of the chip I assume).
AM I CORRECT IN THINKING THAT THERE IS NO DELAY REQUIRED EITHER BEFORE OR AFTER THE READ_ADC COMMAND AS IT IS INHERENT IN THE COMMAND ITSELF
I suppose you really only need a delay after the set_adc_channel if you use the command read_adc in a time shorter than that delay taken for the holding capaciter to charge |
|
 |
Neutone
Joined: 08 Sep 2003 Posts: 839 Location: Houston
|
Re: PCH: read_ADC() and General Timing Issues |
Posted: Thu Mar 25, 2004 7:41 am |
|
|
homfray wrote: | I am acquiring data using 5 AI's on the 18F452 and unsure about the timing and delays required.
Code: | set_adc_channel(0); |
Am I right in thinking that this bit of code makes a link between the specific input channel and the ADC and deselects all the others. After this command I then need a delay as it is after this point in the code that the Hold Capaciter starts to charge. After the capaciter settles it then varies proportional to the voltage on the input.
AM I CORRECT IN THINKING I NEED A DELAY AFTER SET_ADC_CHANNEL and that can be worked out by Amplifier settling time + Holding Capaciter Charging Time + Temperature Coefficient (for my example it is around 11us)
Code: | adcValue = Read_ADC(); |
At this point the it starts the successive approximation technique which takes ten cycles and once this is complete it then captures that value. Am I correct in thinking that inherent in the above line of code, it waits for the acquisition to take place and to be captured before moving to the next line of code(it must access the acqusition interupt of the chip I assume).
AM I CORRECT IN THINKING THAT THERE IS NO DELAY REQUIRED EITHER BEFORE OR AFTER THE READ_ADC COMMAND AS IT IS INHERENT IN THE COMMAND ITSELF
I suppose you really only need a delay after the set_adc_channel if you use the command read_adc in a time shorter than that delay taken for the holding capaciter to charge |
I set the Go/Done bit, that starts and signals the completion of an ADC read, to time the setteling of a channel. A read takes 12 TAD and that is about 12uS for me. Set a bit that will clear 12uS later is an effective method to delay before reading that uses minimal code. It also allows interupts to occur without adding to the delay time. You could also read twice and throw out the first reading. If you have a really time critical app you can do filtering during the channel settel and conversion but this is more difficult to time. |
|
 |
homfray
Joined: 19 Nov 2003 Posts: 45 Location: Oxford
|
|
Posted: Thu Mar 25, 2004 8:33 am |
|
|
Have you got an example code of this, it may make things a little easier to see? Does that mean you do not use read_ADC? and is the delay after you set_adc_channel or after read_ADC?
Also if I want to set just one bit. I know for the 18F452 that I would have to set bit 2 on ADCON0
and
Code: | #byte ADCON0 = 0xFC2 |
in <asm> code I would just BSF ADCON0, 2 but unsure in C. |
|
 |
Chas Guest
|
|
Posted: Thu Mar 25, 2004 9:17 am |
|
|
Check out the help file for the read_adc() function. There are some new parameters that allow starting the ADC (read_acd(ADC_START_ONLY);) and not waiting for the complete ADC conversion, then later coming back and getting the result (my_data = read_adc(ADC_READ_ONLY);) It is up to you to make certain that you allow enough time for conversion. I have used this quite successfully in a project with an 8kHz loop time. I start the ADC for the first time in the initialization routine, then in the loop I read the ADC with the read_only parameter, then restart it with the start_only parameter. If there is a chance that you will try to read the result before the conversion is complete, you can monitor the Go/Done bit, then read the result. |
|
 |
Neutone
Joined: 08 Sep 2003 Posts: 839 Location: Houston
|
|
Posted: Thu Mar 25, 2004 9:42 am |
|
|
homfray wrote: | Have you got an example code of this, it may make things a little easier to see? Does that mean you do not use read_ADC? and is the delay after you set_adc_channel or after read_ADC?
Also if I want to set just one bit. I know for the 18F452 that I would have to set bit 2 on ADCON0
and
Code: | #byte ADCON0 = 0xFC2 |
in <asm> code I would just BSF ADCON0, 2 but unsure in C. |
Have a look at this. The registry stuff is so I can read all the information as a block using MODBUS routines.
http://home.houston.rr.com/neutone/analog.c |
|
 |
homfray
Joined: 19 Nov 2003 Posts: 45 Location: Oxford
|
|
Posted: Thu Mar 25, 2004 10:01 am |
|
|
you clever watsit, Neutone!!!! Thats exactly how you do it. It bloody easy when it written down by a smart fella  |
|
 |
|