CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Reading ADC through interrupt

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Guest








Reading ADC through interrupt
PostPosted: Wed Feb 22, 2006 11:01 am     Reply with quote

I'm trying to poll the adc through rtcc interrupts. I'm having trouble because it's not reading.

Code:

#define adc=8
int value;
 
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
set_rtcc(100); /* preset the value to get 100Hz
while (true)
{
  if (cADCflag == 1)
   {
      cADCflag=0;
   }
}

#INT_RTCC
void TIMER_INTERRUPT (void)
{
   set_rtcc(100);
   value=read_adc();
  cADCflag=1;
}


thanks
C Turner



Joined: 10 Nov 2003
Posts: 40
Location: Utah

View user's profile Send private message

Reading ADC through interrupt
PostPosted: Wed Feb 22, 2006 11:29 am     Reply with quote

I suspect that your code snippet is missing a lot of pieces - but just in case:

- I don't see where you set up the ADC in the first place - that is, inputs, Vref settings, A/D clock speed, etc.
- You never set your A/D channel to the one that you are going to use. You probably did that somewhere else - but just in case...
- I didn't see where you'd actually set up "RTCC" with the clock source, prescaler, etc. so I have no idea at which speed it's actually running.
- Will "set_rtcc(100)" *really* set the interrupt to 100 Hz? No: "RTCC" (a.k.a. "timer0) is just an 8-bit timer that counts up and rolls over, causing an interrupt. Presetting it to a value (like 100) only has an effect exactly one time: It does about 155 more counts, rolls over, causes and interrupt (if it's enabled, that is...) and then starts again at zero. If you want to have the RTCC ISR run at a different rate than 1/256th of the prescaled rate, you need to pre-set it inside the ISR, taking into account latency, etc. (I prefer to use Timer2 in these situations - when I have it - as it does all of this automagically...)

The above configs are pretty easy to do: There are lots of examples on this board - assuming, again, that your code snippet didn't include them.

The first thing that jumped out at me was that in your interrupt, you are actually stalling it, waiting for an A/D command, and the carrying on.

In the event that "rtcc" is actually running, it is entirely possible that it is zipping along at a high rate, generating an new interrupt before the A/D conversion ever completes.

Aside from all of that, a better way to do this would be to use the "ADC_READ_ONLY" constant to get "value" and *then* use the "ADC_START_ONLY" constant (but not saving a value anywhere) to begin a conversion: By the time the next ISR comes along (assuming that your ISR rate is slow enough and the A/D conversion cycle is fast enough) your result will be available - with no waiting!

CT
Ttelmah
Guest







PostPosted: Wed Feb 22, 2006 11:33 am     Reply with quote

The format to use 8bit ADC inputs, is #device adc=8, not a define.
You are not showing what your RTCC clock is set to.
You don't show the definition for cADCflag.
Setting the timer 'to' a value, probably won't work. The problem is that it takes time to get into an interrupt, and if the timer has already advanced, then your timing will be wrong.
What clock source is the ADC set to?.
What channel is it set to?.
How are the ADC inputs configured?.
If your clock rate is low, then your code may be spending all it's time in the interrupt handler, given the relatively long time needed for the ADC conversion.
I suspect one of these is the actual 'problem'.

Reading the ADC like this, will introduce a significant delay inside the timer interrupt code, which may give problems. Once you have found the setup problem, consider a different sequence:
Code:

#INT_RTCC
void TIMER_INTERRUPT (void)
{
   set_rtcc(100);
   value=read_adc(ADC_READ_ONLY);
   cADCflag=1;
   read_adc(ADC_START_ONLY);
}

With your code, the adc, is started, and then the system waits for it to take a reading, before proceeding. This code, reads the value from the last conversion, and then starts a new conversion, and does not wait.
As shown, it'll have the fault that the first reading will be garbage (start the adc, when you setup the timer etc., to avoid this). The conversion is done, while the processor is getting on doing other things.

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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