Forum: Compiler & IDEs ATmega8 C- Programmierung AD- Wanlder


von Martin (Gast)


Lesenswert?

Hallo,
ich würde gerne einen ATmega8 in C-Sprache so porgrammieren, dass ich 
eine Spannung in den AD- Wandler einlese und diese anhand von LED´s 
anzeigen lassen will! Ich habe ein Programm geschrieben, welches aber 
nicht funktioniert. Könnte mir bitte jmd helfen?

MfG Martin



#include <avr/io.h>

void main(void)
{

int b;

DDRC = 0x00;
DDRD = 0xFF;

ADCSRA = 0xE6;

while(1)
{

b = ADCW;


if(b>51 && b<58)
PORTD = 0x01;

if(b>59 && b<64)
PORTD = 0x03;

if(b>65 && b<71)
PORTD = 0x07;

if(b>72 && b<77)
PORTD = 0x0F;

if(b>78 && b<83)
PORTD = 0x1F;

if(b>84 && b<90)
PORTD = 0x3F;

if(b>91 && b<96)
PORTD = 0x7F;

if(b>97 && b<102)
PORTD = 0xFF;


}
}

von Oliver (Gast)


Lesenswert?


von Gaast (Gast)


Lesenswert?

lies mal das datenblatt vom atmega8 durch, dann findest du auch noch ein 
Beispiel...

von F. R. (freiling)


Lesenswert?

Der Fehler liegt darin, dass du zwar den ADC ständig auslesen willst, 
aber nach einer fertigen Wandlung wird der ADC ja angehalten und du 
musst ihn wieder starten!
1
while(1)
2
{
3
4
ADCSRA |= (1<<ADSC);              // eine ADC-Wandlung 
5
  while ( ADCSRA & (1<<ADSC) ) {
6
     ;     // auf Abschluss der Konvertierung warten 
7
8
b = ADCW;
9
10
...
11
12
}
13
}

damit sollte es funktionieren, sofern der Rest richtig initialisiert 
wurde.

von Martin (Gast)


Lesenswert?

echt? ich hab ihn ja eig im free runing mode, deswegen denk ich dass er 
eig ständig läuft!
martin

von Rolf Magnus (Gast)


Lesenswert?

> Ich habe ein Programm geschrieben, welches aber nicht funktioniert.

Denkst du daß "nicht funktioniert" eine sinnvolle Feherbeschreibung ist? 
Wie sieht der Testaufbau aus? Was passiert genau? Was hättest du 
erwartet? Ist ein Hardware-Fehler auszuschließen?

von Martin (Gast)


Lesenswert?

ja des kann man jetzt auslegen wie man will, aber da das prgramm einen 
fehler enthält funktioniert es für mich nicht! die hardware stimmt und 
der grundaufbau vom programm auch! der fehler liegt eindeutig an der 
programmierung des AD- wandlers, aber ich weiß halt nicht woran! hab mir 
das datenblatt durchgelesen und schon diverse seiten und deshalb scuh 
ich hier hilfe!
mfg martin

von Justus S. (jussa)


Lesenswert?

Martin schrieb:
> ja des kann man jetzt auslegen wie man will, aber da das prgramm einen
> fehler enthält funktioniert es für mich nicht!

es ist immer hilfreich, nicht zu sagen, was nicht funktioniert, das 
macht das Helfen immer so einfach...

> die hardware stimmt und
> der grundaufbau vom programm auch!

das sagen sie immer...

> der fehler liegt eindeutig an der
> programmierung des AD- wandlers, aber ich weiß halt nicht woran! hab mir
> das datenblatt durchgelesen und schon diverse seiten und deshalb scuh
> ich hier hilfe!

und behälst alle grundlegenden Infos für dich, sehr schlau...

und sowas
1
ADCSRA = 0xE6;

macht man nicht!

von Karl H. (kbuchegg)


Lesenswert?

Justus Skorps schrieb:

> und sowas
>
>
1
> ADCSRA = 0xE6;
2
>
>
> macht man nicht!

Genauer gesagt hält es mich (und wahrscheinlich viele andere ebenso) 
davon ab, auch nur einen Gedanken an Hilfe zu verschwenden.
Wenn du es absichtlich möglichst kryptisch schreibst, dann sieh zu wie 
du alleine zurecht kommst.

Das C-Motto "Es war schwer zu schreiben, es soll auch schwer zu lesen 
sein" ist längst allgemein ad acta gelegt worden :-)

von Karl H. (kbuchegg)


Lesenswert?

Im Datenblatt vom Mega16 steht zb
(funktioniert beim Mega8 genau gleich. Das 16er hab ich aber gerade im 
anderen Fenster offen)

> Using the ADC Interrupt Flag as a trigger source makes
> the ADC start a new conversion as soon as the ongoing conversion
> has finished. The ADC then operates in Free Running mode,
> constantly sampling and updating the ADC Data Register. The
> first conversion must be started by writing a logical one to
> the ADSC bit in ADCSRA.

Da ich aber kein Interesse daran habe, dein 0xE6 auseinanderzudröseln, 
kann ich auch nicht sagen, ob du ADSC setzt oder nicht.

von Martin (Gast)


Lesenswert?

und sowas
>
>> ADCSRA = 0xE6;
>

>
> macht man nicht!


wie macht man es dann?

is doch egal ob ich des schreib oder:

ADCSRA = 0b11100110

mfg martin

von Martin (Gast)


Lesenswert?

ja gut macht sinn, so ist es leichter zu verstehen!
;-)
martin

von Karl H. (kbuchegg)


Lesenswert?

Martin schrieb:
> und sowas
>>
>>> ADCSRA = 0xE6;
>>
>
>>
>> macht man nicht!
>
>
> wie macht man es dann?

So

  ADCSRA = ( 1 << ADEN )  |    // Enable
           ( 1 << ADSC )  |    // Start Conversion
           ( 1 << ADATE ) |    // Auto Trigger Enable
           ( 1 << ADPS2 ) |    // Prescaler 64
           ( 1 << ADPS0 );

und dann hat man auch ein paar Schlüsselwörter, mit denen man im 
Datenblatt suchen kann.

Zb. steht im Dtaenblatt bei ADATE

• Bit 5 – ADATE: ADC Auto Trigger Enable
When this bit is written to one, Auto Triggering of the ADC is enabled. 
The ADC will start a conversion on a positive edge of the selected 
trigger signal.

Wo machst du letzteres, bzw. wie stellst du sicher, dass so ein Trigger 
Signal kommt?

von Michael W. (retikulum)


Lesenswert?

Martin schrieb:
> und sowas
>>
>>> ADCSRA = 0xE6;
>>
>
>>
>> macht man nicht!
>
>
> wie macht man es dann?
>
> is doch egal ob ich des schreib oder:
>
> ADCSRA = 0b11100110
>
> mfg martin

Die Kollegen wollen darauf hinaus, dass es selbsterklärend ist wenn man

ADCSRA = (1 << Bitname) schreibt.

Michael

von hoschi (Gast)


Lesenswert?

Ja das ist egal es ist beides Mist.

Schau doch mal ins TUT

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Analoge_Ein-_und_Ausgabe

Da sind Beispiele wie man leserlich programmiert und sogar so ziemlich 
"out of the Box" funktionieren.

von Karl H. (kbuchegg)


Lesenswert?

Was passiert eigentlich, wenn du
* zuerst den ADC fertig konfigurierst
* und erst dann mittels ADSC die erste Konvertierung startest
1
  ADCSRA = ( 1 << ADEN )  |    // Enable
2
           ( 1 << ADATE ) |    // Auto Trigger Enable
3
           ( 1 << ADPS2 ) |    // Prescaler 64
4
           ( 1 << ADPS0 );
5
6
7
  ADCSRA |= ( 1 << ADSC )  |    // und los gehts!

Auch vermisse ich die Einstellung der Referenzspannung. Machst du 
nichts, dann hast du: AREF, Internal Vref turned off
Daher die Frage: Wie sieht deine ARef Beschaltung aus?

von Justus S. (jussa)


Lesenswert?

Karl heinz Buchegger schrieb:

>
> Zb. steht im Dtaenblatt bei ADATE
>
> • Bit 5 – ADATE: ADC Auto Trigger Enable


uhm, also in meinem Datenblatt zum Mega8 gibt es kein ADATE...

von gast (Gast)


Lesenswert?

hmm warum nicht den  ADC Complete ISR nutzen ^^

immer wenn der wert fetrig ist kommt ein interrupt
dann kann man auch schnell die LED setzen und fertig

von Karl H. (kbuchegg)


Lesenswert?

Justus Skorps schrieb:
> Karl heinz Buchegger schrieb:
>
>>
>> Zb. steht im Dtaenblatt bei ADATE
>>
>> • Bit 5 – ADATE: ADC Auto Trigger Enable
>
>
> uhm, also in meinem Datenblatt zum Mega8 gibt es kein ADATE...

Kram, kram, kram

Tatsächlich. Ds heißt beim Mega8 anders als im Mega16
OK. Dann nenn es ADFR

(Funktioniert auch ein wenig anders. Hätte doch wohl das Mega8 DB 
raussuchen sollen)

Ich würd es aber trotzdem mit der Variante:
"Zuerst fertig konfigurieren, dann starten" versuchen.
1
  ADCSRA = ( 1 << ADEN )  |    // Enable
2
           ( 1 << ADFR )  |    // Free running
3
           ( 1 << ADPS2 ) |    // Prescaler 64
4
           ( 1 << ADPS0 );
5
6
7
  ADCSRA |= ( 1 << ADSC )  |    // und los gehts!

Und die Frage nach der Referenzspannung bleibt natürlich auch noch

von Justus S. (jussa)


Lesenswert?

Karl heinz Buchegger schrieb:

> Tatsächlich. Ds heißt beim Mega8 anders als im Mega16
> OK. Dann nenn es ADFR
>
> (Funktioniert auch ein wenig anders. Hätte doch wohl das Mega8 DB
> raussuchen sollen)

wenn es nur ein anderer Name gewesen wäre hätte ich schon nicht 
gemeckert ;c)

> Und die Frage nach der Referenzspannung bleibt natürlich auch noch

aber sein Hardware-Aufbau ist doch garantiert richtig und ein 
Geheimnis...

von Rolf Magnus (Gast)


Lesenswert?

> ja des kann man jetzt auslegen wie man will, aber da das prgramm einen
> fehler enthält funktioniert es für mich nicht!

Was ich damit ausdrücken wollte, war, daß "funktioniert nicht" keine
auch nur annähernd ausreichende Beschreibung des Verhaltens ist.
Was mir auffällt ist, daß nur in einem recht kleinen Bereich von 5% bis 
10% der AREF-Spannung überhaupt irgendwelche Ausgänge high-Pegel 
bekommen. Ob das so gehört, weiß ich nicht, da du es ja partout nicht 
verraten willst. Ohne zu wissen, welche Spannungen du an den Eingang 
anlegst, was an AREF angelegt ist und welche Ausgaben du darauf 
erwartest, glaube ich dir deshalb nicht einfach so, daß da kein Fehler 
sein kann.

> die hardware stimmt und der grundaufbau vom programm auch!

Hmm, und da bist du dir absolut 100%ig sicher?

von Oliver (Gast)


Lesenswert?

>> die hardware stimmt und der grundaufbau vom programm auch!

>Hmm, und da bist du dir absolut 100%ig sicher?

Ist doch klar: Der ATMega ist kaputt. Was anderes kann es ja gar nicht 
mehr sein, wo doch alles 100% in Ordnung ist, (ausser, daß es nicht 
funktioniert)

Das Programm ist es nämlich auch nicht. Das sollte das tun, was du da 
hingeschrieben hast.

Oliver

von P. S. (Gast)


Lesenswert?

Spaetestens, wenn man mit sowas wie den AD-Wandlern spielen will, sollte 
man sich vieleicht erst eine gescheite Ausgabemoeglichkeit beschaffen 
(egal ob seriell oder Display).

von Oliver (Gast)


Lesenswert?

>Ist doch klar: Der ATMega ist kaputt.

Nachtrag: Das wäre nicht der erste Mega, der sich mit VCC an AREF nach 
einer unbeabsichtigt aktivierten internen Spannungsreferenz sehr seltsam 
verhält.

Oliver

von Martin (Gast)


Lesenswert?

hallo,
die AREF liegt bei meiner Hardware an der VCC.
Die VCC beträgt natürlich 5 Volt.
Und ich möchte gerne, dass 8 LED´s eine Spannung zwischen 1 und 2 Volt 
an einem Balken anzeigen! Die LED´s werden über ULN2803 Treiber 
angesteuert!
mfg martin

von Karl H. (kbuchegg)


Lesenswert?

OK.
Dann würde ich jetzt erstmal vorschlagen, die ADC Funktion aus dem 
gcc-Tutorial zu nehmen. Die ist getestet und funktioniert.
Von der den Wert auslesen lassen und den Wert ohne Modifikation direkt 
an den Port zuweisen. Wenn du dann an der Messpannung drehst (Poti?) 
muss sich das LED-Bild verändern. Wenn es das nicht tut hast du ein 
Hardwareproblem (oder den ADC bereits geschrotter, ohne Not hängt man 
den ARef nicht an Vcc)

von Rolf Magnus (Gast)


Lesenswert?

> Die VCC beträgt natürlich 5 Volt.

So natürlich ist das nicht.

> Und ich möchte gerne, dass 8 LED´s eine Spannung zwischen 1 und 2 Volt
> an einem Balken anzeigen!

Dein Balken wird sich nicht verändern, solange deine Spannung über 0,5V 
liegt. Vielleicht ist dir entgangen, daß der ADC 10 Bit Auflösung hat.
Deine Werte würden stimmen, wenn er 8 Bit hätte.

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.