Electronics > Projects, Designs, and Technical Stuff
Making A Cylon Eye
Lance:
I'm trying to make 8 leds run like a cylon eye. Because the leds cover two different port ranges, I decided to try and make a little bitfield which I could then set the ports with. It failed horribly.
The idea is to have 8 unsigned integers, one representing each light. Then just use some bitwise shifts to move the light around.
--- Code: ---void Cylon(void)
{
unsigned int counter=0;
unsigned long i=0;
struct light
{
unsigned int light0:1;
unsigned int light1:1;
unsigned int light2:1;
unsigned int light3:1;
unsigned int light4:1;
unsigned int light5:1;
unsigned int light6:1;
unsigned int light7:1;
}
union light_union
{
struct light x;
} Lights;
Lights.x=(0b00000000u);
}
--- End code ---
Actually trying to set the bits is being problematic, I get this error message:
--- Code: ---illegal conversion between types unsigned int -> struct light
--- End code ---
I'm not sure what to do here.
RayJones:
You are close, but not quite right! (as you've probably figured!)
You need to add an int to your union, and keep your struct as you have already.
Ala
--- Code: ---union light_union {
int x;
struct light bits;
} Lights;
--- End code ---
You can then access x as you desire, and the magic of the union will set the bits broadside as you desire, likewise read them back.
If you want change a bit, use
--- Code: ---Lights.bits.light0 = 1; (or 0)
--- End code ---
Lance:
--- Quote from: RayJones on February 20, 2011, 06:29:07 am ---You are close, but not quite right! (as you've probably figured!)
You need to add an int to your union, and keep your struct as you have already.
Ala
--- Code: ---union light_union {
int x;
struct light bits;
} Lights;
--- End code ---
You can then access x as you desire, and the magic of the union will set the bits broadside as you desire, likewise read them back.
If you want change a bit, use
--- Code: ---Lights.bits.light0 = 1; (or 0)
--- End code ---
--- End quote ---
I see. Could you please explain to me why this is necessary?
RayJones:
BTW, I've been coding for far too long, and still the union caught me with my pants down the other day.
I knew what I wanted to achieve, but still made minced meat of it. :'(
The secret is each line in the union specifies a element, the largest element determines the end size of the union (space used in memory).
Other elements will occupy the same memory space, but be interpreted according to their type, ie a bit field in your application.
Other tricks could be
--- Code: ---union {
int AsInt;
float AsFloat;
}
--- End code ---
This allows you to write a float value, then grab the byte form equivalent for transfer/storage.
When digging down to byte level though you need to be careful of the endian order of your processor as to where the LSB lives in memory for a 16 or 32 bit value.
My personal fave is
--- Code: ---union {
int Word;
struct {
char LSB;
char MSB;
} bytes;
}
--- End code ---
This is used to rip a 16 bit value into the HIWORD/LOWORD far more efficiently than the typical mask and shift operations used.
Once again, take care with the endianess of your processor.
RayJones:
I should also add, using int is processor specific as to how many bits it is.
The native register size of the processor is usually adopted.
ie for a 16 bit processor, ints will be 16 bits, likewise 32 bits for a 32 bit processor.
to control the sizes better, you should use shorts or longs (16 or 32)
char is invariably 8 bits, but not always!
Having said this, you should realise my examples above are flawed, instead of int I should use long in the float example, and short in the HIWORD/LOWORD example.
Navigation
[0] Message Index
[#] Next page
Go to full version