C code: left shift is shifted, but the upper bits

I am doing a small embedded project, where I have 40 bits transferred via an interface like SPI. I pull these bits from the 32-bit bus and put the upper 32 bits into the variable uint32_tand the lower 8 bits into the variable uint8_t. I try to combine them into one uint64_t. However, when I shift to 8, it drops to the top 8 bits. Here is my code.

uint64_t getError()
{
    uint32_t * disp_addr = (uint32_t*)(MYDISPLAY);

    uint64_t error_upper;
    uint8_t error_lower;
    uint64_t error= 0;

    error_lower = *(disp_addr+1);
    error_upper = *(disp_addr+0);
    error = ((uint64_t) error_upper) <<8 | error_lower;
    return error;
}

This code works, except that it removes my 8 upper bits. Any thoughts or hints would be greatly appreciated. Thank.

change

uint64_t getError()
{
    uint32_t * disp_addr = (uint32_t*)(MYDISPLAY);

    uint64_t error_upper;
    uint8_t error_lower;
    uint64_t error= 0;

    error_lower = 0x34;
    error_upper = 0xABCDEF12;
    error = ((uint64_t) error_upper) <<8 | error_lower;
    printf("%010x", error);
    //return error;
}

Results: 00cdef1234

+4
source share
3 answers

The format printfspecifier is invalid.

#include <stdio.h>

typedef unsigned __int64 uint64_t;
typedef unsigned char uint8_t;

int main(void) {
    uint64_t error_upper, error;
    uint8_t error_lower;

    error_lower = 0x34;
    error_upper = 0xABCEDF12;
    error = (error_upper << 8) | error_lower;
    printf("%x\n", error);
    printf("%llx\n", error);
    return 0;
}

Program output:

cedf1234
abcedf1234
+4
source

, ? , :

uint32_t temp = 0x01020304;
uint32_t *disp_addr = &temp;
uint64_t error_upper;
uint8_t error_lower;
uint64_t error= 0;

error_lower = *(disp_addr+1);
error_upper = *(disp_addr+0);
error = (error_upper<<8) | error_lower;

printf("\n%08X%08X\n",  (uint32_t)(error>>32), error);

0000000102030401

%d ?

0

Look carefully at

uint32_t *disp_addr = &temp;
...
error_lower = *(disp_addr+0);

Since disp_addrthis is ptr to uint32_t, you store the 32-bit value in an 8-bit variable. Depending on your endiannes computer and how you download disp_addr, you may not download the correct data.

You probably wanted to:

uint32_t *disp_addr = &temp;
...
error_lower = *(uint8_t *)(disp_addr+0);

which is not the same.

-1
source

Source: https://habr.com/ru/post/1589029/


All Articles