How to convert an int to two bytes in C / C ++?

19

I get the data from a temperature sensor on a microcontroller that has a 10-bit AD converter. I store the data in a variable of type int (of 32 bits), and I need to send this data via serial communication. For this, I need to convert this value int to type byte , but since they are 10 bits if I convert to just a byte I will lose information, so I need to convert int to two bytes so I can transmit one byte at a time through the serial port. I will also need to convert these two bytes to an integer value again.

How do I convert a int to two bytes and two bytes to a int again, using C/C++ ?

    
asked by anonymous 03.04.2014 / 19:03

4 answers

20

Something we have to clarify before is that the type int on modern platforms has 4 bytes . This is a problem because it is impossible to make 4 bytes fit within 2 bytes , is not it?!

On the other hand, there is a guarantee that type short int occupies at least 2 bytes on any platform. These statements can be easily verified by sizeof() , which returns the number of bytes that a given type of data occupies:

printf("%d\n", sizeof(int));
printf("%d\n", sizeof(short int));

In this way, this answer assumes that you would like to separate each byte of a variable short int .

To perform this task, we can use a bit mask , which involves the implementation of operations of binary logic ( bitwise operations ) and bit shift ) to extract the 8 bits that interest us from the original variable.

To begin this task, we declare and initialize an appropriate variable:

short int num = 42345;

It is interesting to note that the number 42345 in the decimal base is represented by 1010 0101 0110 1001 in the binary base system. It is relevant to know this because after the separation occurs, we will have a unsigned char variable to store the first byte - > % with% (105), and another variable 0110 1001 to store the second byte - > unsigned char (165).

To extract the first byte of 1010 0101 :

unsigned char byte1 = (num & 255);          // Ou: (num & 0xFF)
printf("%d\n\n", byte1);

To extract the second byte of num :

unsigned char byte2 = ((num >> 8) & 255);   // Ou: ((num >> 8) & 0xFF);
printf("%d\n", byte2);

The purpose of the answer is not to discuss how masks work, but to demonstrate how the problem could be solved in this way. There are more than a hundred programming books and many more online logs that describe in detail the operation of bitmasks.

Good luck!

    
05.04.2014 / 23:53
11

Convert valor to 2 bytes:

byte[0] = valor / 256;
byte[1] = valor % 256;

Convert two bytes

valor = byte[0] * 256 + byte[1];

This for Big Endian, if you prefer Little Endian, swap the bytes

    
03.04.2014 / 19:11
9

You can use union to do this type of operation.

This way:

union Valor
{
    uint32_t dword;

    struct
    {
        uint32_t valor;
    };

    struct
    {
        uint16_t word0;
        uint16_t word1;
    };

    struct
    {
        uint8_t byte0;
        uint8_t byte1;
        uint8_t byte2;
        uint8_t byte3;
    };
};

But, make sure the compiler supports this before. I say this because it has a very limited microcontroller compiler. The variables uint32_t , uint16_t , and uint8_t may have another name depending on the compiler (version, platform and etc), but are usually set to #include <stdint.h> .

Int for 2 bytes

Then you use it like this:

Valor var;
var.valor = 700;

printf("Valor = %d\n", var.valor);
printf("Byte 0 = %d\n", var.byte0);
printf("Byte 1 = %d\n", var.byte1);
printf("Word 0 = %d\n", var.word0);

As you want 2 bytes, you want word0 (for Big Endian).

It can also be:

uint32_t variavel_qualquer = 700;
Valor* var = (Valor*) &variavel_qualquer;
printf("Word 0 = %d\n", var->word0);

2 bytes for Int

Valor var;
var.valor = 0; // Para garantir que estará tudo zero.

var.byte0 = 188;
var.byte1 = 2;

printf("Resultado = %d", var.valor); // Retorna 700

No IdeOne: link

    
03.04.2014 / 19:23
1

The simplest way is to use the Shift and Bit-Wise operators, mainly because it is easily mapped to an equivalent Assembly statement and as we are in a context of microcontroller It is crucial that we have the most optimized code possible.

int orig = 0x0403;
byte dest[4];

// para converter de inteiro para byte
dest[0] = orig         & 0xff;
dest[1] = (orig >> 8)  & 0xff; 
dest[2] = (orig >> 16)  & 0xff; 
dest[3] = (orig >> 24)  & 0xff; 

// para retornar os dois byte para um inteiro
orig = (dest[3] << 24) + (dest[2] << 16) + (dest[1] << 8) + dest[0]
    
09.07.2015 / 17:09