Ahmed Fradi
Ahmed Fradi

Reputation: 3

how Converting 2 arrays of bytes (uint8_t) into a word (uint16_t)?

I want to convert two times the Signal[8] values into a uint16_t word, so I can send it via the SPI port.(shift register)?

I tried the following, but it doesn't work: the code was like that, my you can compile it.

void senddata(void){
    
    uint8_t NZero = 0;
    uint16_t timeout;
    uint8_t value ;
    volatile uint8_t Signal[8]={RGB_NC_0, RGB_1, RGB_2, RGB_3, RGB_4, RGB_5, RGB_6, RGB_NC_7}; // to be set by the state machine
    volatile uint8_t SPIData[16]={0};
    
for(int i=0;i<8;i++){
        nonZero|= Signal[i];
        }
  int i , j;
  //Set LATCH low
    GPIO_WriteBit(LED_LATCH_PORT, LED_LATCH, Bit_RESET);
    //Set blank high
    GPIO_WriteBit(LED_BLANK_PORT, LED_BLANK, Bit_SET);
    //Enable SPI
    SPI_Cmd(LED_SPI, ENABLE);
  //iterate through the registers
    for(i = 2 - 1; i >=  0; i--){
  //iterate through the bits in each registers
        for(j = 8 - 1; j >=  0; j--){
           valr = Signal[i] & (1 << j);
            SPI_I2S_SendData(LED_SPI, value);
          while(SPI_I2S_GetFlagStatus(LED_SPI, SPI_I2S_FLAG_TXE) == 0 && timeout < 0xFFFF) //Odota että TXE=1
        { timeout++; }
        if(timeout == 0xFFFF){break;}
                    }
    }

    SPI_Cmd(LED_SPI, DISABLE); /*!< SPI disable */
        
    GPIO_WriteBit(LED_LATCH_PORT, LED_LATCH, Bit_SET);//Set LATCH high
        if(NZero){
            GPIO_WriteBit(LED_BLANK_PORT, LED_BLANK, Bit_RESET);//Set BLANK low
    }
    else{
            GPIO_WriteBit(LED_BLANK_PORT, LED_BLANK, Bit_SET);//Set BLANK high
    }

 }

Upvotes: 0

Views: 170

Answers (2)

Aconcagua
Aconcagua

Reputation: 25536

You can combine each subsequent two bytes into the SPI port register as follows:

for(size_t i = 0; i < sizeof(signal/sizeof(*signal); i += 2)
{
    spiPortRegister = (uint16_t)signal[i + 0] << 0
                    | (uint16_t)signal[i + 1] << 8;
    // send via SPI here!
}
// a *totally* generic implementation might add special handling for
// odd arrays, in your specific case you can omit... 

Analogously you split back on receiver side:

for(size_t i = 0; i < sizeof(signal/sizeof(*signal); i += 2)
{
    // receive via SPI here
    signal[i + 0] = (uint8_t) spiPortRegister >> 0;
    signal[i + 1] = (uint8_t) spiPortRegister >> 8;
}

Note: Additions or shifts by 0 are unnecessary and only added for code consistency; they will be optimised away by compiler anyway, but you can omit, if you prefer. Similarly the casts in second case, but these in addition silent the compiler from warning about precision loss.

Note, though, that even though promotion to int occurs in first case int might only be of size of 16 bits – and as you apparently operate on a MCU chances for rise – in which case the shift could provoke overflow, thus undefined behaviour, thus the cast should be applied in any case!

Upvotes: 2

0___________
0___________

Reputation: 67745

Endianness independent

uint16_t get16(volatile uint8_t *table)
{
    return *table | ((uint16_t)*(table + 1) << 8);
}

or depending on endianess

uint16_t get16(volatile uint8_t *table)
{
    uint16_t result;
    memcpy(&result, table, sizeof(result));
    return result;
}

Upvotes: 2

Related Questions