Switch-sats med Struct

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
CyberLeffe
Inlägg: 50
Blev medlem: 22 februari 2007, 01:15:26
Ort: Göteborg/Örebro

Switch-sats med Struct

Inlägg av CyberLeffe »

Jag har gjort en struct som innehåller data som sätts beroende på vad jag har skickat till min PIC via serieporten.

structen är deklarerad enligt

Kod: Markera allt

volatile struct {
		  unsigned C0:1;
		  unsigned C1:1;
		  unsigned C2:1;
		  unsigned C3:1;
		  unsigned NONE:1;
		  unsigned COM:1;
		  unsigned ERROR:1;
		  unsigned DO:1;
	} CMDbits;
Jag har sedan en switch-sats där jag vill göra olika saker beroende på de fyra lägsta bitarna i min struct.

Kod: Markera allt

switch(CMDbits && 0x0F){
					case 0x00:
						TX1char("TEXT1");
						break;
						
					case 0x01:
						TX1char("TEXT2");
						break;
					
					case 0x02:
						TX1char("TEXT3");
						break;
						
					case default:
						TX1char("ERROR");
						break;
}
Men jag kan inte få det att fungera. Skriver jag på detta sätt får jag error i kompileringen
Error [1124] scalar operands expected for '&&' operator
Error [1112] integer type expected in switch control expression

Så min fråga är hur kan man skriva för att skriva en switch-sats som är beroende av de 4 lägsta bitarna i en struct.

Kanske lite otydlig förklaring...
eqlazer
Inlägg: 923
Blev medlem: 22 september 2007, 13:53:45
Ort: Göteborg

Re: Switch-sats med Struct

Inlägg av eqlazer »

Antar att det är '&' du ska ha i switch-statementet, alltså bitvis och, inte logisk.
niklo
Inlägg: 150
Blev medlem: 16 september 2009, 11:46:48
Ort: Norrköping

Re: Switch-sats med Struct

Inlägg av niklo »

structar är inte integer så du kommer troligen fortsätta att få d:o problem.
sodjan
EF Sponsor
Inlägg: 43247
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Switch-sats med Struct

Inlägg av sodjan »

Varför överhuvudtaget blanda in en struct där !?
Det borde räcka om CMDbits är en byte/char eller vad
du en 8-bitars variabel kallas. Varför behöver du accessa
varje bit inviduellt med egna namn ?
johano
Inlägg: 1943
Blev medlem: 22 januari 2008, 10:07:45
Ort: Stockholm

Re: Switch-sats med Struct

Inlägg av johano »

> Varför behöver du accessa varje bit inviduellt med egna namn ?

Men om du vill så är en UNION behändig isåfall.

Kod: Markera allt

typedef union _CMD
{
 unsigned char CMDBitsByte;
 struct
 {
  unsigned C0:1;
  unsigned C1:1;
  unsigned C2:1;
  unsigned C3:1;
  unsigned NONE:1;
  unsigned COM:1;
  unsigned ERROR:1;
  unsigned DO:1;

 } CMDBitsStruct;
} CMD;

CMD cmd;

cmd.CMDBitsStruct.C0 = 0;
...

switch(cmd.CMDBitsByte & 0x0f)
{
 ...
}

/johan
CyberLeffe
Inlägg: 50
Blev medlem: 22 februari 2007, 01:15:26
Ort: Göteborg/Örebro

Re: Switch-sats med Struct

Inlägg av CyberLeffe »

>Antar att det är '&' du ska ha i switch-statementet, alltså bitvis och, inte logisk.

Ja det är riktigt att det endast skall vara ett '&', gick lite snabbt när jag skrev inlägget. Dock löser inte detta mitt problem.


>Varför behöver du accessa varje bit inviduellt med egna namn ?

Det är inget som säger att jag måste göra det, men jag tycker att koden blir mer läslig och begriplig genom att göra på detta sätt. Dessutom är det ganska smidigt att på ett enkelt sätt kunna accessa enskilda bitar då jag använder vissa som status bitar.

johano:

Kod: Markera allt

 switch(cmd.CMDBitsByte & 0x0f)
{
...
}
Nja gör det egentligen någon skillnad om jag har en union eller struct?
sodjan
EF Sponsor
Inlägg: 43247
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Switch-sats med Struct

Inlägg av sodjan »

> men jag tycker att koden blir mer läslig och begriplig genom att göra på detta sätt.

Ha ! Kul... :-)

> Nja gör det egentligen någon skillnad om jag har en union eller struct?

Du kan inte göra en bit-wise and mellan en konstant och en struct,
det är inte kompatibla datatyper. Unionen som föreslogs gör att
du får en int (unsigned char) som sannolikt fungerar bättre. Läste
du exemplet ? Har du testat ??

Men som sagt, enklast är nog att skippa den där bit-structen helt...
dangraf
Inlägg: 530
Blev medlem: 9 juni 2003, 15:30:56
Ort: göteborg

Re: Switch-sats med Struct

Inlägg av dangraf »

men om du definierar upp bitarna i din strukt för att göra saker tydligt, varför krånglar du då till det med & tecken och grejjer??

Man skulle kunnat skriva såhär:

Kod: Markera allt

volatile struct {
        unsigned type:4;
        unsigned NONE:1;
        unsigned COM:1;
        unsigned ERROR:1;
        unsigned DO:1;
   } CMDbits;


switch(CMDbits.type)
{
  case 0:
...
}
Användarvisningsbild
stozze
Inlägg: 20
Blev medlem: 31 december 2007, 13:29:25
Ort: Vasa
Kontakt:

Re: Switch-sats med Struct

Inlägg av stozze »

Tycker jag ser ett litet fel där i switch-satsen, "case default:" ska väl egentligen bara vara "default:"
Nerre
Inlägg: 27184
Blev medlem: 19 maj 2008, 07:51:04
Ort: Upplands väsby

Re: Switch-sats med Struct

Inlägg av Nerre »

Kan man vara garanterad att kompilatorn verkligen lägger de olika elementen i structen i bitföljd?

Är det inte så att kompilatorn får optimera, och därmed kan lägga varje element i ett eget ord eller en egen byte, eftersom de operationer som görs går snabbare att göra då?
Användarvisningsbild
mri
Inlägg: 1165
Blev medlem: 15 mars 2007, 13:20:50
Ort: Jakobstad, Finland
Kontakt:

Re: Switch-sats med Struct

Inlägg av mri »

Kollade just i en C++ referens bok (antagligen är det lika för C, men har inte kollat upp det).
Språket definierar INTE hur och var bitarna allokeras.

Men, såvitt jag vet lägger nog de flesta kompilatorer dom i den ordning man förväntar sig, dvs. första biten i LSB, osv.

Skall man vara säker på att koden är portabel får man nog göra som sodjan föreslog.
Nerre
Inlägg: 27184
Blev medlem: 19 maj 2008, 07:51:04
Ort: Upplands väsby

Re: Switch-sats med Struct

Inlägg av Nerre »

Jag har nåt svagt minne av att jag läst att många kompilatorer inte lägger flera element i samma byte även om det skulle få plats. Så att bitmaska en struct är alltså lite riskabelt.
Zäta
Inlägg: 181
Blev medlem: 22 september 2006, 08:25:21
Ort: Borlänge

Re: Switch-sats med Struct

Inlägg av Zäta »

Nja, men definerar inte Microchip själva sina structar/unioner på detta sätt? Borde ju funka. Kolla i headerfilerna och se efter hur dom gjort.

Annars kasnke du kan tilldela värdet till en variabel innan du gör den bitvisa operationen.
sodjan
EF Sponsor
Inlägg: 43247
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Switch-sats med Struct

Inlägg av sodjan »

Om man gör en union mellan en unsigned char (8-bitar) och
en bit-struct, så borde de ju ligga i samma byte. Annars
fungerar inte unionen speciellt bra...
Användarvisningsbild
mri
Inlägg: 1165
Blev medlem: 15 mars 2007, 13:20:50
Ort: Jakobstad, Finland
Kontakt:

Re: Switch-sats med Struct

Inlägg av mri »

Nerre: Hittade lite officiell info på nätet:

C99 standard 6.7.2.1/10 - "Structure and union specifiers"
An implementation may allocate any addressable storage unit large enough to hold a bitfield. If enough space remains, a bit-field that immediately follows another bit-field in a structure shall be packed into adjacent bits of the same unit. If insufficient space remains, whether a bit-field that does not fit is put into the next unit or overlaps adjacent units is implementation-defined. The order of allocation of bit-fields within a unit (high-order to low-order or low-order to high-order) is implementation-defined. The alignment of the addressable storage unit is unspecified.

Dvs, kompilatorn bör nog inte flytta över bitarna i en ny "storage unit" om det finns plats i den föregående.

I tråden var jag fann ovanstående C99 stycke fanns den här avslutande kommentaren:
Of course the best answer is to use a class which reads/writes bit fields as a stream. Using the C bit field structure is just not guaranteed. Not to mention it is considered unprofessional/lazy/stupid to use this in real world coding.
:-)
Skriv svar