user2819759
user2819759

Reputation: 95

How to concatenate hex byte array to long int without using union in C?

I have an array. Array bytes are in hexadecimal. Now I am trying to concatenate array index 1 to 4 in to unsigned long int and 5 to 8 in to one more unsigned long int and index 9 and 10 to unsigned int. I tried like this. But it's not working. I do not want to use union to concatenate. I am using this code in STM32F4-Discovery.

This is a receive interrupt Handler function :

  void usart1_IRqHandler()
  {
  unsigned char received_string[20];
  unsigned long int Addr1=0,Addr2=0;
  unsigned int Addr=0;
  
  /*Code to Receive Entire packet.......
   .....................................
   .....................................
  At this point whole packet is received, now I want to send back the response to the target node using address from received data, So first step is to concatenate address bytes*/ 
  
  /*From the logic analyzer I can observe the received_string bytes as shown below 
  received_string[1]=0x00; 
  received_string[2]=0x13;
  received_string[3]=0xA2;
  received_string[4]=0x00;

  received_string[5]=0x40;
  received_string[6]=0xB4;
  received_string[7]=0x14;
  received_string[8]=0x35;

  received_string[9]=0x8E;
  received_string[10]=0xC7;*/

  Addr1 =  (received_string[1]<<24)| (received_string[2]<<16)| (received_string[3]  <<8)| received_string[4]);
  Addr2 =  (received_string[5]<<24)| (received_string[6]<<16)|(received_string[7]  <<8)| received_string[8]);           
  Addr =  (received_string[9]<<8)| (received_string[10]);   

  Send_packet(Addr1,Addr2,Addr);
  }

Function Send Packet will target remote node with these address.

     Send_packet(unsigned long int Addr1,unsigned long int Addr1,unsigned int Addr)
    {
      unsigned char tx_buf[20];
      tx_buf[5]=(Addr1>>24) & 0xff;
      tx_buf[6]=(Addr1>>16) & 0xff;
      tx_buf[7]=(Addr1>>8)  & 0xff;
      tx_buf[8]=(Addr1>>0)  & 0xff;

      tx_buf[9]=(Addr2>>24)  & 0xff;
      tx_buf[10]=(Addr2>>16) & 0xff;
      tx_buf[11]=(Addr3>>8)  & 0xff;
      tx_buf[12]=(Addr4>>0)  & 0xff;

      tx_buf[9]=(Addr2>>8)  & 0xff;
      tx_buf[10]=(Addr2>>0) & 0xff;
     
      usart_send(tx_buf);
      
   }

This is the output of sending packet in logic analyzer.

  Addr1=0xA2401437
  Addr2=0x025500A2
  Addr=0x4014

Since the address does not matched, I am not able to target the remote node.

Upvotes: 0

Views: 651

Answers (2)

wovano
wovano

Reputation: 5093

The question is missing a minimal reproducable example and lacks details on how the information was acquired. However, the basic idea of how to convert the number is correct (the code in the question does not compile, so there's no way to tell what code was actually tested by the OP).

Below is an example that demonstrates it's working:

#include <stdio.h>

int main()
{
    unsigned char received_string[20];
    
    received_string[1] = 0x00;
    received_string[2] = 0x13;
    received_string[3] = 0xA2;
    received_string[4] = 0x00;
    
    received_string[5] = 0x40;
    received_string[6] = 0xB4;
    received_string[7] = 0x14;
    received_string[8] = 0x35;

    received_string[9] = 0x8E;
    received_string[10] = 0xC7;
    
    unsigned long int Addr1 = (received_string[1] << 24) | (received_string[2] << 16) | 
                              (received_string[3] << 8) | received_string[4];
    unsigned long int Addr2 = (received_string[5] << 24) | (received_string[6] << 16) | 
                              (received_string[7] << 8) | received_string[8];
    unsigned int Addr = (received_string[9] << 8) | (received_string[10]);
    
    printf("Addr1 = %08lX\n", Addr1);
    printf("Addr2 = %08lX\n", Addr2);
    printf("Addr = %04X\n", Addr);

    return 0;
}

This will print:

Addr1 = 0013A200
Addr2 = 40B41435
Addr = 8EC7

NB: As correctly stated by user M.M. in a comment on the answer of Yasir Majeed, the masking is entirely unnecessary. It will either be optimized away by the compiler or insert useless instructions.

Note, however, that to make this code more portable, the bytes should be cast to unsigned long before shifting. Otherwise, this will fail on platforms where sizeof(int) < 4.

Upvotes: 1

Yasir Majeed
Yasir Majeed

Reputation: 741

int i = ((received_string[0] << 24) & 0xff000000) |
                ((received_string[1] << 16) & 0x00ff0000) |
                ((received_string[2] << 8) & 0x0000ff00) |
                ((received_string[3] << 0) & 0x000000ff);

This will construct the unsigned int for you. You can change the indexes of my example to your desired indexes

Upvotes: 0

Related Questions