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
loutek
PostPosted: Jun 04, 2011 - 02:20 PM
Rookie


Joined: Dec 28, 2008
Posts: 47
Location: Italy

Hi all, I want to read a multiple ADC input without using interrupt.CPU running at 8 Mhz
I use this sub:
Code:
uint16_t Read_ADC (uint8_t ch)  {
ADMUX = (1<<REFS0);   //AVCC as ADC Voltage Reference
  ADCSRA = (1<<ADEN) | (1<< ADPS2); //enable ADC, prescale 16
ch = ch&0b00000111;
ADMUX |= ch;
 
  ADCSRA |= (1<<ADSC);
  while (!(ADCSRA & (1<<ADIF)));
  ADCSRA |= (1<<ADIF);
  return ADC;
  }

read the input value and in main:
Code:
int main() {
   DDRB = 0xFF;
   uint16_t ADC_result = 0;
   int i;
    USART_init();
   adc_Init();
   while (1) {
      for (i = 0; i < 3; i++) { //start the scan...
         ADC_result = Read_ADC(i); //and read the result
         switch (i) { ...then i use the value to do something
.........


But nothing happens.
However if I remove the for loop and
Code:
ADC_result = Read_ADC(0);

i can read the ADC value.
Any suggestion?

thank you
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Jun 04, 2011 - 02:23 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62371
Location: (using avr-gcc in) Finchingfield, Essex, England

Not enough context. Show more of the code and explain "nothing happens" and how you are observing that.

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
loutek
PostPosted: Jun 04, 2011 - 02:48 PM
Rookie


Joined: Dec 28, 2008
Posts: 47
Location: Italy

By now i just want to read a voltage on ADC0 and ADC1 and turn on/off a led.
Code:

nt main() {
   DDRB = 0xFF;
   uint16_t ADC_result = 0;
   int i;
    USART_init();
   adc_Init();
   while (1) {
      for (i = 1; i < 3; i++) {
         ADC_result = Read_ADC(i);
         switch (i) {
         case 1:
            if (ADC_result < 120) {
               PORTB = 0x01;
                   
            }
            else if (ADC_result > 150) {
               PORTB = 0x00;
               
            }

         case 2:
            if (ADC_result < 120) {
               PORTB = 0x01;
                   
            }
            else if (ADC_result > 150) {
               PORTB = 0x00;
               
            }

         }
      }
      }
      return 0;
   }

no led is turned on/off
Thank
 
 View user's profile Send private message  
Reply with quote Back to top
Koshchi
PostPosted: Jun 04, 2011 - 05:06 PM
10k+ Postman


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

Quote:
By now i just want to read a voltage on ADC0 and ADC1 and turn on/off a led.
Code:
for (i = 1; i < 3; i++) {
         ADC_result = Read_ADC(i);
But this reads ACD1 and ADC2.

_________________
Regards,
Steve A.

The Board helps those that help themselves.
 
 View user's profile Send private message  
Reply with quote Back to top
loutek
PostPosted: Jun 04, 2011 - 07:11 PM
Rookie


Joined: Dec 28, 2008
Posts: 47
Location: Italy

@koshch
you're right... But not working at all
Code:
for (i=0; i 2; i++)

i'll try another solution...
 
 View user's profile Send private message  
Reply with quote Back to top
Visovian
PostPosted: Jun 04, 2011 - 08:43 PM
Posting Freak


Joined: Aug 07, 2007
Posts: 1478
Location: Czech

deleted
 
 View user's profile Send private message  
Reply with quote Back to top
Visovian
PostPosted: Jun 04, 2011 - 08:58 PM
Posting Freak


Joined: Aug 07, 2007
Posts: 1478
Location: Czech

Quote:
ADMUX = (1<<REFS0); //AVCC as ADC Voltage Reference
ADCSRA = (1<<ADEN) | (1<< ADPS2); //enable ADC, prescale 16
ch = ch&0b00000111;
ADMUX |= ch;

Error, look here
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=107120&highlight=
 
 View user's profile Send private message  
Reply with quote Back to top
loutek
PostPosted: Jun 27, 2011 - 10:19 AM
Rookie


Joined: Dec 28, 2008
Posts: 47
Location: Italy

Thank you all...
Ok... Reading other posts it is better to use interrupt.
So that's my way:
Code:

/*
 ATmega16 @ 8 Mhz
 PORTA as ADC
 PORTB leds
           */

#include <avr/io.h>
#include <avr/interrupt.h>
#include <inttypes.h>

volatile uint8_t adc_result[8];
volatile uint8_t input = 0; // both var. volatite because shared by main and ISR ...clawson FAQ #1

void ADC_init(void);

int main(void) {
   DDRB = 0xFF; // PORTB as Out
   ADC_init();  //init ADC
   sei(); // enable all interrupts
   ADCSRA |= (1 << ADSC); // first ADC conversion

   while (1) {

      if (adc_result[0] > 150) {
         PORTB = 0x01;
      } else if (adc_result[0] < 150) {
         PORTB = 0x00;
      }

      if (adc_result[1] > 150) {
         PORTB = 0x02;
      } else if (adc_result[1] < 150) {
         PORTB = 0x00;
      }
   }
   return 0;
}

ISR( ADC_vect ) {
   adc_result[input] = ADCH; // input 0, first result, 8 bits
   if (input < 8)
   input++;
   else
   input = 0;

   ADMUX |= input; // next input
   ADCSRA |= ( 1 << ADSC ); // next conversion
}

void ADC_init() {
    ADMUX |= (1 << ADLAR) | (1 << REFS0); // left adj. and AVcc as reference
   ADCSRA = (1 << ADEN) | (1 << ADIE) | (1 << ADPS2); // Enable ADC, interrupt, prescaler 16
}


...but I can't see any led on. Sad
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Jun 27, 2011 - 10:41 AM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62371
Location: (using avr-gcc in) Finchingfield, Essex, England

Quote:

ADMUX |= input; // next input

You never clear the previous channel setting. Suggest you use:
Code:
ADMUX = (1 << ADLAR) | (1 << REFS0) | channel;

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
indianajones11
PostPosted: Jun 27, 2011 - 11:11 AM
Raving lunatic


Joined: Nov 28, 2004
Posts: 3553
Location: San Diego, Ca

Also, one time code should be done... once . Put

Code:
ADMUX = (1<<REFS0);   //AVCC as ADC Voltage Reference
  ADCSRA = (1<<ADEN) | (1<< ADPS2); //enable ADC, prescale 16
in your adc_init() ( which you already did, so no need to repeat the same stuff ). It's just a waste of time / memory to do it the way you did .

Your code with the switch is not right, time to open your C book and look at that.

_________________
1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1
 
 View user's profile Send private message  
Reply with quote Back to top
loutek
PostPosted: Jun 27, 2011 - 07:35 PM
Rookie


Joined: Dec 28, 2008
Posts: 47
Location: Italy

Hello, when I start debuging the changed code
Code:

#include <avr/io.h>
#include <avr/interrupt.h>
#include <inttypes.h>

volatile uint8_t adc_result[8];
volatile uint8_t input = 0; // both var. volatite because shared by main and ISR ...clawson FAQ #1


int main(void) {
   DDRB = 0xFF; // PORTB as Out
   ADMUX |= (1 << ADLAR) | (1 << REFS0); // left adj. and AVcc as reference
   ADCSRA = (1 << ADEN) | (1 << ADIE) | (1 << ADPS2); // Enable ADC, interrupt, prescaler 16
   sei(); // enable all interrupts
   ADCSRA |= (1 << ADSC); // first ADC conversion
   while (1) {
      if (adc_result[0] > 120) {
         PORTB = 0x01;
      } else if (adc_result[0] < 120) {
         PORTB = 0x00;
      }

      if (adc_result[1] > 120) {
         PORTB = 0x02;
      } else if (adc_result[1] < 120) {
         PORTB = 0x00;
      }
     
   }
   return 0;
}

ISR( ADC_vect ) {
   adc_result[input] = ADCH; // input 0, first result, 8 bits
   if (input < 8)
   input++;
   else
   input = 0;

   ADMUX |= (input & 0x07); // next input and mask the bits
   ADCSRA |= ( 1 << ADSC ); // next conversion

     }

I can see in the I/O view no ADSC setted by
Code:
ADCSRA |= (1 << ADSC); // first ADC conversion
instruction
I think code is correct but I can't check where is my error or what I can't understand.

Thank you
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Jun 27, 2011 - 07:41 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62371
Location: (using avr-gcc in) Finchingfield, Essex, England

Quote:

I start debuging

Simulator or real hardware debugging?

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
loutek
PostPosted: Jun 27, 2011 - 07:46 PM
Rookie


Joined: Dec 28, 2008
Posts: 47
Location: Italy

...real hardware debugging. I test hardware too and things work... i think it's a programming issue..
Thank you very much for reply.
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Jun 27, 2011 - 07:59 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62371
Location: (using avr-gcc in) Finchingfield, Essex, England

Quote:

ADMUX |= (input & 0x07); // next input and mask the bits

This is not right - you are NOT clearing the previous channel selection - presumably you did not understand my previous answer?

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
indianajones11
PostPosted: Jun 27, 2011 - 10:43 PM
Raving lunatic


Joined: Nov 28, 2004
Posts: 3553
Location: San Diego, Ca

I doubt that you put a breakpoint and then single-stepped into the ADSC being set, because you didn't see it , but you didn't say the ISR DIDN'T fire , OR that you didn't get adc_values . If you run the debugger at full speed, there's plenty you'll miss, if that's what you're doing .

Anyway, you're bouncing all around with these code versions and it's not a good move to go from non-working code to a more complex non-working version ( ISR ).

How are ALL your MCU adc pins connected and which debugger do you use ? Put adc_result in the watch window and breakpoint after it should get a value in the ISR .

You don't see any LEDs on, but only superman could since it would be too fast for you to see . You have no delays for when it's on / off .

_________________
1) Studio 4.18 build 716 (SP3)
2) WinAvr 20100110
3) PN, all on Doze XP... For Now
A) Avr Dragon ver. 1
B) Avr MKII ISP, 2009 model
C) MKII JTAGICE ver. 1
 
 View user's profile Send private message  
Reply with quote Back to top
loutek
PostPosted: Jun 29, 2011 - 02:27 PM
Rookie


Joined: Dec 28, 2008
Posts: 47
Location: Italy

to clear the previus channel:
Code:
 
ISR( ADC_vect ) {
   for (input=0; input <8; input++) {
        input = ADMUX;
        input &= 0x07;
        adc_result[input] = ADCH;
        ADMUX++;
      ADCSRA |= (1 << ADSC); // next ADC conversion
     }
    ADMUX &= 0xF0;
    }


Now if a simulator debug i can see ADSC setted, in real debug with avr dragon no ADSC is setted Confused Confused
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: Jun 29, 2011 - 02:29 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62371
Location: (using avr-gcc in) Finchingfield, Essex, England

Your code makes no sense whatsoever?!?

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
loutek
PostPosted: Jun 29, 2011 - 02:37 PM
Rookie


Joined: Dec 28, 2008
Posts: 47
Location: Italy

Quote:
Your code makes no sense whatsoever?!?

...Ok I give it up...
 
 View user's profile Send private message  
Reply with quote Back to top
Kartman
PostPosted: Jun 29, 2011 - 03:14 PM
Raving lunatic


Joined: Dec 30, 2004
Posts: 8789
Location: Melbourne,Australia

Go back to your original code and fix the problems. Have you read the datasheet onthe part you're using? It is all pretty simple, but you're making some fundamental mistakes.
 
 View user's profile Send private message  
Reply with quote Back to top
JohanEkdahl
PostPosted: Jun 29, 2011 - 04:05 PM
10k+ Postman


Joined: Mar 27, 2002
Posts: 18599
Location: Lund, Sweden

In your latest code, what is the point with doing
Code:
        ADMUX++;

?
Youre at the end of the loop, just about to iterate and increment input which will then be assigned to ADMUX.
 
 View user's profile Send private message Visit poster's website 
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