Forum: Mikrocontroller und Digitale Elektronik Berechnung der Übergabeparameter beim Funktionsaufruf klappt nich immer


von Stephan M. (multimeter90)


Lesenswert?

Hallo Leute,

ich habe keine Ahnung ob es für dieses Problem überhaupt möglich ist 
eine Lösung zu finden, falls diese denn existiert.

Ich rufe eine Funktion auf und berechne die Parameter bei der Übergabe. 
Das funktioniert fast immer... nur warum nicht immer? Im Beispiel, bei 
dem das auftritt berechne ich eigentlich (TASTATUR_START_Y+48), auch mit 
dem eigesetzen Wert für TASTATUR_START_Y geht es nicht. Es wird kein 
Rechteck gezeichnet, sondern viele ungleich verteilte Senkrechte Linien.
Im Falle, dass es funktioniert, wird ein schönes Rechteck gezeichnet.

1
// Prototyp
2
void LCD_DrawRectangle(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, unsigned char on, unsigned char fill); 
3
4
//Aufruf geht:
5
// rahmen um Tastatur
6
LCD_DrawRectangle(TASTATUR_START_X, TASTATUR_START_Y,(130+TASTATUR_START_X),(140),PIXEL_ON,0);
7
8
// Aufruf geht NICHT
9
LCD_DrawRectangle(TASTATUR_START_X, TASTATUR_START_Y,(130+TASTATUR_START_X),(92+48),PIXEL_ON,0);

Warum macht das einen Unterschied?

von Karl H. (kbuchegg)


Lesenswert?

Stephan Meter schrieb:
> Hallo Leute,
>
> ich habe keine Ahnung ob es für dieses Problem überhaupt möglich ist
> eine Lösung zu finden, falls diese denn existiert.
>
> Ich rufe eine Funktion auf und berechne die Parameter bei der Übergabe.
> Das funktioniert fast immer... nur warum nicht immer? Im Beispiel, bei
> dem das auftritt berechne ich eigentlich (TASTATUR_START_Y+48), auch mit
> dem eigesetzen Wert für TASTATUR_START_Y geht es nicht. Es wird kein
> Rechteck gezeichnet, sondern viele ungleich verteilte Senkrechte Linien.
> Im Falle, dass es funktioniert, wird ein schönes Rechteck gezeichnet.

Och, die Berechnung wird schon funktionieren.
Die Frage ist eher: Was macht die Funktion mit dem Wert?
Kann die überhaupt mit dem berechneten Ergebnis etwas anfangen?

Und dann kann es natürlich immer noch sein, dass das eigentliche Problem 
ganz woanders sitzt und du hier nur die Symptome siehst.

> Es wird kein Rechteck gezeichnet, sondern viele ungleich
> verteilte Senkrechte Linien.

Die Funktion soll aber nicht zufällig ein gefülltes Rechteck zeichnen, 
macht dies indem sie lauter senkrechte (oder waagrechte) Linien malt und 
aus irgendeinem arithmetischen Grund  werden ein paar Linien 
ausgelassen?


> ich habe keine Ahnung ob es für dieses Problem überhaupt möglich
> ist eine Lösung zu finden, falls diese denn existiert.

Wieso so zaghaft? Natürlich gibt es auch dafür eine Lösung. Rechtecke 
malen ist ja jetzt nicht unbedingt Raktentechnik.

von Peter II (Gast)


Lesenswert?

Stephan Meter schrieb:
> Warum macht das einen Unterschied?

eigentlich nicht, vergleich doch mal den ASM code.

von Stephan M. (multimeter90)


Lesenswert?

Danke für die schnellen Antworten.

Ich habe das Problem gefunden. Liegt sicherlich an meinem Compiler. Er 
sieht beim Aufruf die 92 und macht daraus einen signed char, dann 
rechnet er +48 und wandelt dann in unsigned int um.
Bei der anderen Berechnung mit den 130+TASTATUR_START_X nimmt er gleich 
einen unsigned char. Ich habe vor meine 92 ein (unsigned int) 
geschrieben, jetzt gehts.

von Peter II (Gast)


Lesenswert?

Stephan Meter schrieb:
> Liegt sicherlich an meinem Compiler.

was für einen compiler nutzt du?

von Karl H. (kbuchegg)


Lesenswert?

Stephan Meter schrieb:
> Danke für die schnellen Antworten.
>
> Ich habe das Problem gefunden. Liegt sicherlich an meinem Compiler. Er
> sieht beim Aufruf die 92 und macht daraus einen signed char, dann
> rechnet er +48 und wandelt dann in unsigned int um.

Das ist aber eigentlich den C-Regeln nach nicht erlaubt.
92 ist ein signed int.

von Stephan M. (multimeter90)


Lesenswert?

Ich kann es mir nur so erklären.

von dumdidum (Gast)


Lesenswert?

Bitte mehr Details. Woher kommt der Prototyp? Aus welcher Bibliothek. 
Sind die beiden Aufrufe in derselben Datei?

Falls nicht: Vielleicht ist beim 2ten Aufruf der Prototyp nicht 
definiert worden und somit wird die Zahl 140 als int interpretiert und 
in die beiden Variablen geschrieben.

Was passiert wenn Du beide Stellen vertauschts? Geht dann auch der eine 
Aufruf und der andere nicht?

Also : mehr Details (und vielleicht das kleinste moegliche Programm, 
dass diesen Fehler zeigt posten). Auch Angabe zur Zielhardware ist nicht 
falsch.

von Stephan M. (multimeter90)


Angehängte Dateien:

Lesenswert?

dumdidum schrieb:
> Bitte mehr Details. Woher kommt der Prototyp? Aus welcher Bibliothek.
> Sind die beiden Aufrufe in derselben Datei?

Die Lib ist von mir. Siehe Anhang. Eingebunden per
1
#include "gLCD.h"

> Falls nicht: Vielleicht ist beim 2ten Aufruf der Prototyp nicht
> definiert worden und somit wird die Zahl 140 als int interpretiert und
> in die beiden Variablen geschrieben.

Ich rufe die Funktion nur einmal auf, compiliere, teste. Umschreiben, 
compilieren, testen.

> Was passiert wenn Du beide Stellen vertauschts? Geht dann auch der eine
> Aufruf und der andere nicht?
>
> Also : mehr Details (und vielleicht das kleinste moegliche Programm,
> dass diesen Fehler zeigt posten). Auch Angabe zur Zielhardware ist nicht
> falsch.

Zielhardware ist ein PIC18F4685 von microchip. LCD ist ein 160x160 Pixel 
grafisches LCD mit LC7981 Treiber.

von Thomas K. (thomas_k39)


Lesenswert?

Ich kann zu Deinem eigentlichen Problem wenig beitragen.

Aber: beim Durchsehen der gLCD.c ist mir am Anfang der Funktion 
LCD_DrawLine diese Sequenz aufgefallen:
1
  if(x1==x2){  /* vertical line */
2
    if (x2<x1) {
3
      i=x1; x1=x2; x2=i;  
4
    }

Nun, wenn x1==x2 ist, kann nicht gleichzeitig x2<x1 gelten! Müsste die 
zweite Abfrage nicht
1
if (y2<y1) ...
heissen?

Thomas

von Stephan M. (multimeter90)


Lesenswert?

Da hast du natürlich Recht. Das ist für den Fall, dass ich eine Linie 
von rechts nach links/ unten nach oben zeichnen will dahin gekommen. 
Werde das gleich ändern.

von Thomas K. (thomas_k39)


Lesenswert?

Ich muss mich korrigieren.

Der Code müsste eigentlich
1
  if(x1==x2){  /* vertical line */
2
    if (y2<y1) {
3
      i=y1; y1=y2; y2=i;  
4
    }
heissen. Die nachfolgende for-Schleife geht nämlich davon aus, dass y1 
kleiner als y2 ist.

Thomas

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.