Forum: Mikrocontroller und Digitale Elektronik "if" wird nicht richtig ausgeführt


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Attila C. (attila)


Bewertung
0 lesenswert
nicht lesenswert
Guten Abend!

Folgender code:
1
uint8_t radioAlt()
2
{
3
  uint16_t ra=0;
4
5
  ra=ADC;
6
  ra=~ra/16-192;                          
7
  
8
  if (ra>50)
9
  ra=50;  
10
  
11
  return ra;
12
}

Gibt konstant "50" aus.

Der "if" Teil auskommentiert erbringt, wie gewünscht, Werte zwischen 0 
und etwas über 50. (Ich lese einen IR Distanzmesser aus)

Auch an anderer Stelle im code wird ein einfaches

if (x<0)
x=0;

nicht ausgeführt sondern die negativen Werte einfach weitergeleitet.

Weiss jemand Rat?

von Luca E. (derlucae98)


Bewertung
-4 lesenswert
nicht lesenswert
Die geschweiften Klammern fehlen.

von Attila C. (attila)


Bewertung
0 lesenswert
nicht lesenswert
Hallo Luca,

wenn nach dem "if" nur ein einziger Befehl folgt ist die geschweifte 
Klammer nicht erforderlich.

von Lutz H. (luhe)


Bewertung
0 lesenswert
nicht lesenswert
Attila C. schrieb:
> uint16_t ra=0;
  uint16_t fuenfzig=50;
>   ra=ADC;
>   ra=~ra/16-192;
>
>   if (ra>fuenfzig)
>   ra=fuenfzig;

Gleiche Typen nutzen.

von Jim M. (turboj)


Bewertung
0 lesenswert
nicht lesenswert
Attila C. schrieb:
> sondern die negativen Werte einfach weitergeleitet

Bei einem uint16_t ist x<0 eine Kontradiktion, also stets unwahr.

von Lutz H. (luhe)


Bewertung
0 lesenswert
nicht lesenswert
Lutz H. schrieb:
>>   ra=~ra/16-192;

Kann das negativ werden?

von Attila C. (attila)


Bewertung
0 lesenswert
nicht lesenswert
Lutz: Leider nicht. So klappt es auch nicht.

Jim: Das hätte ich auch gedacht. Er macht es aber trotzdem!

von Attila C. (attila)


Bewertung
0 lesenswert
nicht lesenswert
Lutz: Nein das wird nicht negativ. Das Beispiel mit den negativen Werten 
ist anderer Stelle im Programm.

von Carl D. (jcw2)


Bewertung
4 lesenswert
nicht lesenswert
Da steht:
1
  uint16_t ra=0;
2
3
  ra=ADC;
4
  ra= ( (~ra) / 16 )-192;                      
5
}

ADC 12bit(max):   00001111 11111111
~                 11110000 00000000
/16               00001111 00000000 ->3839
-192.             3647

ADC 12bit(min):   00000000 00000000
~                 11111111 11111111
/16               00001111 11111111 ->4095
-192.             3903

Jede Zahl zwischen 3647 und 3903 ist größer 50

PS: für 10bit Wandler gilt das genau so mit anderen Zahlen

: Bearbeitet durch User
von Teo D. (teoderix)


Bewertung
0 lesenswert
nicht lesenswert
???

Schreib's mal in eine Zeile. Bugs gibt's überall...
if (ra>50) ra=50;

von Lutz H. (luhe)


Bewertung
0 lesenswert
nicht lesenswert
ra=~ra/16-192;

Was soll ~ machen?

ra=(-1)* ra/16-192; ?

Luca E. schrieb:
> Die geschweiften Klammern fehlen.

nehme die {} es wird übersichtlicher

von HildeK (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Du hast eine Funktion mit uint8_t definiert, gibst aber ein ujnt16_t 
zurück. Kann das korrekt funktionieren?

von Attila C. (attila)


Bewertung
0 lesenswert
nicht lesenswert
Carl: Wenn der if Teil auskommentiert ist geht es, wie ich bereits am 
Anfang sagte.

von Wolfgang (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Lutz H. schrieb:
> Lutz H. schrieb:
>>>   ra=~ra/16-192;
>
> Kann das negativ werden?

Nein, ra ist als unsigned deklariert

von Carl D. (jcw2)


Bewertung
0 lesenswert
nicht lesenswert
Attila C. schrieb:
> Carl: Wenn der if Teil auskommentiert ist geht es, wie ich bereits am
> Anfang sagte.

Welcher Wertebereich kommt denn aus dem ADC?
Ich hatte einfach mal 12Bit rechtsbündig min/max angenommen.

Geht was?
Du gibst nur 8bit zurück!

: Bearbeitet durch User
von Stefan E. (sternst)


Bewertung
0 lesenswert
nicht lesenswert
Attila C. schrieb:
> Carl: Wenn der if Teil auskommentiert ist geht es, wie ich bereits am
> Anfang sagte.

Ja, weil durch den Rückgabetyp das Ergebnis auf die unteren 8 Bit 
begrenzt wird. Im if sind die oberen 8 Bit aber noch da.

von Adib (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Lutz H. schrieb:
> Lutz H. schrieb:
>>>   ra=~ra/16-192

Was soll der code denn eigentlich machen? Von welchem ad Wandler kommen 
die Daten?

Kann sein, dass das ergebnis immer > 50 ist (oder das das der Compiler 
glaubt).

Grüße, Adib.

von A. S. (achs)


Bewertung
0 lesenswert
nicht lesenswert
Attila C. schrieb:
> Carl: Wenn der if Teil auskommentiert ist geht es, wie ich bereits am
> Anfang sagte.

Dein Beispiel macht keinen Sinn. Du verwendest
- einen ADC
- "komplexe" Rechenoperationen (~)
- manchen nicht genehme typen etc.

Dein Problem kann ja ausschließlich in der einen Anweisung liegen:

[c]
if(ra>50) {ra=50;}
[c]

Es ist unwahrscheinlich, dass der Compiler dies falsch bearbeitet.

Reduziere also den Code auf das notwendige. Lass ihn z.B. in einer 
Schleife mit i=1..100 laufen, mit ra=i am Anfang.

Es wird sich herausstellen, dass
- Du den Code nicht korrekt abgeschrieben hast (z.B. ein Makro hinterm 
if, dass würde mit {} behoben)
- Du nach laden mit if (warum auch immer) wirklich nur Werte >=50 hast
- Du den code geladen hast, wo das if noch auskommentiert war, das ra=50 
aber schon nicht.

Mit ADC und ~ oder uint irgendwas hat es jedenfalls nichts zu tun.

von Attila C. (attila)


Bewertung
0 lesenswert
nicht lesenswert
Carl und Stefan: Ganz genau!

Ich habe jetzt mal ra vollständig auf dem Display ausgegeben und erhalte 
etwas um die 3800.

Vielen Dank für die Hilfe!

von Lothar M. (lkmiller) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Attila C. schrieb:
> Ich habe jetzt mal ra vollständig auf dem Display ausgegeben und erhalte
> etwas um die 3800.
Deine bitweise Neagtion ist dafür irgendwie die Ursache:
Wenn du 0 vom ADC bekommst, dann kommen da 65535 heraus. Die geteilt 
durch 16 ergeben 4095. Davon 192 abgezogen ergeben irgendetwas "um die 
3800"...

von Carl D. (jcw2)


Bewertung
0 lesenswert
nicht lesenswert
Attila C. schrieb:
> Carl und Stefan: Ganz genau!
>
> Ich habe jetzt mal ra vollständig auf dem Display ausgegeben und erhalte
> etwas um die 3800.
>
> Vielen Dank für die Hilfe!

Wenn du eine Wertefolge skalieren ("/16"), Steigung invertieren ("~") 
und verschieben willst ("-192"), dann am besten mit signed int (da die 
12bit aus dem ADC ja gut reinpassen) und nur mit signed-Operatoren.
Also kein Einer-Komplement ("~") und auch kein shift statt Division. Der 
Compiler kennt diese Tricks selber, aber er weiß auch, wann er sie 
benutzen darf. Erst wenn Bits und Takte ganz knapp werden, dann kann/muß 
man tricksen. Davor ist es nur verschwendete Zeit. ;-)

von Dirk B. (dirkb2)


Bewertung
0 lesenswert
nicht lesenswert
Lothar M. schrieb:
> Attila C. schrieb:
>> Ich habe jetzt mal ra vollständig auf dem Display ausgegeben und erhalte
>> etwas um die 3800.
> Deine bitweise Neagtion ist dafür irgendwie die Ursache:
> Wenn du 0 vom ADC bekommst, dann kommen da 65535 heraus. Die geteilt
> durch 16 ergeben 4095. Davon 192 abgezogen ergeben irgendetwas "um die
> 3800"...

Und dann nur noch 8-Bit zurück gibst (vor allem, wenn du das if 
auskommentierst)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.