View previous topic :: View next topic |
Author |
Message |
Guest
|
problems with A/D interrupts |
Posted: Fri Dec 03, 2004 7:33 am |
|
|
I need to use A/D interrupt to measure a value of voltage from variable resistance to find its max or min while I'm doing another task.
But, my code may be wrong. I can only hear the song but PIC doesn't give a value of max and min to me.
I'm not sure about int_ad and ad_isr.
What I use in the code is correct ??
thank you
Code: |
#device ADC=10
boolean hook_ad=false;
void ad_isr();
#int_ad
void ad_isr()
{
hook_ad = true;
}
void main()
{
long duration;
int16 i, value, min, max, avg, rate;
enable_interrupts(GLOBAL);
enable_interrupts(INT_AD);
setup_port_a(ALL_ANALOG);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0); // PIN 2
min=1023;
max=0;
if(hook_ad)
{
value = Read_ADC();
printf(lcd_putc, "%ld", value);
delay_ms(500);
printf(lcd_putc, "\f");
if(value<min)
min=value;
if(value>max)
max=value;
hook_ad=false;
}
else
{
PlaySong(200);
}
}
|
|
|
![](templates/subSilver/images/spacer.gif) |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri Dec 03, 2004 7:50 am |
|
|
You have to tell the ADC to start a conversion. See the example in the manual for the read_adc command.
also: setup_port_a() is an obsolete function name, the new name is SETUP_ADC_PORTS |
|
![](templates/subSilver/images/spacer.gif) |
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Fri Dec 03, 2004 8:03 am |
|
|
You problem is that you PIC has went to bed The problem is not telling the adc to start. The default for ADC_READ() is ADC_START_AND_READ which you don't want.
Code: |
#device ADC=10
boolean hook_ad=false;
void ad_isr();
#int_ad
void ad_isr()
{
hook_ad = true;
}
void main()
{
long duration;
int16 i, value, min, max, avg, rate;
// Setup the port first
setup_port_a(ALL_ANALOG);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0); // PIN 2
enable_interrupts(INT_AD);
enable_interrupts(GLOBAL);
min=1023;
max=0;
// Start the initial conversion
Read_ADC(ADC_START_ONLY);
while(1)
{
if(hook_ad)
{
// Only read the value
value = Read_ADC(ADC_READ_ONLY);
printf(lcd_putc, "%ld", value);
delay_ms(500);
printf(lcd_putc, "\f");
if(value<min)
min=value;
if(value>max)
max=value;
hook_ad=false;
// Start the next conversion
Read_ADC(ADC_START_ONLY);
}
else
{
PlaySong(200);
}
}
}
|
|
|
![](templates/subSilver/images/spacer.gif) |
future
Joined: 14 May 2004 Posts: 330
|
|
![](templates/subSilver/images/spacer.gif) |
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Fri Dec 03, 2004 4:44 pm |
|
|
Am I missing something? That doesn't even use interrupts. |
|
![](templates/subSilver/images/spacer.gif) |
future
Joined: 14 May 2004 Posts: 330
|
|
Posted: Fri Dec 03, 2004 5:18 pm |
|
|
The way the previous code is structured, using an inline function will work the same way without using interrupts.
Using them, it will have to go through all the interrupt dispatcher (almost 100 instructions) just to set a flag and still handle the read in main().
I think it is much like the thread I commented.
He says "while doing another task", we know that this is not possible. So call the function twice with a delay between calls and its done.
Depending on the PIC clock he is using, probably hook_ad is always true and the read will be limited by the main loop speed... so use an inline function and get higher speeds without spending time in the dispatcher.
This is just my opinion and how I would solve this problem. |
|
![](templates/subSilver/images/spacer.gif) |
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Fri Dec 03, 2004 5:43 pm |
|
|
I see it as an exercise for using ints ![Wink](images/smiles/icon_wink.gif) |
|
![](templates/subSilver/images/spacer.gif) |
|