boolsche Variable

Gast #237357
Lesenswert?

Hallo Leute.
Es gab mal sowas schönes wie boolsche Variable.
Man hat eine Variable, nennen wir sie "test" vom typ boolean
deklariert.
Dann konnte man test := true oder test := false setzen oder
zurücksetzen und mit if(test)  zb für einen Vergleich heranziehen.
Die Frage: Wenn ich ein Bit z.B. PORTD,PD7 so z.B. durch eine define
"vorbereiten", dass es genau so funktioniert, wie "test", wenn wir
mal davon ausgehen das die Zuweisung über = erfolgt und der Vergleich
über ==
Moderator Persönliche Seite #237359
Lesenswert?

> Es gab mal sowas schönes wie boolsche Variable.

Gibt's in C99 übrigens auch.  Anders als in C++ (wo es ein
Standardtyp
ist) muss man in C #include <stdbool.h> machen, danach hat man den Typ
"bool" und die Werte "false" und "true" definiert.

> Die Frage: Wenn ich ein Bit z.B. PORTD,PD7 so z.B. durch eine define
> "vorbereiten", dass es genau so funktioniert, wie "test", wenn
wir
> mal davon ausgehen das die Zuweisung über = erfolgt und der
Vergleich
> über ==

Du meinst sowas?

#define PORTTEST (PIND & _BV(PD7))

...
  if (PORTTEST) {
    ...
  }

(Ich nehme mal an, du wolltest PIND testen und nicht PORTD. ;-)
Gast #237360
Lesenswert?

> (Ich nehme mal an, du wolltest PIND testen und nicht PORTD. ;-)

Ach ja, da war ja noch was. Ich gebe zu das Beispiel ist schlecht
gewählt. Ich dachte mir es wäre allgemeinverständlicher als
GPIOR2,GPIOR04.

mir schwebte etwas in der Art
 #define?? transmitter_online ??? (GPIOR2,GPIOR04)

if ("ankommende Daten ok") transmitter_online = true; (1) else
transmitter_online = false;

if (transmitter_online) { "Mach was "}

geht sowas und wenn ja, wie?
#237361
Lesenswert?

> geht sowas und wenn ja, wie?

Wie oben geschrieben, mit C geht das nicht.
Der Zuweisungsoperator hat in C eine genau festgelegte Bedeutung. Da es
keine "1-Bit-Variable" gibt (zumindest keinen Zeiger darauf), kann man
nur mit dem Zuweisungsoperator allein kein einzelnes Bit verändern.
Persönliche Seite #237362
Lesenswert?

Hier mal ein kleines Beispiel, wie es doch funktionieren könnte!
In wie weit das aber Portabel ist, kann ich nicht sagen. Die Idee kam
mir ganz spontan, als ich mich an einen anderen Thread erinnerte.
1
#include <avr/io.h>
2
#include <stdbool.h>
3

4
typedef struct
5
IOPort8Bit_s {
6
        unsigned char pin0:1;
7
        unsigned char pin1:1;
8
        unsigned char pin2:1;
9
        unsigned char pin3:1;
10
        unsigned char pin4:1;
11
        unsigned char pin5:1;
12
        unsigned char pin6:1;
13
        unsigned char pin7:1;
14
} IOPort8Bit_t;
15

16
IOPort8Bit_t *porta_mirr = (IOPort8Bit_t *)(&PORTA);
17
IOPort8Bit_t *pina_mirr = (IOPort8Bit_t *)(&PINA);
18

19
int
20
main(void)
21
{
22
        DDRA = 0xff;
23

24
        porta_mirr->pin1 = true;
25
        porta_mirr->pin2 = false;
26
        
27
        for(;;)
28
        {
29
                /* if(pina_mirr->pin1) or: */
30
                if(pina_mirr->pin1 == true)
31
                {
32
                        porta_mirr->pin0 ^= 1;
33
                }
34
        }
35

36
        /* NEVEREACHED */
37
        return 1;
38
}
Gast #237363
Lesenswert?

Du könntest doch auch eine Variablen einen Typedef machen.
typedef unsigned char Bool;      /* Boolean */
#define TRUE 1
#define FALSE !TRUE

So kannst du dann mit
Bool test;
eine "Boolsche" Variable deklarieren, die sich auch so verhält, nur
nicht 1 Bit belegt.

if (test)

Falls dann test==TRUE geht er rein, sonnst nicht.

Grüße Andreas
#237365
Lesenswert?

Noch ein Detail am Rande. Ich glaube nicht, daß man so:
#define TRUE 1
#define FALSE !TRUE
True und False definieren sollte.

Besser ist:
#define TRUE (1==1)
#define FALSE (1==0)
somit wird TRUE und FALSE genauso definiert wie der Compiler selbst
intern auch die Werte darstellt.
Gast #237368
Lesenswert?

< er möchte definitiv nur ein Bit einer Variablen
manipulieren...

Das ist nicht ganz richtig. Er möchte ein Bit eines Registers
abfragen oder manipulieren, aber nicht 3 Makros dafür benutzen
#define checktransmitter checkbit(
#define transmitter_online setbit(
#define transmitter_offline clearbit(

sondern nur transmitter dem Register ... zuweisen

und dann mit transmitter = true / transmitter = false oder
if(transmitter)

manipulieren
Gast #237370
Lesenswert?

@
Hab ich gesagt, dass Dein Code schlecht, oder falsch ist?
Sieht klassse aus und von dem was ich so davon verstehe, wird er
sicherlich auch funktionieren. Ist zwar viel zu kompliziert für mich
aber bestimmt ok.
Moderator Persönliche Seite #237371
Lesenswert?

> Was passiert in dem von mir eingefügten Code?

Er wird nicht garantiert funktionieren, weil du das volatile
vergessen hast. ;-)  IO-Register (die ja intern erstmal wie
Speicheradressen behandelt werden) müssen volatile sein.

Ansonsten ist ein bit field durchaus eine Möglichkeit dafür, ja.
Allerdings verliert der Compiler durch die zusätzlich eingefügten
Pointervariablen den Überblick, dass es sich um IO-Register handelt,
sodass er keine IO-Befehle mehr optimieren kann (IN, OUT, SBI, ...).
Besser ist daher
1
#define porta_mirr  ((volatile IOPort8Bit_t *)(&PORTA))
2
#define pina_mirr   ((volatile IOPort8Bit_t *)(&PINA))
Persönliche Seite #237372
Lesenswert?

>Hab ich gesagt, dass Dein Code schlecht, oder falsch ist?

Nein, hast Du nicht.
Bitte nicht gleich wieder unter die Decke gehen ;)

Ich passe den Code mal ein bißchen auf Deine spärlichen Angaben an,
damit Du das evtl. besser verstehst:
1
#include <avr/io.h>
2
#include <stdbool.h>
3

4
typedef struct
5
Register8Bit_s {
6
        unsigned char flag1:1;       /* irgendein flag      */
7
        unsigned char flag2:1;       /* irgendein flag      */
8
        unsigned char transmitter:1; /* transmitter ein/aus */
9
        unsigned char receiver:1;    /* receiver ein/aus    */
10
} Register8Bit_t;
11

12
Register8Bit_t reg;                  /* 'Register' anlegen  */
13

14
int
15
main(void)
16
{
17
        reg.transmitter = true;
18
        reg.receiver = false;
19
        
20
        for(;;)
21
        {       /* Endlosschleife */
22
                if(reg.flag1 == true)
23
                {       /* wenn flag1 gesetzt dann */
24
                        reg.flag2 ^= 1; /* toggle das andere */
25
                }
26
        }
27

28
        /* NEVEREACHED */
29
        return 1;
30
}
Gast #237374
Lesenswert?

@OldBug
Das Beispiel ist mir schon in gewisser Weise klar.
Ich muss halt etwas mit dem Speicher geizen, darum möchte ich keine 8
Bit für einen boolschen Operanden verschwenden.
Natürlich kann ich das ganze Register so bitweise belegen, aber ich
komme mit den Structs nicht so gut klar und dann auch noch ein volatile
...
Das durchschaue ich nicht mehr und da inzwischen einfache if-Abfragen
den größten Wahnsinn anzetteln und mich in stundenlange Fehlersuche
verwickeln, will ich es nicht mit Dingen schmücken, die ich
anschließend nicht mehr kurz auflösen kann um Fehler einzugrenzen.
Ich werd es mir auf jeden Fall ausdrucken und für die nächste Version
vormerken, weil es zimlich gut aussieht,

nur...
wo ist der Punkt an dem ich "reg" dem GPIOR2 (das Register) zuweise?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren