Search This Blog

Thursday, February 28, 2008

Simple Idle Mode ( Mega ) ADC Example

The first ADC control example uses the Idle sleep mode and a simple
delay loop between samples, and the use of a pointer to write to the
output array. The latter is hardly warranted in this case, but if the
output array was two-dimensional it would make sense. Note the use of sbi/cbi instructions setting bits on PORTA. This is a very good debug tool if you have access to an oscilloscope.


Sample program to demonstrate using the Mega103 analog to digital
converter (ADC) in conjunction with the simple sleep instruction to
minimize power use.

For demonstration purposes, the high 8 bits of channel 3 (10-2) are written
to PORTB, the set of LEDs on an STK300.

Ron Kreymborg
May 2001


#include <stdlib.h>
#include <interrupt.h>
#include <signal.h>

#define BYTE unsigned char
#define ADC_CONTROL (1<<ADEN | 1<<ADIE | 1<<ADPS2 | 1<<ADPS0)

int main(void);
void AtoDconverter(void);
void Delay(void);

static volatile int Sample[8]; // a/d converter samples
static volatile int *Pointer[8];
static volatile BYTE Index;

int main(void)
int i, value;

outp(0x00, PORTA); // all low
outp(0xff, DDRA); // all output
outp(0xff, PORTB); // all low
outp(0xff, DDRB); // all output
sbi(ACSR, ACD); // disable comparator
cbi(MCUCR, SM0);
cbi(MCUCR, SM1);
sbi(MCUCR, SE);

for (i=0; i<8; i++)
Pointer[i] = &Sample[i]; // initialise pointers

Delay(); // allow clocks to settle
sei(); // hello world

while (1)
AtoDconverter(); // take a sample
value = ~(Sample[2]>>2); // display channel 3 on the STK300
outp(value, PORTB); // set of leds

return 0;

// Control the ADC for an eight channel sample using the inbuilt noise
// cancelling capability.
void AtoDconverter(void)
sbi(PORTA, 1); // for scoping

for (Index=0; Index<8; Index++)
sbi(PORTA, 3); // for scoping
cbi(ADCSR, ADEN); // turn off ADC
outp(Index, ADMUX); // select the channel
outp(ADC_CONTROL | 1<<ADSC, ADCSR); // turn ADC on and start conversion

// The read is done in the interrupt routine. Here we go to
// sleep in Idle mode until the conversion is done.
cbi(PORTA, 3); // for scoping

cbi(PORTA, 1); // for scoping

// Arbitrary inter-sample delay.
void Delay(void)
int i, j;

for (i=0; i<2000; i++)
j = i;

// ADC conversion complete interrupt
*Pointer[Index] = inp(ADCL) | inp(ADCH)<<8;

No comments: