Problem bei LCD-Ausgabe

OP #1734253
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);
}
}
Gast #1734261
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);
...
OP #1734279
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);

}
}
#1734281
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.
#1734480
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
OP #1734506
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
#1734521
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.
OP #1736184
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       ");

}
}
OP #1736492
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

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