Variable auf LCD ausgeben

Gast #4174723
Mahlzeit!

da ich nun langsam echt am Ende mit meinem Latein bin, dachte ich, ich 
frage mal euch.

µC ist ein PIC16f887

Zur Problemstellung:
Ich lese Temperaturwerte (per AD Wandler) ein und möchte diese Werte 
dann umgerechnet auf einem Display als aktuelle Temperatur ausgeben.

So weit so gut:
Nur funktioniert das ganze nicht...

hier mal der C-Code, vielleicht könnt ihr ja was mit anfangen...
1
 Temp1 = AN0;
2
 Temp1 = Temp1 / 2 -17;             
3
              
4
                
5
                lcd_clear();
6
                lcd_cursor_home();
7
                lcd_puts("Temp Spule 1");
8
                lcd_cursor_home_l2();
9
                itoa( Temp1, buffer, 10);
10
                lcd_puts(buffer);

der HitechC Compiler meckert außerdem 2 mal in der itoa Zeile...

main.c:466 warning: illegal conversion of integer to pointer
main.c:466 warning: illegal conversion of pointer to integer

was ist da das konkrete Problem?
Detocs schrieb:

> was ist da das konkrete Problem?

wie ist den buffer definiert?


Bitte akzeptiere, dass die Datentypen der beteiligten Variablen immer 
mit dazu gehören! Die sind wichtig und öfter als einem lieb ist Teil des 
Problems.

buffer muss in deinem Fall ein char-Array sein
1
  char buffer[10];

die Fehlermeldungen deuten darauf hin, dass es das nicht ist.
Gast
hier sind die Definitionen dazu, hätte ich evenutell gleich dazu tun 
sollen^^

char buffer[7];
int Temp1;

ich vermute auch, dass da irgendwo das Problem liegt, komme allerdings 
nicht dahinter, was es genau ist..

Den buffer habe ich schon mit etlichen Werten definiert gehabt...
Detocs schrieb:
> hier sind die Definitionen dazu, hätte ich evenutell gleich dazu tun
> sollen^^
>
> char buffer[7];
> int Temp1;
>
> ich vermute auch, dass da irgendwo das Problem liegt, komme allerdings
> nicht dahinter, was es genau ist..

OK.
Zeig den ganzen Code.
Deine Fehlermeldungen passen nicht zum geistigen Bild, das ich mir 
gemacht habe. Jetzt ist meine Glaskugel, die die häufigsten Fehler 
kennt, am Ende ihres Lateins angelangt.
Gast
hier mal der Teil des Codes, den es betrifft :

der Spaß in den definitions:
1
 
2

3
char buffer[7];
4
int Temp1;

den Displaybefehl:
1
void lcd_write(unsigned char Zeichen)
2
{ 
3
    lcd_busy();
4
    LCD_Port = 0;
5
    LCD_RS = 1;
6
  LCD_Port = LCD_Port | (0x0F & (Zeichen >> 4)); 
7
  LCD_STROBE;
8
  LCD_Port = 0;
9
    LCD_RS = 1;
10
    LCD_Port = LCD_Port | (0x0F & Zeichen);      
11
  LCD_STROBE;
12
    LCD_RS = 0;
13
}
14

15
// Schreibe ein String auf die LCD
16
void lcd_puts(const char * s)
17
{
18
  while(*s)
19
    lcd_write(*s++);
20
}

und wie oben schon der Schreibbefehl für das Display:
1
 Temp1 = AN0;
2
 Temp1 = Temp1 / 2 -17;             
3
              
4
                
5
                lcd_clear();
6
                lcd_cursor_home();
7
                lcd_puts("Temp Spule 1");
8
                lcd_cursor_home_l2();
9
                itoa( Temp1, buffer, 10);
10
                lcd_puts(buffer);

der Fehler geht mir so langsam mächtig auf den Geist... das komplette 
Programm funktioniert...
bis auf genau die Ausgabe der Variablen....
Detocs schrieb:
> hier mal der Teil des Codes, den es betrifft :

OK. wenn du nicht willst, dann schränk ich eben das Problem ein.

Mach dir eine Funktion
1
void lcd_puti( int wert )
2
{
3
  char buffer[10];
4

5
  itoa( wert, buffer, 10 );
6
  lcd_puts( buffer );
7
}
und ruf sie auf
1
>                 lcd_clear();
2
>                 lcd_cursor_home();
3
>                 lcd_puts("Temp Spule 1");
4
>                 lcd_cursor_home_l2();
5

6
                  lcd_puti( Temp1 );
7

8
> 
9
>

Irgendwelche Fehlermeldungen im Zusammenhang mit der Funktion?
Gast
jede lcd-Bibliothek hat eine Funktion zum Anzeigen von Integern, 
sinnvollerweise ohne itoa, weil diverser Überbau nicht gebraucht wird. 
Nimm so eine "lcd_int-Funktion" oder schreib sie dir selbst.
Im übrigen schätze ich, wirst du auf Dauer mit itoa alleine nicht 
besonders glücklich werden. Spätestens wenn du das erste mal eine 
Anzeige von 90 auf dem LCD siehst (im Herbst, wenn es wieder kühler 
wird, wird es dann soweit sein), wirst du dich fragen, wie das zustande 
kommt.
grundschüler schrieb:
> jede lcd-Bibliothek hat eine Funktion zum Anzeigen von Integern,
> sinnvollerweise ohne itoa, weil diverser Überbau nicht gebraucht wird.

itoa hat keinen bzw. kaum Überbau.
Was du meinst ist sprintf. Wenn man den Speicher hat, spricht nichts 
dagegen sprintf zu benutzen, zumal man die Formatiermöglichkeiten gut 
nutzen kann.
Gast
jap, sind genau dieselben...

main.c:309 warning: non-prototyped function declaration for "lcd_puti"
main.c:312 warning: illegal conversion of integer to pointer
main.c:312 warning: illegal conversion of pointer to integer

bloß eben jetzt an der Stelle an der das Unterprogramm steht..
Bei PIC gibts doch diesen Sonderfall, dass der (einige?) Compiler 
'const' anders interpretieren.
(irgendsowas in der Richtung: automatische Unterscheidung SRAM-Flash)
1
lcd_putsv( char* s)
2
{
3
  while(*s)
4
    lcd_write(*s++);
5
}
6

7
void lcd_puti( int wert )
8
{
9
  char buffer[10];
10

11
  itoa( wert, buffer, 10 );
12
  lcd_putsv( buffer );
13
}
Gast
die Displayroutine habe ich übernommen, die hat sonst auch immer 
funktioniert... nur eben jetzt funkt mir was dazwischen...

so langsam glaube ich, ich komme um eine neue lcd-routine und bibliothek 
nicht herum...
Gast
ich merke gerade, das Problem scheint doch mehr zu betreffen als 
vermutet...
1
void Anzeige_Display(void)
2
{
3
    switch(Display)
4
    {
5
        case 0: Temp1 = AN0 / 2 -17;                                
6
                itoa( Temp1, buffer, 10);
7
                lcd_clear();
8
                lcd_cursor_home();
9
                lcd_puts("Temp Spule 1");
10
                lcd_cursor_home_l2();
11
                lcd_puts(Temp1);
12
                break;  
13

14
        case 1: Temp2 = AN1 / 2 -17;
15
                itoa( Temp2, buffer, 10);
16
                lcd_clear();
17
                lcd_cursor_home();
18
                lcd_puts("Temp Spule 2");
19
                lcd_cursor_home_l2();
20
                lcd_puts(buffer);
21
                break;
22

23
        case 2: Temp3 = AN2 / 2 -17;
24
                itoa( Temp3, buffer, 10);
25
                lcd_clear();
26
                lcd_cursor_home();
27
                lcd_puts("Temp Spule 3");
28
                lcd_cursor_home_l2();
29
                lcd_puts(buffer);
30
                break;
31

32
        case 3: Temp4 = AN3 / 2 -17;
33
                itoa( Temp4, buffer, 10);
34
                lcd_clear();
35
                lcd_cursor_home();
36
                lcd_puts("Temp Spule 4");
37
                lcd_cursor_home_l2();
38
                lcd_puts(buffer);
39
                break;
40

41
        case 4: Temp5 = AN4 / 2 -17;
42
                itoa( Temp5, buffer, 10);
43
                lcd_clear();
44
                lcd_cursor_home();
45
                lcd_puts("Temp Kuehler 1");
46
                lcd_cursor_home_l2();
47
                lcd_puts(buffer);
48
                break;
49

50
        case 5: Temp6 =AN5 / 2 -17;
51
                itoa( Temp6, buffer, 10);
52
                lcd_clear();
53
                lcd_cursor_home();
54
                lcd_puts("Temp Kuehler 2");
55
                lcd_cursor_home_l2();
56
                lcd_puts(buffer);
57
                break;
58

59
        case 6: Temp7 = AN6 / 2 -17;
60
                itoa( Temp7, buffer, 10);
61
                lcd_clear();
62
                lcd_cursor_home();
63
                lcd_puts("Temp Gehaeuse");
64
                lcd_cursor_home_l2();
65
                lcd_puts(buffer);
66
                break;
67
    }
68
}

was nun äußerst Interessant ist, dass im case0, der im moment noch 
peripherietechnisch der einzig mögliche ist, das Display auf der 2. 
Zeile jetzt "Temp Kuehler 2" ausgibt in Laufschrift, in Abhängigkeit von 
AN0... :D
wird echt immer geiler :D
Detocs schrieb:

> so langsam glaube ich, ich komme um eine neue lcd-routine und bibliothek
> nicht herum...

Das Problem zu verstehen und zu wissen wie und warum es entsteht ist die 
bei weitem bessere Lösung. Probleme, die man vor sich herschiebt warten 
nur darauf erneut zuzuschlagen. Dann aber, wenn man es am wenigsten 
brauchen kann.
Das hier
1
                lcd_puts("Temp Spule 1");
2
                lcd_cursor_home_l2();
3
                lcd_puts(Temp1);

kann allerdings nicht richtig sein.
lcd_puts kann nicht gleichzeitig dafür zuständig sein einen String 
auszugeben und einen Integer.
Mehr Sorgfalt!
Und warum sträubst du dich schon wieder dagegen, die ganzen Teil "Gib 
einen Integer aus" in eine eigene Funktion zu verbannen.

Dann hättest du das 'Problem' an einer einzigen Stelle konzentriert 
anstatt quer über das halbe Programm verstreut.

Mal ganz abgesehen, dass es mir viel zu blöd wäre, 3 Millionen mal im 
Code immer wieder itao .. lcd_puts zu schreiben.

Du musst weg von der Copy&Paste Programmierung. Eine int-Variable 
auszugeben ist eine Standardanwendung. Wenn deine lcd Funktionen keine 
entsprechende Funktion bereit halten, dann schreib dir eine! Es ist 
nicht verboten, aufbauend auf dem, was man vorgesetzt bekommen hat, sich 
weitere Hilfsfunktionen zu schreiben.
Gast
1
void Anzeige_Display(void)
2
{
3
    switch(Display)
4
    {
5
...

Der einzige Unterschied in deinen cases ist die Ausgabe eines Strings.
Du könntest die Cases alle weglassen. Besonders solange du den Fehler 
noch nicht gefunden hast.
Dann später ersetzt du das
1
  lcd_puts("Temp Kuehler ...");
einfach durch ein
1
  lcd_puts( DisplayName[Display] );
Matthias Lipinsky schrieb:

> Der einzige Unterschied in deinen cases ist die Ausgabe eines Strings.

Fast.
Er geht auch jeweils auf eine andere ANx Variable (Analog Input?)

Aber wie auch immer. Ich geh mit dir konform, dass die Funktion viel zu 
lang und viel zu unübersichtlich ist. Die vielen globalen Variablen sind 
auch nicht gerade ideal. Zumal sie in der jetzigen Form bis auf 2 
unnötig sind. Es wird ja sowieso nur ein einziger case Fall genommen. 
Daher braucht es nicht in jedem case eine eigene Variable, die das 
Rechenergebnis aufnimmt.
1
void Anzeige_Display(void)
2
{
3
    int Wert = -99;
4

5
    lcd_clear();
6
    lcd_cursor_home();
7

8
    switch(Display)
9
    {
10
        case 0: Wert = AN0 / 2 -17;                  
11
                lcd_puts("Temp Spule 1");
12
                break;  
13

14
        case 1: Wert = AN1 / 2 -17;
15
                lcd_puts("Temp Spule 2");
16
                break;
17

18
        case 2: Wert = AN2 / 2 -17;
19
                lcd_puts("Temp Spule 3");
20
                break;
21

22
        case 3: Wert = AN3 / 2 -17;
23
                lcd_puts("Temp Spule 4");
24
                break;
25

26
        case 4: Wert = AN4 / 2 -17;
27
                lcd_puts("Temp Kuehler 1");
28
                break;
29

30
        case 5: Wert =AN5 / 2 -17;
31
                lcd_puts("Temp Kuehler 2");
32
                break;
33

34
        case 6: Wert = AN6 / 2 -17;
35
                lcd_puts("Temp Gehaeuse");
36
                break;
37
    }
38

39
    lcd_cursor_home_l2();
40
    lcd_puti( Wert );
41
}
Gast
>Er geht auch jeweils auf eine andere ANx Variable (Analog Input?)

Das hatte ich übersehen. Auch das könntest Du in ein Array packen. Ich 
würde eine Struktur anlegen, in der der Name ( zB "Temp Spule X" und der 
Analogeingang steht), diese Struktur als Array anlegen.

Aber zuerst sollten deine Displayroutinen korrekt laufen, bevor Du den 
Rest baust. Du musst immer daran denken, eine Software hat eine 
Struktur. Sie besteht (vereinfacht) gesagt, aus einem Hauptteil. Das ist 
bei Dir das Einlesen der ANx und Berechnen und Ausgeben der 
Temperaturen. Der Hilfsteil ist das Ausgeben aufs LCD selbst. Ich fange 
immer an, solche Hilfsfunktionen zuerst zu schreiben und zu testen. 
Solange diese nicht zuverlässig sind, ist es nicht klug den Überbau 
voranzutreiben. Oder baust Du beim Hausbau am Dachwerk, wenn das 
Fundament noch nicht fertig ist?
Gast
ich weiß es sieht beknackt aus, aber:
so bescheuert es auch klingt, es soll gerade so kompliziert aussehen....

es ist ein olles Schulprojekt, und zu meinem Glück hat der korregierende 
Lehrer nicht gerade viel Ahnung von C...
also je "aufwändiger", desto besser nachher für mich..

das Hauptproblem an dem Spaß ist, das ganze geht aus meinen momentanen 
Fähigkeiten heraus...
Gast
Detocs schrieb:
> es ist ein olles Schulprojekt, und zu meinem Glück hat der korregierende
> Lehrer nicht gerade viel Ahnung von C...
> also je "aufwändiger", desto besser nachher für mich..
Dann würde ich am besten ganz viel mit pointer und pointer auf pointer 
arbeiten. Das mit dem struct array sieht IMHO auch so aus als ob du 
Ahnung hättest.
Detocs schrieb:
> hat jemand eine gute Display-routine, die eventuell so etwas schon kann?

Die was schon kann?

Hast du beim itoa den ersten und zweiten Parameter getauscht?
Die Fehlermeldungen würden zu diesem abweichenden itoa passen.

wenn ein übliches itoa die Parameter so hat
1
char* itoa( int value, char * txt, ...
deines aber so definiert ist
1
char* itoa( char * txt, int value, ...
ja, dann sind 2 Fehler zu erwarten. Bei einem Aufruf ala
1
   int wert;
2
   char buffer[10];
3
   itoa( wert, buffer, ... );
hast du als erstes Argument einen int, wo ein Pointer erwartet wird und 
als zweites Argument im Aufruf einen Pointer wo ein int erwartet wird. 
Und genau das sind ja auch deine Fehlermeldungen.

Im übrigen wurde weiter oben auch ein Link zu einem Beitrag gepostet, in 
dessen Zug ich eine eigene myItoa angeboten habe. Nichts aufregendes.
Gast
getauscht habe ich den Spaß, sodass es jetzt richtig drin steht.

Fehlermeldungen sind weg, allerdings funktioniert es trotzdem nicht..

auf der zweiten Zeile, wo eigentlich die umgerechneten Analogwerte 
stehen sollten, steht wieder "Temp Peltier 2" und "Temp Gehaeuse" 
abhängig davon, welchen Wert AN0 im Moment hat...

Verwundert mich, macht für mich auch irgendwie keinen Sinn
Gast
1
void std_lcd_int(int32_t dat){
2
if (dat==0){std_lcd_putchar(0+48);}else{
3
u8 i,l=1;
4
u32 tl=1;
5
while((dat/tl)>0){
6
tl=tl*10;l++;
7
}
8
 tl=tl/10;
9

10
 for( i=l-2;i!=255;i--) {
11
 std_lcd_putchar((dat)/tl+48);
12
 dat=dat%tl;
13
 tl=tl/10;
14
}}}/**/

Standardfunktion ohne itoa, müsste immer passen
Gast
du definierst

#define std_lcd_putchar lcd_puts
#define u8 uint8_t
#define u32 uint32_t

damit die Funktion dein lcd_char findet und die abkürzungen erkennt, 
dann zeigt das Lcd dir mit der Funktion std_lcd_int()  den Integerwert 
an.

das kürzt man sinnvoll ab:
#define lcd_int std_lcd_int
oder ganz kurz:
#define li std_lcd_int

dann ersetzt li(Temp1) =>

              itoa( Temp1, buffer, 10);
                lcd_puts(buffer);

Die Funktion stellt zuerst fest, wie lang der Integer-Wert ist, zerlegt 
ihn dann in einzelne Ziffern und zeigt die Ziffern als Character an. Im 
Prinzip das , was itoa auch macht.
Detocs schrieb:
> und wo und wie setz ich das ein? :D
>
> sorry für die vielleicht blöde frage, wie gesagt, das geht aus meinem
> Wissensbereich raus

Die Funktion übernimmt einen int (diesmal als 32 Bit int) und bestimmt 
die einzelnen Ziffern, die sie dann sukzessive mittels einer 
angenommenen FUnktion lcd_putchar ausgibt.

Wenn die Funktion mal ordentlich formatieren würde
1
void std_lcd_int(int32_t dat)
2
{
3
  if ( dat == 0 )
4
    std_lcd_putchar( '0' );
5

6
  else {
7
    u8 i,l=1;
8
    u32 tl=1;
9

10
    // erster Teil: Bestimmung der 'Groessenordung' der Zahl
11
    while( (dat/tl) > 0 )
12
    {
13
      tl = tl * 10;
14
      l++;
15
    }
16
    tl = tl / 10;
17

18
    // zweiter Teil: Ausgabe der Ziffern
19
    for( i = l-2; i !=255; i-- )
20
    {
21
      std_lcd_putchar( dat / tl + '0' );
22
      dat = dat % tl;
23
      tl = tl / 10;
24
    }
25
  }
26
}

dann könnte man auch erkennen wie sie funktioniert.
Der erste Teil bestimmte den in der Zahl maximal vorkommenden "10-er 
Teiler".
Bei der Zahl 2563 wäre das zb 1000, weil in der Zahl keine größere 
Stelle als Tausender vorkommt.
Der zweite Teil zerlegt dann die Zahl entsprechend mit dem Teiler, der 
in jedem SChritt entsprechend kleiner wird.
2563 / 1000 ergibt 2, was soviel bedeutet wie: in 2563 sind genau 2 
Tausender enthalten. Also wird eine '2' an das Display ausgegeben. 
Danach werden die 2 Tausender von der Zahl 'abgezogen' (mit der modulo 
Operation). Aus 2563 wird 563, der Teiler auf 1/10 verkleinert, aus 1000 
wird 100 und die ganze OPeration wiederholt mit der Fragestellung: 
wieviele Hunderter sind in 563 enthalten.

Alles in allem ist das m.M.n etwas geschwätzig formuliert. Ich hätte mir 
da eine ganz normale myItoA nach dem Vorbild in dem verlinkten Beitrag 
gemacht:
1
void myUtoa( unsigned int num, char* str )
2
{
3
  unsigned char i;
4

5
  for( i = 0; i < 5; ++i )
6
  {
7
    str[4-i] = ( num % 10 ) + '0';
8
    num = num / 10;
9
  }
10
  str[5] = '\0';
11
}

ähnliche Idee, nur dass die Zerlegung sukzessive erfolgt
1
213 % 10   ->        3   Einerstelle
2
213 / 10   -> 21
3

4
21 % 10    ->        1   Zehnerstelle
5
21 / 10    -> 2
6

7
2 % 10     ->        2   Hunderterstelle
8
2 / 10     -> 0 (daher wissen wir, das alles abgearbeitet wurde)

die Beschränkung, dass diese Funktion auch führende 0-en mit abbildet 
ist nicht unbedingt wesentlich und lässt sich auch leicht ausbauen.
Detocs schrieb:
> ich weiß es sieht beknackt aus, aber:
> so bescheuert es auch klingt, es soll gerade so kompliziert aussehen..

Detocs schrieb:
> und wo und wie setz ich das ein? :D
>
> sorry für die vielleicht blöde frage, wie gesagt, das geht aus meinem
> Wissensbereich raus

Das ist Dir wohl nicht kompliziert genug? Befehle, deren Parameter mal 
so und mal so angegeben werden müssen -das ist doch traumhaft...

SCNR
Paul
grundschüler schrieb:
> du definierst
>
> #define std_lcd_putchar lcd_puts
> #define u8 uint8_t
> #define u32 uint32_t
>
> damit die Funktion dein lcd_char findet und die abkürzungen erkennt,
> dann zeigt das Lcd dir mit der Funktion std_lcd_int()  den Integerwert
> an.
>
> das kürzt man sinnvoll ab:
> #define lcd_int std_lcd_int
> oder ganz kurz:
> #define li std_lcd_int
>
> dann ersetzt li(Temp1) =>
>
>               itoa( Temp1, buffer, 10);
>                 lcd_puts(buffer);


nein. Sorry.
Aber so macht man das nicht.

Man schreibt sich die Funktion so um (nachdem man sie erst mal 
ordentlich formatiert hat), dass sie in den Fundus der bereits 
vorhandenen Funktionen passt.

Soviel Zeit muss schon sein, dass man seinen Vorrat an Basisfunktionen 
ordentlich pflegt, einsatzbereit hält und derartiges Flickwerk erst gar 
nicht aufkommen lässt.
Woher kommt eigentlich diese Unsitte mit -1 zu multiplizieren? Gut ich 
geh davon aus, dass der Compiler das schon wieder wegoptimieren wird - 
aber was ist an
1
    Zahl = -Zahl;
so verwerflich? Es drueckt genau aus, was man will. Das unäre Minus ist 
genau die Operation, die in C das negative eines Ausdrucks liefert. Es 
ist genau die Operation, die aus einer 1 eine -1 macht.
Gast
die Funktionsweise des Codes von grundschüler ist mir schon klar,
mir geht es nur um die Umsetzung in C..

das was er mir geschrieben hat funktioniert nämlich leider nicht...
der Compiler kann nichts mit i und l anfangen.. und er erwartet 
irgendwie einen Semikolon in der Zeile mit u8 i,l = 1;

nur doof, dass da schon einer ist...

so langsam dreh ich noch durch mit dem Schrott...
Gast
Problem:
main.c:466 warning: illegal conversion of integer to pointer
main.c:466 warning: illegal conversion of pointer to integer

Aufgetretene Stelle:
itoa( Temp1, buffer, 10);

Lösungshilfe:
char *  itoa ( int value, char * str, int base );

Lösung:
Vertauschte Argumente 1 & 2.

Interessant wie viel um den heißen Brei herum geredet werden kann.
Gast
Detocs schrieb:
> die Funktionsweise des Codes von grundschüler ist mir schon klar,
> mir geht es nur um die Umsetzung in C..
Das IST C, du brauchst weiter oben nur:
1
typedef uint8_t u8
2
typedef uint32_t u32
und die std_lcd_putchar()heißt bei dir vllt. anders.
Gast
Dennis:
das habe ich gestern bereits getan, hat auch nichts geändert...


ptr:

das lcd_put_char() hatte ich bereits geändert..
mit typedef kann der Compiler auch nichts anfangen.. er erkennt dann u8 
und u32 nicht mehr.
Gast
Und sollte dein Compiler typedef wirklich nicht kennen, kannst du auch
1
#define u8 uint8_t
2
#define u32 uint32_t
verwenden oder einfach das u8 bzw. u32 im Quellcode durch uint8_t bzw. 
uint32_t ersetzten.

Noch was: <stdint.h> includiert?
Moderator Persönliche Seite
Karl Heinz schrieb:
> Woher kommt eigentlich diese Unsitte mit -1 zu multiplizieren?

grundschüler wirft immer gern unleserlichen, verkomplizierenden (und 
nicht funktionierenden) Code in diverse Threads, um die Leser zu 
verwirren und den TO gezielt zu verunsichern und auf komplett falsche 
Pfade zu führen.

Allein das:

  #define std_lcd_putchar lcd_puts

ist eine Nebelbombe, mit denen er den TO stundenlang schier zur 
Verzweiflung bringen kann. Ersteres erwartet ein Zeichen, letzteres 
einen String. Bis der TO gerafft hat, dass es so gar nicht läuft und es 
gar nicht an ihm liegt, können schon mal ein paar Tage vergehen.

@rundschüler: Warum machst Du sowas immer und immer wieder? Wieviele 
Leute sollen Dir hinterherlaufen, um Deinen Code auseinanderzunehmen, um 
ihn dann schlussendlich als disfunktional zu entlarven?
Detocs schrieb:
> die Funktionsweise des Codes von grundschüler ist mir schon klar,
> mir geht es nur um die Umsetzung in C..
>
> das was er mir geschrieben hat funktioniert nämlich leider nicht...

Wenn dir die Funktionsweise klar ist, dann schreib ihn neu! So toll ist 
der von grundschüler gelieferte Code dann auch wieder nicht.
Und wenn du ihn quasi in deinen eigenen Worten noch mal neu schreiben 
würdest, würdest du dabei sogar noch was lernen.

Im übrigen hab ich dir ja auch eine Funktion als Ersatz für dein 
scheinbar seltsames itoa geliefert. Was ist denn an der schon wieder 
falsch?
Warum kann man die nicht verwenden um daraus dann einfach eine Funktion
1
void lcd_puti( int wert )
2
{
3
  char tmp[5];
4

5
  myUtoa( wert, tmp );
6
  lcd_puts( tmp );
7
}
zu bauen?
Ist dir das zu einfach? Zu wenig komplex? zu wenig kryptisch für deinen 
Lehrer? Ist es zu schwer für dich, die signed/unsigned Mismatches zu 
beseitigen? Oder was stimmt daran nicht?
Oder was stimmt an der etwas umfangreicheren Funktion aus der FAQ nicht, 
die die Rolle von itoa fast komplett übernehmen kann?

Noch ein kleiner Tip:
Wenn du so einen Code siehst, der so aussieht wie der von grundschüler, 
dann mach einen Bogen drumrum. Der sieht zwar wahnsinnig geheimnisvoll 
und kryptisch aus .. ist aber in 90% aller Fälle ganz einfach nur Mist.
Gast
das Problem war/ ist, soweit bin ich in C nicht eingearbeitet...woher 
auch wenn mans fast nur in der Schule macht bzw. braucht....

es funktioniert jetzt übrigens, habe das myUtoa genommen und passend 
umgestrickt...

Vielen Dank für eure schnelle Hilfe :)
hat mir den Arsch gerettet :P
Detocs schrieb:
> wäre zwar eigenartig, wenn es in der Firma plötzlich diese Temperaturen
> annehmen würde, ich werde es aber im Hinterkopf behalten ;D

Nein, nicht im Hinterkopf behalten.

die lcd_puti Funktion gehört zu den LCD Funktionen. Die schreibt man 
sich einmal (so wie du eine lcd_puts Funktion hast) und dann kommt sie 
zu den lcd Funktionen mit dazu, damit du sie verfügbar hast, wenn du sie 
das nächste mal brauchst.
Und selbstverständlich muss eine Funktion, die für sich den Anspruch hat 
einen Integer ausgeben zu können auch mit negativen Zahlen umgehen 
können. Egal ob die jetzt in deinem konkreten Projekt vorkommen werden 
oder nicht.

Gewöhn dich daran, dass in deinen ersten Projekten immer wieder mal 
Funktionen als 'Abfallprodukt' anfallen werden, die das Zeug haben aus 
dem Status 'projektspezifisch' herauszufallen und die man sich auf einem 
Common-Verzeichnis sammelt, weil sie immer wieder mal gebraucht werden. 
So wie zum Beispiel Funktion für die LCD Ausgabe.
Du baust dir selbst und du erweiterst dir selbst deinen Baukasten, aus 
dem du auch in Zukunft immer wieder fertige (Teil-)Lösungen abrufen 
kannst. Jeder Programmierer hat auf seinem Rechner ein Verzeichnis, auf 
dem solche Funktionen gesammelt werden. Programmierer sind faul. Wir 
erfinden das Rad nicht neu, wenn wir es schon einmal erfunden haben. Die 
Kunst besteht darin, zu entscheiden welche 'Erfindungen' die Bedeutung 
des Rades haben und welche in einem konkreten Projekt nur Mittel zum 
Zweck sind, die aber ausserhalb des Projekts nicht besonders interessant 
sind. Integer nach STring wandeln bzw. Integer irgendwo ausgeben hat 
definitiv den Stellwert eines Rades.



Abgesehen davon, soll es schon mal vorgekommen sein, dass ein Gerät auch 
mal nach draussen gebracht wird und das auch noch im Winter. Das wirft 
dann kein besonders gutes Licht auf die Fähigkeiten des Programmierers, 
wenn die Anzeige dann bei Schneefall behauptet es hätte 8°C. Das fällt 
in etwa in die Kategorie der Setup Programme, die behaupten sie hätten 
schon 138% von 4 Gigabyte kopiert. Natürlich ist das kein Beinbruch, 
aber ich denk mir dann  meinen Teil dabei.
Moderator Persönliche Seite
Detocs schrieb:
> wäre zwar eigenartig, wenn es in der Firma plötzlich diese Temperaturen
> annehmen würde, ich werde es aber im Hinterkopf behalten ;D

Es geht jetzt nicht um die konkrete Anwendung, sondern um 
Wiederverwendbarkeit von Code. Wenn Du in 2 Jahren eine neue Aufgabe zu 
bewätigen hast und Du Dir denkst: "Das habe ich doch schon mal in der 
Vergangenheit programmiert? Das nehme ich als Vorlage!", dann könnte das 
in die Hose gehen... nur weil Du damals nicht daran gedacht hast, 
negative Zahlen zu berücksichtigen. Da gehts nicht nur um die Behandlung 
des Vorzeichens an sich, sondern dann auch um Buffergrößen, die alle um 
ein weiteres Zeichen (dann sind wir z.B. bei 7 für tmp[]) erweitert 
werden müssen.

Daher auch mein Einwurf bzgl. uint16_t auf einem 32-Bit-µC.... denn wer 
weiß, für welchen µC Du in ein paar Jahren Deine neue Aufgabe 
programmieren wirst?

Okayokay, man kann es auch übertreiben. Aber es gibt ein paar (kleinere) 
Dinge, die man schon berücksichtigen sollte. Diese machen einem später 
das Leben wesentlich bequemer.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 11 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.