ATmega8 C- Programmierung AD- Wanlder

Gast #1475855
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;


}
}
#1475906
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.
Gast #1475949
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?
Gast #1476116
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
#1476131
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!
#1476140
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 :-)
#1476146
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.
#1476152
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?
#1476154
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
#1476171
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?
#1476179
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
#1476198
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...
Gast #1476240
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?
Gast #1476244
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
Gast #1476249
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
#1477033
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)
Gast #1477706
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren