Forum: Mikrocontroller und Digitale Elektronik Variable auf LCD ausgeben


von Detocs (Gast)


Lesenswert?

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?

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

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.

: Bearbeitet durch User
von Detocs (Gast)


Lesenswert?

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...

von Karl H. (kbuchegg)


Lesenswert?

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.

: Bearbeitet durch User
von Detocs (Gast)


Lesenswert?

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....

von Karl H. (kbuchegg)


Lesenswert?

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?

: Bearbeitet durch User
von grundschüler (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

: Bearbeitet durch User
von Georg G. (df2au)


Lesenswert?

Welches ist die ominöse Zeile 466, die dein Compiler bemeckert?

Warum hast du lcd_puts mit "const" als Parameter definiert?

von Detocs (Gast)


Lesenswert?

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..

von Karl H. (kbuchegg)


Lesenswert?

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
}

: Bearbeitet durch User
von Detocs (Gast)


Lesenswert?

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...

von Georg G. (df2au)


Lesenswert?

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

Ganz schlechter Ansatz. Such den Fehler. Sonst spuckt er dir in der 
Zukunft immer mal wieder rein. Was ist mit der "const" Definition?

von Detocs (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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!

von Wolfgang L. (smarty9797)


Lesenswert?

HiTech hat bei itoa (und wahrscheinlich auch noch bei anderen 
Funktionen) die Reihenfolge der Parameter buf und val vertauscht.
Bei Hitech lautet die Definition für itoa:
char * itoa (char * buf, int val, int base)

Guckst Du hier:
http://forum.htsoft.com/all/showflat.php/Cat/0/Number/177472

Warum sie das gemacht haben? Wer kann das schon ahnen...

Gruß,
Wolfgang

von Karl H. (kbuchegg)


Lesenswert?

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.

von Dirk B. (dirkb2)


Lesenswert?

Detocs schrieb:
> main.c:312 warning: illegal conversion of integer to pointer
> main.c:312 warning: illegal conversion of pointer to integer

Wie sieht der Prototyp für dein itoa aus?

von Matthias L. (Gast)


Lesenswert?

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] );

von Karl H. (kbuchegg)


Lesenswert?

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
}

: Bearbeitet durch User
von M. K. (sylaina)


Lesenswert?

Ich würd mir mal die Definition von itoa anschaun, nicht dass buffer und 
value vertauscht sind.

: Bearbeitet durch User
von Matthias L. (Gast)


Lesenswert?

>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?

von Dirk B. (dirkb2)


Lesenswert?

Das itoa könnte (wie schon mehrfach befürchtet) nicht Standardkonform 
sein:
http://electronics.stackexchange.com/questions/65473/integer-to-ascii-in-c18

(Jaja, itoa ist nicht im ISO-Standard von C.)

Möglicherweise hilft auch diese Lösung:
Beitrag "Re: itoa in C18 Compiler will nicht so wie sie soll"

von Detocs (Gast)


Lesenswert?

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...

von *ptr (Gast)


Lesenswert?

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.

von Detocs (Gast)


Lesenswert?

hat jemand eine gute Display-routine, die eventuell so etwas schon kann?

Bei der vorhandenen kommt immer mehr Müll zum vorschein...

von Karl H. (kbuchegg)


Lesenswert?

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.

: Bearbeitet durch User
von Detocs (Gast)


Lesenswert?

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

von grundschüler (Gast)


Lesenswert?

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

von Detocs (Gast)


Lesenswert?

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

von grundschüler (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

: Bearbeitet durch User
von Paul B. (paul_baumann)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

PS: wenn du es mit Temperaturen zu tun hast, wirst du allerdings nicht 
umhin kommen, dich auch mit negativen Zahlen zu beschäftigen. :-)

FAQ

von Karl H. (kbuchegg)


Lesenswert?

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.

: Bearbeitet durch User
von Matthias L. (Gast)


Lesenswert?

>Die Funktion stellt zuerst fest, wie lang der Integer-Wert ist, zerlegt
>ihn dann in einzelne Ziffern u

Man könnte die Zahl auch direkt von links nach rechts aufbauen...

Beitrag "Re: Problem mit ADC an mega128"

von grundschüler (Gast)


Lesenswert?

notwendige Ergänzung für negative Zahlen:
1
if(dat<0){
2
std_lcd_putchar('-');
3
dat=dat*-1;
4
}

von Karl H. (kbuchegg)


Lesenswert?

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.

: Bearbeitet durch User
von Detocs (Gast)


Lesenswert?

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...

von Detocs (Gast)


Lesenswert?

was man noch dazu erwähnen sollte, negative Temperaturen werden nicht 
vorkommen...
das ganze spielt sich zwischen 20°C und 80°C ab

von Dennis Heynlein (Gast)


Lesenswert?

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.

von *ptr (Gast)


Lesenswert?

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.

von Detocs (Gast)


Lesenswert?

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.

von npn (Gast)


Lesenswert?

Detocs schrieb:
> mit typedef kann der Compiler auch nichts anfangen

Aber "typedef" ist Bestandteil der Sprache C. Wenn der Compiler damit 
nichts anfangen kann, würde ich mir Sorgen machen.
Welchen Compiler benutzt du?

von *ptr (Gast)


Lesenswert?

Detocs schrieb:
> mit typedef kann der Compiler auch nichts anfangen..
Auch nicht wenn du noch ein Semikolon am Ende der beiden Zeilen machst?
Bei mir kompiliert der Code Problemlos, wenn ich das u8 und u32 typdefe.

von *ptr (Gast)


Lesenswert?

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?

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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?

: Bearbeitet durch Moderator
von Karl H. (kbuchegg)


Lesenswert?

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.

: Bearbeitet durch User
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Karl Heinz schrieb:
>   char tmp[5];

Besser wäre es wohl, tmp mindestens 6 Zeichen zu spendieren. Desweiteren 
führt ein uint16_t statt int für die Variable "wert" zu mehr 
Portabilität und nicht womöglich zu einem Buffer-Overflow auf 32Bit-µCs 
;-)

: Bearbeitet durch Moderator
von Karl H. (kbuchegg)


Lesenswert?

Frank M. schrieb:
> Karl Heinz schrieb:
>>   char tmp[5];
>
> Besser wäre es wohl, tmp mindestens 6 Zeichen zu spendieren.

Danke.
Darauf hab ich jetzt nicht besonders geachtet. Du hast natürlich recht.

von Karl H. (kbuchegg)


Lesenswert?

Frank M. schrieb:

> Desweiteren
> führt ein uint16_t statt int für die Variable "wert" zu mehr
> Portabilität und nicht womöglich zu einem Buffer-Overflow auf 32Bit-µCs
> ;-)

Akzeptiert.
Der TO hat allerdings einen 8 Bit PIC.

Und Hand aufs Herz. Irgendwas wird ja wohl der TO dann auch alleine 
können.
(oder auch nicht)

von Detocs (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

Detocs schrieb:
> was man noch dazu erwähnen sollte, negative Temperaturen werden nicht
> vorkommen...

Berühmte letzte Worte.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Karl Heinz schrieb:
> Detocs schrieb:
>> was man noch dazu erwähnen sollte, negative Temperaturen werden nicht
>> vorkommen...
>
> Berühmte letzte Worte.

.... bevor der Schneesturm ihn bei -22°C hinfortriss ;-)

von Detocs (Gast)


Lesenswert?

wäre zwar eigenartig, wenn es in der Firma plötzlich diese Temperaturen 
annehmen würde, ich werde es aber im Hinterkopf behalten ;D

von Karl H. (kbuchegg)


Lesenswert?

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.

: Bearbeitet durch User
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

: Bearbeitet durch Moderator
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.