Forum Menu




 


Log in Problems?
New User? Sign Up!
AVR Freaks Forum Index

Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Author Message
craignied
PostPosted: Aug 14, 2012 - 02:05 PM
Newbie


Joined: Apr 27, 2012
Posts: 19


I was wondering if somebody could shed some light on a problem that I'm having: I'd like to sample with the ADC in an xmega32a4u with one frequency, and report the results with another. But I'd also like to average a window of ADC measurements. This code does not work:

Code:

... defines, includes, etc.

// Globals
volatile int ADCvalue;   // record ADC result
int window[ WINDOW_SIZE ];   // the smoothing window

int main( void )
{
... set ups

   // Set up and configure PORTE Timer/Counter
   TCE0.CTRLA = TC_CLKSEL_DIV64_gc;      // divide clock by 64 = 500 kHz
   TCE0.PER = 12500;                  // set clock period to 12500 ( 32 MHz / ( 2 * 64 * 12500 ) = approx 20 Hz for 2 frames )
   TCE0.INTCTRLA = TC_OVFINTLVL_LO_gc;      // set low level interrupt on overflow
   TCE0.CNT = 0;                     // zero clock

   PMIC.CTRL = PMIC_LOLVLEN_bm;   // enable low level interrupts
   sei();                     // enable interrupts

   while( 1 )
   {   
      ADCA.CH0.CTRL |= ADC_CH_START_bm;   // start conversion on channel 0
      while( !( ADCA.CH0.CTRL & ADC_CH_START_bm ) );   // wait until it completes
      ADCvalue = ADCA.CH0RES;
      
      // Simulate a stack reverse push for reading the ADC value into the window
      for ( uint8_t i = 0; i < WINDOW_SIZE - 1; i++ )
         window[ i ] = window[ i + 1 ];
      window[ WINDOW_SIZE - 1 ] = ADCvalue;
      
      ...
         
      _delay_ms( DELAY_TIME );      
   };

   return 0;
};

// LCD controller routine
void LCD_update( void )
{
... display code
}

// Interrupt routine to display on LCD
ISR( TCE0_OVF_vect )
{         
   LCD_update();
}


As it loads one ADCvalue into one window position only. This code, however, does work:

Code:

... defines, includes, etc.

// Globals
volatile int ADCvalue;   // record ADC result
int window[ WINDOW_SIZE ];   // the smoothing window

int main( void )
{
... set ups

   // Set up and configure PORTE Timer/Counter
   TCE0.CTRLA = TC_CLKSEL_DIV64_gc;      // divide clock by 64 = 500 kHz
   TCE0.PER = 12500;                  // set clock period to 12500 ( 32 MHz / ( 2 * 64 * 12500 ) = approx 20 Hz for 2 frames )
   TCE0.INTCTRLA = TC_OVFINTLVL_LO_gc;      // set low level interrupt on overflow
   TCE0.CNT = 0;                     // zero clock

   PMIC.CTRL = PMIC_LOLVLEN_bm;   // enable low level interrupts
   sei();                     // enable interrupts

   while( 1 )
   {            
      _delay_ms( DELAY_TIME );      
   };

   return 0;
};

// LCD controller routine
void LCD_update( void )
{
... display code
}

// Interrupt routine to display on LCD
ISR( TCE0_OVF_vect )
{   
   ADCA.CH0.CTRL |= ADC_CH_START_bm;   // start conversion on channel 0
   while( !( ADCA.CH0.CTRL & ADC_CH_START_bm ) );   // wait until it completes
   ADCvalue = ADCA.CH0RES;

   // Simulate a stack reverse push for reading the ADC value into the window
   for ( uint8_t i = 0; i < WINDOW_SIZE - 1; i++ )
      window[ i ] = window[ i + 1 ];
   window[ WINDOW_SIZE - 1 ] = ADCvalue;
      
   LCD_update();
}


But then the ADC samples at an undesired frequency. Any ideas as to why the first doesn't load the entire window (shouldn't it return after the interrupt to the previous position,) and/or how to get the desired behavior?

Many TIA,
Craig
 
 View user's profile Send private message  
Reply with quote Back to top
Koshchi
PostPosted: Aug 14, 2012 - 04:35 PM
10k+ Postman


Joined: Nov 17, 2004
Posts: 13847
Location: Vancouver, BC

If you want to sample at a specific rate, then set up at timer to trigger the ADC at that rate, then use the ADC interrupt to save that value where you want it.
Quote:
Any ideas as to why the first doesn't load the entire window
Why do you think that it is not? The only difference between the two is the rate of the ADC.

_________________
Regards,
Steve A.

The Board helps those that help themselves.
 
 View user's profile Send private message  
Reply with quote Back to top
craignied
PostPosted: Aug 19, 2012 - 04:12 PM
Newbie


Joined: Apr 27, 2012
Posts: 19


Thanks super, Steve. I worked around it by doing the averaging inside the LCD routine. I identified that it wasn't loading the entire window by setting a breakpoint and watch variable with a JTAGICE3.
 
 View user's profile Send private message  
Reply with quote Back to top
Display posts from previous:     
Jump to:  
All times are GMT + 1 Hour
Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Powered by PNphpBB2 © 2003-2006 The PNphpBB Group
Credits