|
|
View previous topic :: View next topic |
Author |
Message |
plum33
Joined: 07 Apr 2006 Posts: 1
|
problem with ADC |
Posted: Fri Apr 07, 2006 1:46 am |
|
|
I have problem with this code:
Code: | #include "C:\Documents and Settings\t40\My Documents\ccs projekty\ammeter\ammeter18d.h"
long int adval;
#int_AD
AD_isr()
{
OUTPUT_HIGH(PIN_B5);
}
void main()
{
setup_adc_ports(AN0|VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL|ADC_TAD_MUL_0);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
enable_interrupts(INT_AD);
enable_interrupts(GLOBAL);
setup_low_volt_detect(FALSE);
setup_oscillator(OSC_8MHZ|OSC_TIMER1|OSC_31250|OSC_PLL_ON);
set_tris_b(0b00000000);
while (1)
{
set_adc_channel(0);
OUTPUT_HIGH(PIN_B7);
OUTPUT_LOW(PIN_B6);
delay_ms(500);
adval=Read_ADC();
OUTPUT_HIGH(PIN_B6);
OUTPUT_LOW(PIN_B7);
delay_ms(500);
}
}
|
the problem is that interrupt don't work and I doubt does adc conversion works at all.(i'm programming 18F4520 ) |
|
|
Ttelmah Guest
|
|
Posted: Fri Apr 07, 2006 2:35 am |
|
|
You are misunderstanding how the internal functions work, and trying to 'misuse' them...
Now first of all, there is little advantage at all, in using the ADC interrupt ability. An interrupt, takes a long time to service (typically requiring perhaps 20 to 30 instruction times to save the registers before calling the 'handler' routine, and then a similar number to restore the registers on return). The ADC, depending on the clock rate chosen, and the chip version involved, typically involves at worst about 10uSec to perform a conversion, so in most cases, it takes _longer_ to call an interrupt handler, than to sit and 'poll' the ADC. The only normal reason to use the ADC interrupt handler,is if the ADC is being triggered by a CTC event (using the special function mode of the CTC).
The internal 'read_adc' function, has a number of different operating modes, according to a 'flag' value passed to it. The _default_ mode (with no value passed), will trigger the ADC, and sit polling the ADIF bit, till the conversion completes. Now, if you enable an ADC interrupt handler, with the function operating in this mode, it will _hang_. The problem is, that when ADIF gets set, the interrupt handler is called, which automatically clears the interrupt flag. The routine then never sees the interrupt going true, and will then sit for ever, waiting for it to happen.
The simplest way to use the ADC, is to get rid of the interrupt handler, and disable the interrupt. The code will then work.
If you _must_ use the handler, then you need to trigger the ADC in a different way. Use 'read_adc(ADC_START_ONLY)'. This will trigger the ADC, and do nothing else. When the conversion is complete, the interrupt handler will be called, and in this, you should then read the ADC, with 'read_adc(ADC_READ_ONLY)'. However this will take many uSec longer to do, than using the default behaviour. Your main code will also need to wait for the handler to be called and the value returned, adding more complexity.
Best Wishes |
|
|
kender
Joined: 09 Aug 2004 Posts: 768 Location: Silicon Valley
|
Re: problem with ADC |
Posted: Fri Apr 07, 2006 2:46 am |
|
|
plum33 wrote: | the problem is that interrupt don't work... |
Ttelman has beat me by some 30 seconds with the answer to this question.
plum33 wrote: | and I doubt does adc conversion works at all.(i'm programming 18F4520 ) |
If your hardware is hooked up correctly, your code should do the A/D conversion just fine.
Code: |
delay_ms(500);
adval=Read_ADC();
printf("%lu \n\r", adval); // add this to make sure your A/D conversion actually happens
|
|
|
|
|
|
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
|