Forum: Compiler & IDEs Bitmanipulation in verschiedenen Files


von Stefanie (Gast)


Lesenswert?

Hallo,

ich habe gerade das Tutorial über Bitmanipulationen gelesen und nun eine 
Frage, wie ich es in meinem konkreten Fall richtig anwenden kann:

Ich habe ein Projekt mit mehreren Files
z.B.
Alarm.c mit Alarm.h
Power.c mit Power.h
Temperatur.c mit Temperatur.h
...

Jeder Sensor missten periodisch eine Messgröße aus und falls meldet, 
wenn nötig den Alarm der Alarm.c
mit folgender Funktion
setAlarm(ALARM_lowPower);
oder
setAlarm(ALARM_highTemp);

in der Alarm.c ist nun folgendes definiert

#define ALARM_lowPower 0
#define ALARM_highTemp 1
...

int Alarm_array

void setAlarm(string Alarmtype)
{
Alarm_array |= ((1 <<  Alarmtype);
}


Das Alarm_array wird dann von mir ausgewertet und ich habe somit in 
einer einzigen Variable den Zustand des Gerätes stecken.

Kann das so funktionieren?? Was ist falsch?

DANKE

von Stefanie (Gast)


Lesenswert?

Jetzt kommt mir noch eine Frage zur Auswertung dieses Alarm_array.
Die Variable ist ja ein Integer. Wie kann ich mir nun rausfiltern, 
welches Bit dieser Variable gesetzt ist?

von Andreas B. (Gast)


Lesenswert?

Wie man testet, ob ein bestimmtes Bit gesetzt ist, sollte auch im 
Tutorial stehen. Um zu sehen, welche Bits alle gesetzt sind, bleibt 
meist nichts besseres als alle in Frage kommenden Bits nacheinander zu 
testen. Wenn man nicht wissen muss, welche Bits gerade gesetzt sind, 
kann man auch mehrere auf einmal mit einer Bitmaske abfragen.

Bei Alarm_array muss man noch aufpassen, ob setAlarm() (ein clearAlarm() 
wird es ja auch noch geben) aus verschiedenen Kontexten (Haupschleife, 
Interrupt) aufgerufen werden kann, die sich gegenseitig unterbrechen 
können. Dann muss die Unterbrechung in setAlarm() verhindert werden, in 
den meisten Fällen also Interrupts abschalten am Anfang und wieder 
aktivieren am Ende.

Eventuell braucht die Variable auch noch ein volatile, je nach 
Einsatzszenario.

von Guru (Gast)


Lesenswert?

Ich weiss ja nicht, ob das ein Versehen ist, aber Du schriebst:

>Ich habe ein Projekt mit mehreren Files
>...
>Alarm.c mit Alarm.h
>...

und dann:
1
in der Alarm.c ist nun folgendes definiert
2
3
#define ALARM_lowPower 0
4
#define ALARM_highTemp 1
5
...
6
7
int Alarm_array
8
9
void setAlarm(string Alarmtype)
10
{
11
   Alarm_array |= ((1 <<  Alarmtype);
12
}

Damit Du aber die Preprozessor definitionen aus Funktionen aus den 
anderen C-Files heraus aufrufen kannst, müssen diese in z.B. in Alarm.h 
definiert werden.

--------------------

Um zu prüfen ob ein bestimmtes Bit gesetzt ist, kannst Du z.B.
1
if (Alarm_array & (1 <<  ALARM_lowPower) {
2
   // low power alarm IST gesetzt
3
}
4
else {
5
   // low power alarm ist NICHT gesetzt
6
}

verwenden. Näheres dazu beschreibt das C-Buch Deiner Wahl.

von Stefanie (Gast)


Lesenswert?

Hallo,

danke für die Meldungen!

Guru schrieb:
> void setAlarm(string Alarmtype)
> {
>    Alarm_array |= ((1 <<  Alarmtype);
> }

der Übergabeparameter muß vom Typ int sein, da er ja ersetzt wird.

aber bei folgender Zeile
"Alarm_array |= ((1 <<  Alarmtype);"

bekomme ich die Meldung:
"overflow is possible in 8 bit shift left, casting shifted operand to 
'int' may be required"

Warum bzw. was soll ich tun?

von Karl H. (kbuchegg)


Lesenswert?

Stefanie schrieb:


Welcher Compiler ist das?
GCC ist es nicht.

> der Übergabeparameter muß vom Typ int sein, da er ja ersetzt wird.

Mach das auf einem 8_Bit System besser einen unsigned char und keinen 
int. int hat mindestens 16 Bit und es gibt keinen Grund, dass hier ein 
16 Bit Wert an die Funktion übergeben werden müssen. So große Zahlen 
hast du nicht.

> aber bei folgender Zeile
> "Alarm_array |= ((1 <<  Alarmtype);"
>
> bekomme ich die Meldung:
> "overflow is possible in 8 bit shift left, casting shifted operand to
> 'int' may be required"

Die Fehlermeldung ist irreführend, denn eigentlich ist "1" schon ein 
int. (Daher weiß ich auch, dass du nicht den GCC benutzt).
Sieh mal nach, ob die Änderung auf unsigned char in der Argumentliste 
schon reicht, wenn nicht, dann caste halt die 1 um auf einen int, wenn 
sichs der Compiler darauf steht

  Alarm_array |= (((int)1 <<  Alarmtype);"

> Warum bzw. was soll ich tun?

Zum Warum musst du den Compilerhersteller fragen. Laut C-Standard gibt 
es hier nichts auszusetzen.

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.