![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
Hicham
Joined: 09 Feb 2010 Posts: 17
|
details about read_adc function |
Posted: Thu Feb 11, 2010 1:48 pm |
|
|
Hello,
I'm new to PIC-C, and I'm moving from assembly to C,
when i program AD conversion (pic 16F876) with assembly
i used to it in 2 steps
first : charging the capacitor with
bsf ADCON0,ADON
and waiting about 20us (for my settings)
second: after that I launch the conversion with
bsf ADCON0,GO
and the conversion will start
third: when the AD conversion end, I'll have an interrupt so I can read the converted result (ADRESH & ADRESL) and the ADON bit will go low
But in CCS, I can't figure out how this work in details.
Does "ADC_START_ONLY" do the same job as "bsf ADCON0,ADON" ?
I checked the help, but not much about it, so any help here ? |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
![](templates/subSilver/images/spacer.gif) |
Hicham
Joined: 09 Feb 2010 Posts: 17
|
|
Posted: Fri Feb 12, 2010 8:17 am |
|
|
Thanks,
Your code is very simple, I need to do other stuff while waiting the AD conversion. |
|
![](templates/subSilver/images/spacer.gif) |
languer
Joined: 09 Jan 2004 Posts: 144 Location: USA
|
|
Posted: Fri Feb 12, 2010 1:58 pm |
|
|
When I want to see what's behind the curtain I normally take a peek
So in this case if you look at the LST file:
Code: | ***CCS FULL READ***
.................... adcValue = read_adc();
0041: BSF 1F.2
0042: BTFSC 1F.2
0043: GOTO 042
0044: MOVF 1E,W
0045: CLRF 22
0046: MOVWF 21
***CCS START, THEN READ AFTERWARDS OPERATIONS***
.................... read_adc(ADC_START_ONLY);
0052: BSF 1F.2
.................... adcValue = read_adc(ADC_READ_ONLY);
005A: BTFSC 1F.2
005B: GOTO 05A
005C: MOVF 1E,W
005D: CLRF 22
005E: MOVWF 21
|
Now from the datasheet it says to "Wait for A/D conversion to complete, by either: (1) Polling for the GO/DONE bit to be cleared (with interrupts enabled); OR (2) Waiting for the A/D interrupt"
CCS code will poll the GO/DONE bite (option #1). But in your case you may want to use the interrupt option along with the ADC_START_ONLY option in the main loop, and the ADC_READ_ONLY option in the interrupt section.
Something like:
Code: | ........
int16 adcValue = 0;
........
#int_ad
adc_handler()
{
adcValue = read_adc(ADC_READ_ONLY);
}
........
main()
{
setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_DIV_32);
set_adc_channel(0);
delay_us(10);
while ( TRUE )
{
// start, and then read cycle
enable_interrupts(GLOBAL);
enable_interrupts(INT_AD);
read_adc(ADC_START_ONLY);
}
}
........ |
|
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Feb 12, 2010 2:02 pm |
|
|
Here is a revised program that shows how to start and then read the adc.
The two read_adc() operations shown below that do a Start and Read Only
are the equivalent of this line:
Code: |
adc_value = read_adc();
|
Code: |
#include <16F877.H>
#device adc=10
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock= 4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
//============================
void main()
{
int16 adc_value;
float volts;
setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_DIV_8);
set_adc_channel(0);
delay_us(20);
while(1)
{
read_adc(ADC_START_ONLY);
adc_value = read_adc(ADC_READ_ONLY);
volts = (float)(adc_value * 5)/1023.0;
printf( "%3.2f \n\r", volts);
delay_ms(500);
}
} |
|
|
![](templates/subSilver/images/spacer.gif) |
Hicham
Joined: 09 Feb 2010 Posts: 17
|
|
Posted: Sun Feb 14, 2010 11:59 am |
|
|
# languer
thanks man,its really helpful. and i like the LST trick.i'll use it
#PCM programmer
Thanks, but you can't do anything wile waiting for the AD conversion ??
check the previews post by languer. it has lots information.
thanks all for your help.i really appreciated |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah Guest
|
|
Posted: Sun Feb 14, 2010 3:46 pm |
|
|
Some comments:
A search in the forum, will find examples posted in the past, of using the separate commands inside a timer interrupt, so that on the first 'pass', you select the channel, then on the next, trigger the conversion to start, then read the value on the next. You can either use three states like this, or immediately select the next channel after reading.
Now, the ADC interrupt, is a bit of a 'hare'. The _only_ time the ADC interrupt is worth using, is if you are triggering the ADC, using the special event trigger of the CTC. Otherwise, it takes longer to get into, and out of an interrupt, than to simply wait for the ADC to complete....
If the ADC is setup to it's optimum clock, it only takes 24uSec to complete a conversion on the older chips, and on some of the newer chips less than half this. In general you can't do a lot in this sort of time, so separating the operations, only really makes sense when using a timer to control everything, and performing the actual readings in a timer based 'thread'.
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|