![]() |
| | #1 |
| Registered User Join Date: Aug 2008
Posts: 5
| I'm trying to convert an array of integers into a format suited to output on various chip pins. As it stands, I have 8 integers that I want to output to a number of demultiplexer ICs. Each IC requires a 3-bit input. These inputs need to come from a chip with 3 8-bit outputs. The problem therefore is that I need to convert these ints to 3-bit format, string them together to form a 24-bit long word, and then cut that word into 8-bit long chunks for output. This is what I've got so far, but as you can see, the bits don't seem to only partially reflect the correct values. Any idea what's wrong? http://sharebee.com/4c6bd1d8 <-- .c file Any help would be greatly appreciated! ======================================... Code: #include <stdio.h>
#include <stdlib.h>
int main()
{
int short x;
unsigned short led[8] = {1,1,1,1,1,1,1,1};
// PRINTS INTEGER ARRAY
printf("\nLed int array\n========================\n");
for (x=0;x<=7;x++) printf("Led %d = %d\n",x,led[x]);
printf("\n");
// UNION OF 3-BIT NUMBERS AND INDIVIDUAL BITS
union {
struct mini_words //24 bytes?
{
unsigned short a:3;
unsigned short b:3;
unsigned short c:3;
unsigned short d:3;
unsigned short e:3;
unsigned short f:3;
unsigned short g:3;
unsigned short h:3;
} word;
struct bytes
{
unsigned char b0:1;
unsigned char b1:1;
unsigned char b2:1;
unsigned char b3:1;
unsigned char b4:1;
unsigned char b5:1;
unsigned char b6:1;
unsigned char b7:1;
unsigned char b8:1;
unsigned char b9:1;
unsigned char b10:1;
unsigned char b11:1;
unsigned char b12:1;
unsigned char b13:1;
unsigned char b14:1;
unsigned char b15:1;
unsigned char b16:1;
unsigned char b17:1;
unsigned char b18:1;
unsigned char b19:1;
unsigned char b20:1;
unsigned char b21:1;
unsigned char b22:1;
unsigned char b23:1;
unsigned char b24:1;
} b;
} un;
// FILLING STRUCTURE WITH DATA FROM ARRAY
un.word.a=(led[0]);
un.word.b=(led[1]);
un.word.c=(led[2]);
un.word.d=(led[3]);
un.word.e=(led[4]);
un.word.f=(led[5]);
un.word.g=(led[6]);
un.word.h=(led[7]);
// PRINTING CURRENT STATE OF 3-BIT WORDS IN UNION
printf("Assignments to structure\n========================\n");
printf(" %hd ",un.word.a);
printf("%hd ",un.word.b);
printf("%hd ",un.word.c);
printf("%hd ",un.word.d);
printf("%hd ",un.word.e);
printf("%hd ",un.word.f);
printf("%hd ",un.word.g);
printf("%hd\n\n",un.word.h);
printf("Bits in string\n========================\n");
printf("%d",un.b.b0);
printf("%d",un.b.b1);
printf("%d ",un.b.b2);
printf("%d",un.b.b3);
printf("%d",un.b.b4);
printf("%d ",un.b.b5);
printf("%d",un.b.b6);
printf("%d",un.b.b7);
printf("%d ",un.b.b8);
printf("%d",un.b.b9);
printf("%d",un.b.b10);
printf("%d ",un.b.b11);
printf("%d",un.b.b12);
printf("%d",un.b.b13);
printf("%d ",un.b.b14);
printf("%d",un.b.b15);
printf("%d",un.b.b16);
printf("%d ",un.b.b17);
printf("%d",un.b.b18);
printf("%d",un.b.b19);
printf("%d ",un.b.b20);
printf("%d",un.b.b21);
printf("%d",un.b.b22);
printf("%d",un.b.b23);
getch();
return(0);
}
|
| dan56965 is offline | |
| | #2 |
| and the hat of Jobseeking Join Date: Aug 2001 Location: The edge of the known universe
Posts: 21,662
| Try printing out the size of your 'word' struct. My guess is that it isn't 3 (like you're expecting). > unsigned short e:3; > unsigned short f:3; Up to e, you've used 15 bits (bits 0 to 14). But it might be down to the implementation whether the first bit of f ends up in bit 15 (what you want), or bit 16 (the start of the next storage unit, and not what you want). Declaring them as "unsigned long" may (repeat MAY) give the compiler a clue to use a 32-bit underlying storage unit, but it's anyones guess as to whether it will work. http://c-faq.com/struct/bitfields.html If you're trying to map bits in hardware, then bit-fields are not the answer. Sooner or later, you'll come unstuck. Unfortunately, in this case, doing all the bit-bashing yourself is the only way of getting a consistent good answer. |
| Salem is offline | |
| | #3 |
| Registered User Join Date: Jul 2008
Posts: 133
| But this mapping can't work, can it? I mean 8 shorts (16 bytes) into 24 bytes like that... How would you set 3rd byte from a, b, c... exept using b member? EDIT: I may be wrong, but you define word.a as short, being long 3 bytes, but by using normal assignment (un.word.a=...), compiler will treat it as normal short so it will set only 2 bytes of word.a, 3rd you can access only with un.b.b2 or pointer (but it remains unset in this prog). Last edited by rasta_freak; 08-10-2008 at 02:28 PM. |
| rasta_freak is offline | |
| | #4 |
| Kernel hacker Join Date: Jul 2007 Location: Farncombe, Surrey, England
Posts: 15,686
| It took me a few minutes to figure out what the problem was. 3 bits don't make even sets of 16 bits. Unsigned short is a 16-bit integer. Since bitfields do not cross the natural boundary of their constituent base-type, when you have filled 15 bits, the next bit gets padded out. If you change your unsigned short to unsigned long [or "unsigned int" if you use a compiler which has 32-bit integers], then your results will be what I think you expect. Note: I took too long, Salem already answered it... ;-) -- Mats
__________________ Compilers can produce warnings - make the compiler programmers happy: Use them! Please don't PM me for help - and no, I don't do help over instant messengers. |
| matsp is offline | |
| | #5 |
| Registered User Join Date: Jul 2008
Posts: 133
| Can anyone please direct me to some docs where this syntax is explained? I've never used it. Like what exactly is the difference between short:3 & int:3 if they are all 3 bits? |
| rasta_freak is offline | |
| | #6 |
| Registered User Join Date: Aug 2008
Posts: 5
| Salem, Matsp - Thanks for the replies guys... you've been a great help. Defining as long seems to fix it, athough based on what you've said, I'll have a stab at doing it the bit manipulation method instead. That is, unless you're think it'll work on GCC? |
| dan56965 is offline | |
| | #7 | |
| and the Hat of Guessing Join Date: Nov 2007
Posts: 8,803
| Quote:
Edit: Footnote 104 says that if you use plain int, you get signed or unsigned int at your compiler's discretion. | |
| tabstop is online now | |
| | #8 | |
| Kernel hacker Join Date: Jul 2007 Location: Farncombe, Surrey, England
Posts: 15,686
| Quote:
http://www.cs.cf.ac.uk/Dave/C/node13.html Basicly, int x:3 is the same as short x:3 in all aspects except where short and int are differnet size and you have sufficinet sets of 3 bit values to go beyond the number of bits of a short. If we take the generic (C++ style) form: Code: T x:n; T y:n; However, I should point out that there's no obligation to the compiler to actually store x and y in the above example in one T unit, even if T is more bits than 2n. It could just make two T size locations and store each field in one T unit each. The only guarantee is that the value stored will be masked to match the number of bits you have choosen. -- Mats
__________________ Compilers can produce warnings - make the compiler programmers happy: Use them! Please don't PM me for help - and no, I don't do help over instant messengers. | |
| matsp is offline | |
| | #9 |
| Registered User Join Date: Jul 2008
Posts: 133
| Salem, Matsp - - Thanks from me too ![]() EDIT: Ooops, meant Tabstop too.. Last edited by rasta_freak; 08-10-2008 at 03:18 PM. |
| rasta_freak is offline | |
| | #10 | |
| Kernel hacker Join Date: Jul 2007 Location: Farncombe, Surrey, England
Posts: 15,686
| Quote:
Edit: If you are using gcc, then I would actually recommend using "int" instead of "long" - the reason being that if you ever switch to a system that uses 64-bit "long", you'd get unexpected changes versus a system where you have 32-bit "long" values. -- Mats
__________________ Compilers can produce warnings - make the compiler programmers happy: Use them! Please don't PM me for help - and no, I don't do help over instant messengers. Last edited by matsp; 08-11-2008 at 04:12 AM. | |
| matsp is offline | |
| | #11 |
| Registered User Join Date: Aug 2008
Posts: 5
| Hey, just thought I'd add this for the sake of future searchers.... I read about adding undeclared bits in a bit-field, to allow for limited container size. This now works for me without resorting to using long or int variables: Code: union {
struct byte_values
{
unsigned char b0:1;
unsigned char b1:1;
unsigned char b2:1;
unsigned char b3:1;
unsigned char b4:1;
unsigned char b5:1;
unsigned char b6:1;
unsigned char b7:1;
unsigned char b8:1;
unsigned char b9:1;
unsigned char b10:1;
unsigned char b11:1;
unsigned char b12:1;
unsigned char b13:1;
unsigned char b14:1;
unsigned :1;
unsigned char b15:1;
unsigned char b16:1;
unsigned char b17:1;
unsigned char b18:1;
unsigned :8;
unsigned char b19:1;
unsigned char b20:1;
unsigned char b21:1;
unsigned char b22:1;
unsigned char b23:1;
unsigned char b24:1;
unsigned char b25:1;
unsigned char b26:1;
unsigned char b27:1;
unsigned char b28:1;
unsigned char b29:1;
unsigned char b30:1;
unsigned char b31:1;
unsigned char b32:1;
} b;
struct mini_words //24 bits?
{
unsigned short a:3;
unsigned short b:3;
unsigned short c:3;
unsigned short d:3;
unsigned short e:3;
unsigned short f:3;
unsigned short g:3;
unsigned short h:3;
unsigned int y_control:8;
} word;
} un;
|
| dan56965 is offline | |
| | #12 |
| Registered User Join Date: Aug 2008
Posts: 5
| damn, posted the wrong thing there... it should have read like this: Code: union {
struct byte_values
{
unsigned char b0:1;
unsigned char b1:1;
unsigned char b2:1;
unsigned char b3:1;
unsigned char b4:1;
unsigned char b5:1;
unsigned char b6:1;
unsigned char b7:1;
unsigned char b8:1;
unsigned char b9:1;
unsigned char b10:1;
unsigned char b11:1;
unsigned char b12:1;
unsigned char b13:1;
unsigned char b14:1;
unsigned :1;
unsigned char b15:1;
unsigned char b16:1;
unsigned char b17:1;
unsigned char b18:1;
unsigned char b19:1;
unsigned char b20:1;
unsigned char b21:1;
unsigned char b22:1;
unsigned char b23:1;
unsigned :1;
unsigned char b24:1;
unsigned char b25:1;
unsigned char b26:1;
unsigned char b27:1;
unsigned char b28:1;
unsigned char b29:1;
unsigned char b30:1;
unsigned char b31:1;
} b;
struct mini_words //24 bits?
{
unsigned short a:3;
unsigned short b:3;
unsigned short c:3;
unsigned short d:3;
unsigned short e:3;
unsigned short f:3;
unsigned short g:3;
unsigned short h:3;
unsigned int y_control:8;
} word;
} un;
|
| dan56965 is offline | |
| | #13 |
| and the hat of Jobseeking Join Date: Aug 2001 Location: The edge of the known universe
Posts: 21,662
| Saying unsigned short a:3; is no different to unsigned long a:3; it's still only 3 bits. > it should have read like this: Really? Because struct byte_values contains 34 bits. |
| Salem is offline | |
![]() |
| Tags |
| bits, structures, unions |
| Thread Tools | |
| Display Modes | |
|
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Bitwise Operators.... | o0obruceleeo0o | C++ Programming | 21 | 04-09-2003 06:45 AM |
| what is the significance of low order and high order bits | Shadow12345 | Windows Programming | 1 | 11-16-2002 11:46 AM |
| copy some bits into a 8 bits binary number | Unregistered | C Programming | 6 | 05-29-2002 10:54 AM |
| opengl code not working | Unregistered | Windows Programming | 4 | 02-14-2002 10:01 PM |
| Help Please...bits | Unregistered | C Programming | 11 | 01-24-2002 01:43 PM |