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


von Attila C. (attila)


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)


Lesenswert?

Die geschweiften Klammern fehlen.

von Attila C. (attila)


Lesenswert?

Hallo Luca,

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

von Lutz H. (luhe)


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)


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)


Lesenswert?

Lutz H. schrieb:
>>   ra=~ra/16-192;

Kann das negativ werden?

von Attila C. (attila)


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)


Lesenswert?

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

von Carl D. (jcw2)


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)


Lesenswert?

???

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

von Lutz H. (luhe)


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)


Lesenswert?

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

von Attila C. (attila)


Lesenswert?

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

von Wolfgang (Gast)


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)


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)


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)


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. (Gast)


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)


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. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


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)


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)


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)

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.