Hallo
Über diesen "Denkfehler" bin ich auch schon gestolpert. Ursache für dieses unerwartete Verhalten ist die struct-Definition der LEDs. Mit einem Struct kann man sich eigene Datentypen erzeugen die beliebige Bitlängen haben. In "RP6RobotBaseLib.h" steht folgendes:
Code:
union {
uint8_t byte;
struct {
unsigned LEDsR:3;
unsigned LEDsL:3;
unsigned reserved:2;
};
struct {
unsigned LED1:1;
unsigned LED2:1;
unsigned LED3:1;
unsigned LED4:1;
unsigned LED5:1;
unsigned LED6:1;
unsigned reserved1:1;
unsigned reserved2:1;
};
} statusLEDs;
Unten sieht man, dass jede LED nur ein Bit belegt (LED1:1;...). Wenn man nun eine LED setzen möchte, wird vom übergebenen Wert nur ein Bit (das letzte, genannt Bit0) ausgewertet und gegebenenfalls gesetzt, z.b. statusLEDs.LED1=1 bedeutet statusLEDs.LED1=0b00000001 (dezimal 0 wäre binär 0b00000000 also LED aus.) Soweit alles klar?
Nun zu den Bumpers. Die Werte in bumper_left/bumper_right werden im Bumpers-Task durch die Funktionen getBumperLeft()/getBumperRight() eingelesen. Im Rückgabewert der Funktionen (und damit auch in den Variablen bumper_left/bumper_right) steht jeweils das Ergebniss der Portabfrage als 8-bit-Wert.
Der betreffende Eingang für den linken Bumper ist Port B0, bei gedrückten Taster wird deshalb der Wert 1 (binär 0b00000001) eingelesen und in bumper_left gespeichert. statusLEDs.LED4=bumper_left bedeutet dann statusLEDs.LED4=0b00000001 und die LED ist eingeschaltet.
Der Eingang für den rechten Bumper ist Port C6. Bei gedrücktem Bumper wird hier deshalb 2^6 oder 64 eingelesen und in bumper_right gespeichert. statusLEDs.LED1=bumper_right bedeutet dann statusLEDs.LED1=0b01000000. Bit0 ist also 0, die LED bleibt dunkel. Aha!
Lösung: Man vergleicht bumper_right mit 64 und setzt mit dem Ergebniss dieses Vergleichs die LED:
statusLEDs.LED1=bumper_right==64
Bei gedrücktem Bumper ist der Vergleich true und somit geht die LED an. (ACHTUNG! Das funktioniert nicht generell in C weil nicht definiert ist, wie der Compiler intern ein true speichert. true könnte auch z.B. 0b10000000 sein. Nur so am Rande erwähnt):
Code:
#include "RP6RobotBaseLib.h"
int main(void)
{
initRobotBase();
while(true)
{
statusLEDs.LED1=bumper_right==64;
statusLEDs.LED2=bumper_right==64;
statusLEDs.LED5=bumper_left;
statusLEDs.LED4=bumper_left;
task_Bumpers();
updateStatusLEDs();
}
return 0;
}
Der Vollständigkeit halber: Das funktioniert so nur, weil in der Rangfolge der Operatoren == vor = kommt (wie Punkt vor Strich) Im Zweifel (und zur besseren Lesbarkeit des Programms) verwendet man besser Klammern:
statusLEDs.LED1=(bumper_right==64);
Der erzeugte Code ist aber in beiden Fällen gleich.
Gruß
mic
Lesezeichen