Forum: Compiler & IDEs Problem bei LCD-Ausgabe


von Stefan W. (bububaer)


Lesenswert?

Hallo Forum,

erst mal will ich mich hier kurz vorstellen. Ich heiße Stefan, bin 26 
Jahre alt und komme aus dem Allgäu. Seit ca. einem Jahr beschäftige ich 
mich mit Mikrocontrollern. Ich lese hier schon seit längerem mit und hab 
mich jetzt einfach mal registriert.

Ich habe nämlich ein Problem mit einem Programm. Ich möchte eigentlich 
nichts weiter als eine Spannung am analogen Eingang auf dem Display 
ausgeben.

Mein Problem, auf dem Display wird immer 1023 angezeigt, egal, welche 
Spannung ich am PINC0 anlege. Es handelt sich um einen ATMega8.
Freu mich, wenn mir jemand auf die Sprünge helfen kann

Hier das Programm:



void main(void)
{
char wert_str [10];
char test;
DDRD=0xff;
DDRC=0x00;
ADCSR=(1<<ADEN)|(1<<ADPS2)|(1<<ADPS0);

while (1)
{
ADMUX=PINC0;
ADCSR|=(1<<ADSC);
while (bit_is_set(ADCSR, ADSC))
;
itoa (ADCW, wert_str, 10);
lcd_init();
lcd_on();
lcd_goto(1,1);
lcd_write_s (wert_str);
}
}

von Flo (Gast)


Lesenswert?

die lcd_init() gehört nicht in die while(1)-Schleife, du musst das 
Display nur am Anfang 1-mal initialisieren.

Zum ADC:

Test mal aus, den Wert des ADC zwischenzuspeichern, also:

int wert = ADCW;
itoa (wert,wert_str, 10);
...

von Stefan W. (bububaer)


Lesenswert?

Wow, bekommt man hier schnell ne Antwort. Danke, Flo. Ich hab jetzt mal 
alles so geändert wie du es beschrieben hast, das Problem ist leider 
immer noch das gleiche. Das Display zeigt 1023 an, egal, welche Spannung 
ich anlege.
Irgendwo muss noch irgendwas falsch sein...
So sieht das Programm jetzt aus:


void main(void)
{
char wert_str [10];
char test;
lcd_init();

DDRD=0xff;
DDRC=0x00;

ADCSR=(1<<ADEN)|(1<<ADPS2)|(1<<ADPS0);

while (1)
{
ADMUX=PINC0;
ADCSR|=(1<<ADSC);
while (bit_is_set(ADCSR, ADSC))
;

int wert = ADCW;
itoa (wert,wert_str, 10);

lcd_on();
lcd_goto(1,1);
lcd_write_s (wert_str);

}
}

von Hc Z. (mizch)


Lesenswert?

> ADMUX=PINC0;


Schau Dir mal im Datenblatt an, wie die Bits in ADMUX heißen und was sie 
bewirken.  PINC0 heißt keines davon und ob eine 0 in ADMUX richtig ist, 
hängt von der Beschaltung von Aref ab.  Die weiß keiner hier außer Dir, 
aber mit Standardbeschaltung (C an Aref) ist 0 falsch.

von Stefan W. (bububaer)


Lesenswert?

Hey, super. Vielen Dank für eure Beiträge. Ich hab meinen Fehler 
gefunden. Ich hab tatsächlich vergessen an Aref eine Spannung anzulegen.

Vielen Dank

Viele Grüße
Bubu

von Falk B. (falk)


Lesenswert?

@  Stefan W. (bububaer)

>Hey, super. Vielen Dank für eure Beiträge. Ich hab meinen Fehler
>gefunden. Ich hab tatsächlich vergessen an Aref eine Spannung anzulegen.

Schon wieder ein Fehler. An AREF gehört ein 100nF Kondensator gegen GND, 
sonst nichts.

MFG
Falk

von Stefan W. (bububaer)


Lesenswert?

Hi Falk,

ich dachte bisher immer, dass man an Aref 5V anschließen soll. Dann 
funktioniert das auch schon recht gut. Ich bekomm dann am Ausgang Werte 
von ca. 100 - 1023.
Wieso meinst du, dass ein 100nF gegen GND hin muss?? Warum macht man das 
so??
Ich glaub, irgendwo hab ich nen ganz großen Denkfehler drin. Ich hoffe, 
mit eurer Hilfe komm ich noch drauf...

Jeztt wollte ich noch den Wert als Kommawert ausgeben. Also die 
tatsächliche Spannung, z.B. 3,7 Volt.


Mein Lösungsansatz (der nicht funktioniert):

while (bit_is_set(ADCSR, ADSC))
;

unsigned char ZW=ADCW;
ZW=ZW*0.0044921;         //4,6 Volt / 1024 = 0,0044921

itoa (ZW,wert_str, 10)

Wie macht man das jetzt mit den Kommazahlen?? So wie ich das jetzt ha, 
zeigt er nur noch 0 und 1 an.


Viele Grüße
Bubu

von Falk B. (falk)


Lesenswert?

@Stefan W. (bububaer)

>Wieso meinst du, dass ein 100nF gegen GND hin muss?? Warum macht man das
>so??

Weils im Datenblatt steht.

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

>Jeztt wollte ich noch den Wert als Kommawert ausgeben. Also die
>tatsächliche Spannung, z.B. 3,7 Volt.

Siehe Festkommaarithmetik.

MFG
Falk

von Εrnst B. (ernst)


Lesenswert?

Stefan W. schrieb:
> ich dachte bisher immer, dass man an Aref 5V anschließen soll

Vor vielen, vielen Jahren, als die Welt noch jung war, gab es mal µCs, 
bei denen man nicht per Software die Referenzspannung für den ADC wählen 
konnte.
Bei denen musste man tatsächlich 5V an Aref anschließen.

Inzwischen braucht man das nicht mehr, einfach Kondensator an den Pin, 
und per REFSxx-Bits AVCC als Referenz auswählen, wenn man wirklich gegen 
5V messen will.

von Stefan W. (bububaer)


Lesenswert?

Super, danke für eure Hilfe. Bin schon ein ganz großes Stück weiter. 
Allerdings arbeite ich immer noch mit der externen Aref (ich geb die 
Betriebsspannung, 4,6 Volt auf den Aref-Pin).
Kann mir jemand den Befehl verraten, wie ich Aref per Software 
beschalten kann??
Im Tutorial hab ich die Register REFS1 und REFS0 gefunden. Angenommen 
ich möchte Avcc als Referenz nehmen, dann muss ich REFS1 auf 0 und REFS0 
auf 1 setzen.
Wäre das dann so richtig:
ADMUX=(1<<REFS0);



Ansonsten sieht das Programm jetzt so aus (ich hab jetzt noch PINC0 
eingefügt um eine zweite Spannung anzuzeigen:


void main(void)
{
double wert_str [10];
double ZW;
lcd_init();

DDRD=0xff;
DDRC=0x00;

ADCSR=(1<<ADEN)|(1<<ADPS2)|(1<<ADPS0);


while (1)
{
ADMUX=PINC3;
ADCSR|=(1<<ADSC);
while (bit_is_set(ADCSR, ADSC))
;

ZW=ADCW;
ZW=ZW*0.0044921;



dtostrf (ZW,3,3,wert_str);

lcd_on();
lcd_goto(1,1);
lcd_write_s (wert_str);
lcd_write_s (" Volt       ");



ADMUX=PINC0;
ADCSR|=(1<<ADSC);
while (bit_is_set(ADCSR, ADSC))
;

ZW=ADCW;
ZW=ZW*0.0044921;



dtostrf (ZW,3,3,wert_str);

lcd_on();
lcd_goto(2,1);
lcd_write_s (wert_str);
lcd_write_s (" Volt       ");

}
}

von holger (Gast)


Lesenswert?

>Wäre das dann so richtig:
>ADMUX=(1<<REFS0);

Ja.

>ADMUX=PINC3;
>ADMUX=PINC0;

Mit den beiden Zeilen löschst du REFS0 wieder.

von Stefan W. (bububaer)


Lesenswert?

Heißt das, ich muss das in dieser Reihenfolge schreiben:


ADMUX=PINC3;
ADMUX=(1<<REFS0);

....


ADMUX=PINC0;
ADMUX=(1<<REFS0);

von Karl H. (kbuchegg)


Lesenswert?

Stefan W. schrieb:
> Heißt das, ich muss das in dieser Reihenfolge schreiben:
>
>
> ADMUX=PINC3;
> ADMUX=(1<<REFS0);

Dann löscht du die Pin Auswahl wieder

ADMUX = (1<<RFS0) | PINC3;

So wie man eben mehrere Bits in einem Register setzt.

von Stefan W. (bububaer)


Lesenswert?

Oh Mann, ich muss noch richtig viel lernen...

Danke. Jetzt hab ich das mal so reingeschrieben wie Karl-Heinz 
geschrieben hat. Beim Compilieren bekomme ich dann aber eine 
Fehlermeldung:

ain.c:32: error: 'RFS0' undeclared (first use in this function)


Wo liegt jetzt das neue Problem??


Viele Grüße
Bubu

von Florian L. (muut) Benutzerseite


Lesenswert?

E vergessen?
RFS0 -> REFS0

von Chris (Gast)


Lesenswert?

Das es REFS0 heißt und nicht RFS0.

Da fehlt ein E ;)

von Stefan W. (bububaer)


Lesenswert?

Wie peinlich, hätte mir eigentlich auffallen können :-) Vielen Dank für 
eure Hilfe. Bis hierhin sind mal meine Probleme gelöst. Wird aber 
sicherlich nicht mein letztes Problem sein :-)

Ein schönes Wochenende
Bubu

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.