Sida 1 av 1
Switch-sats med Struct
Postat: 19 oktober 2009, 19:02:45
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...
Re: Switch-sats med Struct
Postat: 19 oktober 2009, 19:05:48
av eqlazer
Antar att det är '&' du ska ha i switch-statementet, alltså bitvis och, inte logisk.
Re: Switch-sats med Struct
Postat: 19 oktober 2009, 21:33:55
av niklo
structar är inte integer så du kommer troligen fortsätta att få d:o problem.
Re: Switch-sats med Struct
Postat: 19 oktober 2009, 21:38:31
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 ?
Re: Switch-sats med Struct
Postat: 19 oktober 2009, 21:53:20
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
Re: Switch-sats med Struct
Postat: 19 oktober 2009, 23:34:26
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:
Nja gör det egentligen någon skillnad om jag har en union eller struct?
Re: Switch-sats med Struct
Postat: 19 oktober 2009, 23:50:38
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...
Re: Switch-sats med Struct
Postat: 20 oktober 2009, 08:13:06
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:
...
}
Re: Switch-sats med Struct
Postat: 21 oktober 2009, 12:48:47
av stozze
Tycker jag ser ett litet fel där i switch-satsen, "case default:" ska väl egentligen bara vara "default:"
Re: Switch-sats med Struct
Postat: 21 oktober 2009, 13:01:02
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å?
Re: Switch-sats med Struct
Postat: 21 oktober 2009, 13:28:21
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.
Re: Switch-sats med Struct
Postat: 21 oktober 2009, 13:55:55
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.
Re: Switch-sats med Struct
Postat: 21 oktober 2009, 14:19:03
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.
Re: Switch-sats med Struct
Postat: 21 oktober 2009, 14:22:17
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...
Re: Switch-sats med Struct
Postat: 21 oktober 2009, 14:30:57
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.
