Forum: Mikrocontroller und Digitale Elektronik ADC Wandler des ATMega32


von Jan P. (jan__)


Lesenswert?

Hi Leute,

ich suche jz schon eine ganze Weile nach einer Möglichkeit den 
Ad-Wandler des ATMega32 zu programmieren.
Soweit so gut.

Im Netz habe ich zwei Erklärungen mit Beispiel gefunden und habe 
versucht mich an diesen entlang zu bewegen um mein eigenes Prog zu 
schreiben.

Was will ich machen?
Na ich denke mal, dass dies der Klassiker ist, ein Poti am ADC1 wird 
gedreht, und erzeugt eine Spannung an diesem Eingang zwischen 0 und 5V.
Daraufhin soll dann der Port C geschaltet werden, an dem eine 
Relaisplatine hängt. Die Relais sollen dann den binären Wert der 
Spannung anzeigen.

Ich möchte es auf diese Art und Weise, damit ich erstmal sehe wie der 
AD-Wandler hier funzt und um dann weitere Verbesserungen vorzunehmen.

Hier mal den Code den ich geschrieben habe, der aber leider keine 
Reaktion am Board zeigt:
1
#include <avr/io.h>
2
3
4
int main(void)
5
6
{
7
   int i=0, t;
8
   DDRC=0b11111111;
9
   PORTC=0b00000000;
10
   
11
    while(1)
12
    {
13
       
14
  ADCSRA=0b10000110;
15
16
  
17
  ADMUX=0b00000000;
18
  
19
  ADCSRA|=0b01000000;
20
  
21
  while(bit_is_set(ADCSRA,ADSC));
22
  
23
  i=ADCW*5/1023;
24
  PORTC =  i;    
25
      
26
    }
27
}


Vielen Dank im Voraus

von jodeldiplom (Gast)


Lesenswert?

Jan Phillip schrieb:
> ADCSRA=0b10000110;
Kein Mensch hat Lust daraus die gesetzten Bits zu popeln.

Besser: ADCSRA=(1<<ADABC)|(1<<ABX) (Namen zufällig gewählt)

von Jan P. (jan__)


Lesenswert?

Ok, dann änder ich das mal....

von Spess53 (Gast)


Lesenswert?

Hi

>Daraufhin soll dann der Port C geschaltet werden,

JTAG abgeschaltet?

>ADCSRA=0b10000110;

Und jetzt sollen alle im Datenblatt nachsehen, was das bedeutet?

Tue auch dir einen Gefallen und benutze die Schreibweise

ADCSRA=1<<ADEN|1<< ....

MfG Spess

von Jan P. (jan__)


Lesenswert?

So, da isseet:
1
/*
2
 * AD_Wandler.c
3
 *
4
 * Created: 28.11.2012 17:19:47
5
 *  Author: Jan
6
 */ 
7
8
#include <avr/io.h>
9
10
11
int main(void)
12
13
{
14
   int i=0, t;
15
   DDRC=0b11111111;
16
   PORTC=0b00000000;
17
   
18
    while(1)
19
    {
20
       
21
  ADCSRA=(1<<ADEN)|(1<<ADPS2)|(1<<ADPS1);
22
23
  
24
  ADMUX=0b00000000;
25
  
26
  ADCSRA = (1<<ADSC);
27
  
28
  while(bit_is_set(ADCSRA,ADSC));
29
  
30
  i=ADCW*5/1023;
31
  PORTC =  i;    
32
      
33
    }
34
}

von Spess53 (Gast)


Lesenswert?

Hi

>  ADMUX=0b00000000;

Welche Refernzspannung willst du benutzen?

MfG Spess

von Jan P. (jan__)


Lesenswert?

Spess53 schrieb:

>
>>Daraufhin soll dann der Port C geschaltet werden,
>


Was meinst du damit? Und was soll das bewirken?


DIe Refspannung sollen die externen 5V sein

von Spess53 (Gast)


Lesenswert?

Hi

>Was meinst du damit? Und was soll das bewirken?

Wenn das JTAG-Interface nicht abgeschaltet ist kannst du vier Pins vom 
PortC nicht benutzen.

MfG Spess

von Jan P. (jan__)


Lesenswert?

Achso, das habe ich noch nie gemacht, die Relaiskarte funzt aber 
problemlos wenn ich ein anderes Prog aufspiele.

von Dietrich L. (dietrichl)


Lesenswert?

Jan Phillip schrieb:
> ADMUX=0b00000000;

Da solltest Du Dir das Datenblatt nochmal anschauen. Unabhängig von der 
Referenz ist der Kanal ADC1 jedenfalls nicht 00000.

Übrigens: die Initialisierung würde ich nicht in der while-Schleife 
machen, sondern im Init-Teil. Ob es allerdings die Funktion stört ist 
eine andere Sache.

Gruß Dietrich

von Karl H. (kbuchegg)


Lesenswert?

Tu dir einen Gefallen und hol dir von hier die Routinen
AVR-GCC-Tutorial/Analoge Ein- und Ausgabe: Nutzung des ADC

von Markus W. (horand)


Lesenswert?

Ich kenn den 32er jetzt nicht sondern nur die 8er atmegas aber was auf 
die schnelle auffällt und noch nicht gesagt wurde ist:

In der 2. Version setzt du beim starten der Wandlung das ganze ADCSRA 
auf (1<<ADSC) und löscht damit deine anderen Einstellungen.

Und wenn du dein Ergebnis durch 1023 dividierst und sonst nur int hast 
wird dir nicht mehr viel rauskommen in dein i bzw. dann am Port

lg Markus

von Jan P. (jan__)


Lesenswert?

Das mit dem int hab ich extra gemacht, damit auf jeden Fall eine ganze 
Zahl übergeben wird. Das wird hinterher noch geändert.

Den Fehler mit dem Überschreiben ändere ich mal.

von Jan P. (jan__)


Lesenswert?

So, ich habe das Problem gelöst.

Das Layout der Platine passt nicht mit dem des Controllers zusammen. 
ADC1 auf der Platine ist in Wahrheit ADC4 am Controller. Dadurch konnte 
er auch nichts messen.
Ich hab das Programm dann noch ein wenig bearbeitet. Es sieht jz so aus:
1
#include <avr/io.h>
2
3
4
5
int main(void)
6
7
{
8
   double i=0;
9
   int  t;
10
   DDRC=0b11111111;
11
   PORTC=0b00000000;
12
   
13
   
14
   
15
  ADCSRA=(1<<ADPS2)|(1<<ADPS1);
16
17
  ADMUX |=(1<<ADLAR)|(1<<MUX2);
18
   
19
  ADCSRA|=(1<<ADEN);
20
   
21
    while(1)
22
    {
23
     
24
    
25
  ADCSRA |= (1<<ADSC);
26
  
27
  while (ADCSRA & (1<<ADSC) );
28
  
29
  //i=ADCW*5/1023;
30
  
31
  PORTC =  ADCH;
32
    
33
      
34
    }
35
}


Besten Danke :)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.