Hello everybody,
I am very new to C language. In my project I get data serially from a port pin. I want to save the first 8 bits to one variable, another to second & so on. In all I want to save 32 bits in 4 bytes. Can you suggest C code.
I know it in assembly by using RRC or RLC, but how to achieve it in C?
Thanks
It shouldn't be too complicated. Something is the lines of:
BOOL data_full; BYTE bits_received; insigned int data_received; // initialise global variables; data_full = __FALSE; bits_received = 0; data_received = 0; interrupt_handler() { if(DATA) { data_received =| ( 1 << bits_received ); } bits_received++; if(bits_received == 32) { bits_received = 0; data_full = __TRUE; // do something with data_received. } }
Thanks, that is exactly what I needed. The BOOL, BYTE, __FALSE & __TRUE keywords gave errors in compiling. So I replaced them with bit, unsigned char, 0 & 1 respectively. Now it compiles without errors.
Though I have not tested my project, I will let you know as soon as I test it.
And you manage to fit 32 bits in the following variable?
unsigned int data_received;
Good lord, why use this indentation
if(DATA) { data_received =| ( 1 << bits_received ); }
when you can do this
if(DATA) { data_received =| ( 1 << bits_received ) ; // I always add a trailing space }
The horror, the horror...
I always add a trailing space
Ohh. Very Noël Coward.
Yes, I think it should be
unsigned long data_received;
Also the statement
data_received =| ( 1 << bits_received );
gave me error. So I replaced it with
data_received |= ( 1 << bits_received );
What does |= mean? Anyway the code works perfectly, thanks!
Now in main routine, I want to split up the 32bit int into four 8bit variables. Then using lookup table I want to convert them. Your help will be highly appreciated.
Actually, I prefer Jackson Pollock.
yes, sorry my mistake was ment to be:
it is the same than:
data_received = data_received | ( 1 << bits_received );
to split just do a byte *** operation
BYTE bo, b1, b2, b3; b0 = (data_received & 0x000000FF) b1 = (data_received & 0x0000FF00) >> 8; b2 = (data_received & 0x00FF0000) >> 16; b3 = (data_received & 0xFF000000) >> 24;
may need a BYTE cast
if (DATA) { data_received |= (1 << bits_received); // I always add a trailing space }
Indentation is religion. There are no "right" indentation.
Consider unsigned long prefixes:
b3 = (data_received & 0xFF000000ul) >> 24;
Some compilers will complain about constants out of range if you don't tell they are long. Some compilers will complain about mixing of signed and unsigned if you don't tell that your constant is unsigned.
Some compilers will like shift befure and, just so they can pick up a byte directly instead of having an 8-bit processor doing a 32-bit and operation. Not sure if Keil C51 will detect and optimize. Or even go one step further and skip the shift too - just pick up the relevant byte directly from memory.
sorry, was thinking in integer size in windows 32.
In terms of indentation religion I'm a pastafarian.
Hmmmmm.
Thank you christian crosa, Per Westermark.
I will try this. While searching for this I came across a solution which uses union
stackoverflow.com/.../how-do-i-split-up-a-long-value-32-bits-into-four-char-variables-8bits-using
union { unsigned long position; unsigned char bytes[4]; } CurrentPosition; CurrentPosition.position = 7654321;
The bytes can now be accessed as: CurrentPosition.bytes[0], ..., CurrentPosition.bytes[3]
Though I will be using your approach which seems very simple to me. Just asking for my knowledge, can union be used for this conversion?
yep, the use of the union should work too.
I came across a solution which uses union
Be careful with these things! Read about them here:
c-faq.com/.../index.html
In particular, see here:
c-faq.com/.../taggedunion.html