Computing > Programming

2 byte value into 2 separate 1 byte values

(1/13) > >>

etnel:
Hello, I'm currently trying to store 2 values of 2 bytes each to the EEPROM to my PIC16f1827. The EEPROM stores single bytes. How would I divide my value into 2 bytes to write them? And how do I then read them into one single value again?

Kleinstein:
In C there is the union structure. This way the same memory space can be accessed in different ways, e.g. as an integer or as 2 bytes.
Which of the byte is the high and low byte depends on the CPU used, but for storage this should no be an issue.

An alterntive would be to use a pointer and do a cast ont he pointer type.

A protable way is to use bit masks and shifts for a conversion.

golden_labels:
(Language not specified; assuming C from the context)

The second option offered by Kleinstein is fine. Casting to a char* is portable and well-defined in this particular scenario: the data is not expected to be exchanged with other code, so endianess, ranges, alignment and trap representations are not an issue. The exception to this is using a different compiler or options and wishing to maintain the same EEPROM data. If that’s the case, you may consider the third option. But I would not waste time on doing so until such a neccessity arises. Not laziness; quite opposite: code quality. This is the simplest method, with no potential for introducing subtle bugs, and easiest for compilers to implement efficiently.

Unions in this case give no advantages: that would only cause more noise in the code. The behaviour is identical.

TheCalligrapher:

--- Quote from: etnel on July 15, 2021, 06:50:03 pm ---Hello, I'm currently trying to store 2 values of 2 bytes each to the EEPROM to my PIC16f1827. The EEPROM stores single bytes. How would I divide my value into 2 bytes to write them? And how do I then read them into one single value again?

--- End quote ---

Very simple. If `V` is your two-byte value, then lower [8-bit] byte is obtained as `V % 256` and upper byte is obtained as `V / 256`. If you so prefer, you can replace division by shifting and masking. Makes no difference. One might also add that it is preferrable to perform operations like that in the domain of an unsigned integer type.

This is always more efficient (or as efficient as) that any alternative approaches based on type punning through unions, casting to `unsigned char *` or somesuch.  Never use type punning unless you absolutely have to.

AntiProtonBoy:
memcpy is your friend here.

Navigation

[0] Message Index

[#] Next page

There was an error while thanking
Thanking...
Go to full version