Forum: Mikrocontroller und Digitale Elektronik ATmega8: ADC-Wert auf Display ausgeben klappt nicht


von Steffen O. (derelektroniker) Benutzerseite


Lesenswert?

Hallo,
ich will den ADC- Wert eines ATmega8 (1Mhz) auf einem Display ausgeben. 
Das Diplay ist ein Standard-Display mit HD44780 kompatibeln Controller. 
Die lib dazu ist hier aus dem Wiki (.h- Datei: 
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#LCD-Ansteuerung) 
und (.c- Datei: 
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#LCD-Ansteuerung).
Das Diplay ist meines Wissens richtig angeschlossen, und funktioniert 
auch (Text ausgeben, usw. klappt). Nun wollte ich eben den ADC Wert auf 
dem Display ausgeben, dazu hab ich folgendes Programm geschrieben:
1
#include<avr/io.h>
2
#include"lcd-routines.h"
3
#define F_CPU 1000000
4
#include <util/delay.h>
5
6
int main(void)
7
{
8
lcd_init();
9
set_cursor(3,1);
10
lcd_string("ADC1 Wert:");
11
int adcwert;
12
13
ADMUX |= (0<<REFS1) | (1<<REFS0);   //VCC als Referenz
14
ADCSRA = (0<<ADPS2) | (1<<ADPS1) | (1<< ADPS0);  //Frequenzvorteiler auf 8
15
ADMUX |= (1<<MUX0);  // Kanal 1 waehlen
16
17
//Dummy Readyout
18
ADCSRA |= (1<<ADSC);        
19
while (ADCSRA & (1<<ADSC) ) {
20
      ;
21
    }
22
adcwert = ADCW;
23
24
//Richtiges Readout
25
while (1) {
26
27
ADCSRA |= (1<<ADSC);
28
while (ADCSRA & (1<<ADSC) ) {
29
      ;
30
    }
31
adcwert = ADCW;
32
33
//Ergebnis auf Display darstellen
34
set_cursor(6,2);
35
lcd_data(adcwert);
36
_delay_ms(500);
37
}
38
}

Die Datei lcd-routines.c hab ich unter source files hinzugefügt.
Nun hab ich also die .hex- Datei auf den Mega8 geflasht, und einfach mal 
den ADC1 Pin auf VCC gezogen. Nun erscheint aber auf dem Display nur in 
Zeile 1: ADC1 Wert: (wie es ja auch sein sollte), aber in Zeile 2, wo ja 
der aktuelle ADC Wert sein sollte, ist nur ein Zeichen (schwarzes 
Rechteck).

Wieso funktioniert das Programm nicht?
Kann ich mit lcd_data keine als Integer initialisierte Variablen 
ausgeben? Muss ich dafür lcd_string verwenden?

Vielen Dank schon einmal im Voraus.
Gruß, Steffen

von Falk B. (falk)


Lesenswert?

@  Steffen O. (derelektroniker)

>lcd_data(adcwert);

Das geht so einfach nicht in C. Du musst deinen ADC-Wert in einen 
ASCII-String umwandeln. Z.B. mit der Funktion itoa, siehe 
Festkommaarithmetik. Den kannst du dann ausgeben.

MfG
Falk

von Chris :. (fr34k)


Lesenswert?

adcwert = ADCW;

char buf[4];
itoa(adcwert,buf,10);
lcd_data(buf);

so müssts funktionieren ;)

von Chris :. (fr34k)


Lesenswert?

also genauso wies Falk oben schon beschrieben hat ;)

von Steffen O. (derelektroniker) Benutzerseite


Lesenswert?

Ich hab jetzt mal das von Chris noch eingefügt, aber nun erscheint in 
der zweiten Zeile nur ein S.
Mein Code sieht nun so aus:
1
//Fuer ATmega8 mit 1Mhz
2
3
#include<avr/io.h>
4
#include"lcd-routines.h"
5
#define F_CPU 1000000
6
#include <util/delay.h>
7
#include <stdint.h>
8
9
int main(void)
10
{
11
int adcwert;
12
char buf[5];
13
lcd_init();
14
set_cursor(3,1);
15
lcd_string("ADC1 Wert:");
16
17
18
ADMUX |= (0<<REFS1) | (1<<REFS0);   //VCC als Referenz
19
ADCSRA = (0<<ADPS2) | (1<<ADPS1) | (1<< ADPS0);  //Frequenzvorteiler auf 8
20
ADMUX |= (1<<MUX0);
21
//Dummy Readyout
22
ADCSRA |= (1<<ADSC);        
23
while (ADCSRA & (1<<ADSC) ) {
24
      ;
25
    }
26
    adcwert = ADCW;
27
28
//Richtiges Readout
29
while (1) 
30
{
31
ADCSRA |= (1<<ADSC);
32
while (ADCSRA & (1<<ADSC) ) {
33
      ;
34
    }
35
    adcwert = ADCW;
36
37
//Ergebnis auf Display darstellen
38
set_cursor(6,2);
39
itoa(adcwert,buf,10);
40
lcd_data(buf);
41
_delay_ms(500);
42
}
43
}

Woran liegt das nun?
Ach ja: Woher kommt die 10 in der Funktion "itoa"?

Vielen Dank schon einmal im Voraus.
Gruß, Steffen

von Falk B. (falk)


Lesenswert?

@ Steffen O. (derelektroniker)

>Ich hab jetzt mal das von Chris noch eingefügt, aber nun erscheint in
>der zweiten Zeile nur ein S.

S?
Ja klar, weil

>lcd_data(buf);

Diese Funktion gibt nur einzelne Zeichen aus, keine Strings. Das macht 
lcd_string() (Wer hätte DAS gedacht . . .  ;-)
Die Anweisung oben interpretiert buf als Zeichen. Dumm nur, das buf ein 
Pointer ist.

>Ach ja: Woher kommt die 10 in der Funktion "itoa"?

Das ist die Zahlenbasis. Man kann auch in Binär (2), Okal (8) und 
Hexadezimal (16) umwandeln, theoretisch auch in allen (un)möglichen 
anderen Zahlenbasen. Nonalzahlen? ;-)

MFG
Falk

von Chris :. (fr34k)


Lesenswert?

ich würd mich mal schlaumachen, ob deine lcd routine (die du 
möglicherweise nicht selber geschrieben hast) eventuell eine funktion 
wie "lcd_puts" => fleury lib oda sonst was beinhaltet ;)

von Steffen O. (derelektroniker) Benutzerseite


Lesenswert?

Hallo,

Falk Brunner wrote:
> @ Steffen O. (derelektroniker)
>
>>Ich hab jetzt mal das von Chris noch eingefügt, aber nun erscheint in
>>der zweiten Zeile nur ein S.
>
> S?
> Ja klar, weil
>
>>lcd_data(buf);

Ok, ich hab nun lcd_data durch lcd_string ersetzt, nun erscheint auf dem 
Display eine null.

> Diese Funktion gibt nur einzelne Zeichen aus, keine Strings. Das macht
> lcd_string() (Wer hätte DAS gedacht . . .  ;-)
> Die Anweisung oben interpretiert buf als Zeichen. Dumm nur, das buf ein
> Pointer ist.

Und wie bekomm ich diesen Pointer weg, oder änder ihn so um, dass das 
Display den Variableninhalt anzeigen kann?

>>Ach ja: Woher kommt die 10 in der Funktion "itoa"?
>
> Das ist die Zahlenbasis. Man kann auch in Binär (2), Okal (8) und
> Hexadezimal (16) umwandeln, theoretisch auch in allen (un)möglichen
> anderen Zahlenbasen. Nonalzahlen? ;-)

Danke der Aufklärung ;-).

Gruß, Steffen

von Steffen O. (derelektroniker) Benutzerseite


Lesenswert?

Vielen Dank erstmal für eure Antworten !!!(hab ich vorhin vergessen ;-))

Chris :) wrote:
> ich würd mich mal schlaumachen, ob deine lcd routine (die du
> möglicherweise nicht selber geschrieben hast) eventuell eine funktion
> wie "lcd_puts" => fleury lib oda sonst was beinhaltet ;)

Ich verwende die lib hier aus dem wiki, und die hat so weit ich weiß 
keine Funktion lcd_puts. Die Fleury lib könnte ich bei Gelegenheit mal 
ausprobieren.

Gruß, Steffen

von Falk B. (falk)


Lesenswert?

@ Steffen O. (derelektroniker)

>Ich verwende die lib hier aus dem wiki, und die hat so weit ich weiß
>keine Funktion lcd_puts.

Doch, die heisst nur lcd_data ;-)

>Ok, ich hab nun lcd_data durch lcd_string ersetzt, nun erscheint auf dem
>Display eine null.

Teste erstmal, ob die Ausgabe läuft. Weise mal adcwert direkt einen Wert 
zu. Wenn die Anzeige klappt dann stimmt mit deiner ADC-Auswertung was 
nicht.

MFG
Falk

von Steffen O. (derelektroniker) Benutzerseite


Lesenswert?

Ich habe es nun mal so gemacht:
1
adcwert=542;
2
itoa(adcwert,buf,10);
3
lcd_string(buf);

Und dann erscheint auf dem Display 542, also stimmt warsch. was mit der 
ADC-Routine nicht.
Aber ich hab doch alles so konfiguriert, wie es hier im wiki, bzw. im 
Datenblatt des ATmega8 steht, oder?

Vielen Dank schon einmal im Voraus.
Gruß, Steffen

von Steffen O. (derelektroniker) Benutzerseite


Lesenswert?

Kann es vielleicht daran liegen, dass es nicht funktioniert, weil ich 
die Spannungsversorgung (5V) des Mega8 an den ADC-Eingang gehängt habe? 
Dann sollte doch der ADC eigentlich den höchsten Wert anzeigen, den er 
kann.

Gruß, Steffen

von Falk B. (falk)


Lesenswert?

Versuchs mal bessser so.
1
ADMUX  = (0<<REFS1) | (1<<REFS0);   //VCC als Referenz
2
ADCSRA = (1<<ADEN) | (0<<ADPS2) | (1<<ADPS1) | (1<< ADPS0);  //Frequenzvorteiler auf 8
3
ADMUX |= (1<<MUX0);

MFG
Falk

von Steffen O. (derelektroniker) Benutzerseite


Lesenswert?

Vielen Dank für deine schnelle Hilfe, nun klappts.
Allerdings werden irgendwie ganz komische Werte angezeigt.
Wenn ich den ADC Eingang an VCC halte, werden erwartungsgemäß 1023 
angezeigt, und wenn ich ihn an GND halte, ca. 3.
Verbinde ich nun aber den ADC mit dem Schleifer eines 50k Potis, und die 
beiden anderen Kontakte des Potis jeweils mit VCC und GND, dann werden 
mir ganz komische Werte angezeigt, manchmal bis in die 7000-er gehend.
Woran liegt das? Sind 50K irgendwie zu hoch?

Gruß, Steffen

von MAX (Gast)


Lesenswert?

Hi,
Ich hab zur zeit das gleiche Problem....
wollte dich fragen ob du die Lösung gefunden hast...
Über eine Antwort würde ich mich freuen
bis dann

von Karl H. (kbuchegg)


Lesenswert?

Stell dir vor du hast ein magisches kariertes Papier.
Jedesmal wenn du eine Ziffer in ein Kästchen schreibst, verscheindet die 
bereits dort stehende Ziffer und die neue erscheint. Sonst passiert 
nichts. Insbesondere werden andere Kästchen nicht verändert, nur weil du 
in eines davon eine Ziffer schreibst.

Du schreibst da jetzt die Zahl 23 hin

      +---+---+---+---+---+---+
      | 2 | 3 |   |   |   |   |
      +---+---+---+---+---+---+

und jetzt schreibst du (wieder von vorne beginnend) die Zahl 1018 drüber

      +---+---+---+---+---+---+
      | 1 | 0 | 1 | 8 |   |   |
      +---+---+---+---+---+---+

nicht sonderlich aufregend. Aber jetzt schreibst du (wieder von vorne 
beginnend) die Zahl 234 drüber

      +---+---+---+---+---+---+
      | 2 | 3 | 4 | 8 |   |   |
      +---+---+---+---+---+---+

Hoppala. Was ist jetzt passiert. Auf deinem Papier steht 2348 und nicht 
234!
Warum?
Ganz klar, weil die 8 immer noch von den 1018 dort steht. 1018 hat 4 
Ziffern, 234 aber nur 3. Und damit ist die 8 von den 1018 nie 
überschrieben worden und täuscht dir eine Zahl vor, die du so nie 
ausgegeben hast.

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.