Analog Input in CVAVR, Atmega8

Go To Last Post
15 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hey guys, I need to take 2 analog inputs from 2 potentiometers in an Atmega 8. I tried to go through the existing forums and understand, but I didn't. Could someone also mention if using the read_adc(0) is enough to get an adc value from the A0 Port?

 

Thanks for the answers.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Look at the Codevision examples.

Look at the CodeWizard.    Both the initialisation and the read_adc() function

 

Ask if you do not understand something.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Code

 

What does ADCH mean? I can see ADC0-7 on the atmega 8 diagram, but that's it.

Also, how does the ADCSRA= ADCSRA|0x40 help?

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That particular CV example is 12 years old !

 

I could explain what it means but it would be better to use the CodeWizard.

ATmega8535 is obsolete.   ATmega8 is "old" but still popular.

 

I suggest that you do not use interrupts.   Just call adc_read(N) when you want to read channel #N

// Voltage Reference: AVCC pin
#define ADC_VREF_TYPE ((0<<REFS1) | (1<<REFS0) | (0<<ADLAR))

// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input | ADC_VREF_TYPE;
// Delay needed for the stabilization of the ADC input voltage
delay_us(10);
// Start the AD conversion
ADCSRA|=(1<<ADSC);
// Wait for the AD conversion to complete
while ((ADCSRA & (1<<ADIF))==0);
ADCSRA|=(1<<ADIF);
return ADCW;
}

void main(void)
{
...
// ADC initialization
// ADC Clock frequency: 921.600 kHz
// ADC Voltage Reference: AVCC pin
ADMUX=ADC_VREF_TYPE;
ADCSRA=(1<<ADEN) | (0<<ADSC) | (0<<ADFR) | (0<<ADIF) | (0<<ADIE) | (0<<ADPS2) | (1<<ADPS1) | (0<<ADPS0);
...

 

The ADC can give a 10-bit result called ADCW.   ADCL is the low 8-bits.   ADCH has the high 2-bits.

If you select 8-bit result,  you just read ADCH which now holds the 8-bits.

 

The datasheet explains it quite well.

 

In practice you will use AVCC as ref if you have a good steady mains powered device.

Or the internal Bandgap reference if you have a battery powered device.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

zackdgod wrote:
What does ADCH mean?
It sounds like you will need to spend some time on datasheet study.  What do you learn when you search the datasheet for all occurrences of ADCH?  I'll guess that the last one is part of the Register Summary table...

 

Indeed, Mega8 in this day and age?  Mega8A, perhaps?  Why not Mega88 family?

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have to use it since it's the only microcontroller provided by our electronics society, and I need it to take input from a joystick.

I tried using the read_adc function to get an ac value and then pulse the 4033 clock that many times, hence effectively showing the adc value in the 7 segment display. But it is showing an error. Although it is showing 1023 every time and adding up, even if I change the value on the potentiometer.

This the error:

 

And the code used inside the main  (seg7 is the pin with the 4033 inputs,pulsing it once incr. value by one):

while (1)
      {
         a=read_adc(0);
         for(i=0;i<a;i++)
         {
         seg7=1;
         seg7=0;
         }   
         
         delay_ms(3000);
      }
}

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Draw a sensible schematic. Even though it is just a simulation, it looks like a dog's breakfast.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I can explain the data as: the 4033s being cascaded together, recieving input from PB0. The rest is, as you can see, a potentiometer connected to ADC0.

Please tell me if you need me to make the schematic and send it again.

Last Edited: Mon. Mar 4, 2019 - 11:05 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

zackdgod wrote:
But it is showing an error. Although it is showing 1023 every time ...

 

Show a complete test program.  AREF not connected on a Mega8 does not sound correct.  Why are there no Ground pins shown?  No connection to Vcc?  No decoupling capacitors?

 

What voltage is right on the ADC0 pin?  What voltage is on the AVcc pin?  What voltage is on the AREF pin?

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I suggested using AVCC for the VREF.

You should place a 100nF capacitor on te AREF pin.

I would not connect an external reference to the AREF pin.

 

I don't know how Proteus simulates an Analog voltage.

 

I would test a display by sending known values to it.   e.g. send 1234.   does it display "1234"?

 

You should always make neat schematics.

You should always write nicely formatted code.

 

It takes very little time or effort from you.   But it makes a big difference to your readers.   (and your teacher)

 

David.

Last Edited: Mon. Mar 4, 2019 - 01:45 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The display is working alright.

Connecting AVCC to the AREF doesn't change anything.

The power is 5v as per proteus notations. The GND terminal is present at potentiometer. Since display is working properly, I didn't think the pinout of those were important.

I connected decoupling capacitors, but it gave 1023 when connected to AVCC and 000 when connected to AREF.

 

I tried connecting 5v to AVCC, it gave 1023 for the voltage given in below diag.

When I connected it to AREF, it gave me 102 for the same value.

 

Then, I attached both AVCC and AREF to 5v while supplying the same voltage, and it gave me a correct output, as given in below image.

Please provide your opinions.

 

PS: that's 553

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No,  you must NOT connect AVCC to AREF pin.    AVCC is selected in software e.g.

// Voltage Reference: AVCC pin
#define ADC_VREF_TYPE ((0<<REFS1) | (1<<REFS0) | (0<<ADLAR))

// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input | ADC_VREF_TYPE;
...

Either paste your complete C code or attach it to your message.

 

We may not have Proteus licences but we can build a Codevision project.    And compare with your neatly drawn schematic.

 

We don't mind having backward displays.   But please say this means "0553"

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

#include <mega8.h>
#include <iobits.h>
#include <stdint.h>
#include <delay.h>
#define seg7 PORTB.0
// Declare your global variables here

unsigned int adc_data;
// Voltage Reference: AREF pin
#define ADC_VREF_TYPE ((0<<REFS1) | (0<<REFS0) | (0<<ADLAR))

// ADC interrupt service routine
interrupt [ADC_INT] void adc_isr(void)
{
// Read the AD conversion result
adc_data=ADCW;
}

// Read the AD conversion result
// with noise canceling
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input | ADC_VREF_TYPE;
// Delay needed for the stabilization of the ADC input voltage
delay_us(10);
#asm
    in   r30,mcucr
    cbr  r30,__sm_mask
    sbr  r30,__se_bit | __sm_adc_noise_red
    out  mcucr,r30
    sleep
    cbr  r30,__se_bit
    out  mcucr,r30
#endasm
return adc_data;
}

void main(void)
{
// Declare your local variables here
   int i,a;
// Input/Output Ports initialization
// Port B initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In 
DDRB=(1<<DDB7) | (1<<DDB6) | (1<<DDB5) | (1<<DDB4) | (1<<DDB3) | (1<<DDB2) | (1<<DDB1) | (1<<DDB0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T 
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);

// Port C initialization
// Function: Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In 
DDRC=(0<<DDC6) | (0<<DDC5) | (0<<DDC4) | (0<<DDC3) | (0<<DDC2) | (0<<DDC1) | (0<<DDC0);
// State: Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T 
PORTC=(0<<PORTC6) | (0<<PORTC5) | (0<<PORTC4) | (0<<PORTC3) | (0<<PORTC2) | (0<<PORTC1) | (0<<PORTC0);

// Port D initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In 
DDRD=(0<<DDD7) | (0<<DDD6) | (0<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) | (0<<DDD1) | (0<<DDD0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T 
PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
TCCR0=(0<<CS02) | (0<<CS01) | (0<<CS00);
TCNT0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=0xFFFF
// OC1A output: Disconnected
// OC1B output: Disconnected
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (0<<WGM10);
TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (0<<WGM12) | (0<<CS12) | (0<<CS11) | (0<<CS10);
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0<<AS2;
TCCR2=(0<<PWM2) | (0<<COM21) | (0<<COM20) | (0<<CTC2) | (0<<CS22) | (0<<CS21) | (0<<CS20);
TCNT2=0x00;
OCR2=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=(0<<OCIE2) | (0<<TOIE2) | (0<<TICIE1) | (0<<OCIE1A) | (0<<OCIE1B) | (0<<TOIE1) | (0<<TOIE0);

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
MCUCR=(0<<ISC11) | (0<<ISC10) | (0<<ISC01) | (0<<ISC00);

// USART initialization
// USART disabled
UCSRB=(0<<RXCIE) | (0<<TXCIE) | (0<<UDRIE) | (0<<RXEN) | (0<<TXEN) | (0<<UCSZ2) | (0<<RXB8) | (0<<TXB8);

// Analog Comparator initialization
// Analog Comparator: Off
// The Analog Comparator's positive input is
// connected to the AIN0 pin
// The Analog Comparator's negative input is
// connected to the AIN1 pin
ACSR=(1<<ACD) | (0<<ACBG) | (0<<ACO) | (0<<ACI) | (0<<ACIE) | (0<<ACIC) | (0<<ACIS1) | (0<<ACIS0);

// ADC initialization
// ADC Clock frequency: 1000.000 kHz
// ADC Voltage Reference: AREF pin
ADMUX=ADC_VREF_TYPE;
ADCSRA=(1<<ADEN) | (0<<ADSC) | (0<<ADFR) | (0<<ADIF) | (1<<ADIE) | (0<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);
SFIOR=(0<<ACME);

// SPI initialization
// SPI disabled
SPCR=(0<<SPIE) | (0<<SPE) | (0<<DORD) | (0<<MSTR) | (0<<CPOL) | (0<<CPHA) | (0<<SPR1) | (0<<SPR0);

// TWI initialization
// TWI disabled
TWCR=(0<<TWEA) | (0<<TWSTA) | (0<<TWSTO) | (0<<TWEN) | (0<<TWIE);

// Globally enable interrupts
#asm("sei")

while (1)
      {
         a=read_adc(0);
         for(i=0;i<a;i++)
         {
         seg7=1;
         seg7=0;
         }   
         
         delay_ms(3000);
      }
}

Most of this is from the CV wizard itself

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

zackdgod wrote:
Most of this is from the CV wizard itself

Agreed.

// Voltage Reference: AREF pin
#define ADC_VREF_TYPE ((0<<REFS1) | (0<<REFS0) | (0<<ADLAR))

So, when you made this selection in the CodeVision wizard, what does the datasheet say about that reference for the ADC?

 

Do you understand how an ADC works?  I suggest a re-read and study of that datasheet chapter.

 

Have you told us what voltage is on the various pins, as I asked earlier?  Depending on the answers to that, 1023 could be a "correct" answer.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Apparently, that 4033 resets itself with a timeout?  Sounds sophisticated for 40xx.

 

[edit]  I don't see that in the part description. http://www.ti.com/product/CD4033B

CD4026B and CD4033B each consist of a 5-stage Johnson decade counter and an output decoder which converts the Johnson code to a 7-segment decoded output for driving one stage in a numerical display.

A Johnson counter was needed in the Blazing Saddles movie. https://www.youtube.com/watch?v=...

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Last Edited: Mon. Mar 4, 2019 - 08:41 PM