Search code examples
cfunctionhexprintf32-bit

32-bits as hex number in C with simple function call


I would like to know if I could get away with using printf to print 32 bits of incoming binary data from a microcontroller as a hexadecimal number. I already have collected the bits into an large integer variable and I'm trying "%x" option in printf but all I seem to get are 8-bit values, although I can't tell if that's a limitation with printf or my microcontroller is actually returning that value.

Here's my code to receive data from the microcontroller:

 printf("Receiving...\n");
 unsigned int n=0,b=0;
 unsigned long lnum=0;
 b=iolpt(1); //call to tell micro we want to read 32 bits
 for (n=0;n<32;n++){
     b=iolpt(1); //read bit one at a time
     printf("Bit %d of 32 = %d\n",n,b);
     lnum<<1; //shift bits in our big number left by 1 position
     lnum+=b; //and add new value
 }
 printf("\n Data returned: %x\n",lnum); //always returns 8-bits

The iolpt() function always returns the bit read from the microcontroller and the value returned is a 0 or 1.

Is my idea of using %x acceptable for a 32-bit hexadecimal number or should I attempt something like "%lx" instead of "%x" to try to represent long hex even though its documented nowhere or is printf the wrong function for 32-bit hex? If its the wrong function then is there a function I can use that works, or am I forced to break up my long number into four 8-bit numbers first?


Solution

  • printf("Receiving...\n");
    
    iolpt(1); // Tell micro we want to read 32 bits.
        /*  Is this correct?  It looks pretty simple to be
            initiating a read.  It is the same as the calls
            below, iolpt(1), so what makes it different?
            Just because it is first?
        */
    
    unsigned long lnum = 0;
    for (unsigned n = 0; n < 32; n++)
    {
        unsigned b = iolpt(1); // Read bits one at a time.
        printf("Bit %u of 32 = %u.\n", n, b);
        lnum <<= 1; // Shift bits in our big number left by 1 position.
            // Note this was changed to "lnum <<= 1" from "lnum << 1".
        lnum += b; // And add new value.
    }
    
    printf("\n Data returned: %08lx\n", lnum);
        /*  Use:
                0 to request leading zeros (instead of the default spaces).
                8 to request a field width of 8.
                l to specify long.
                x to specify unsigned and hexadecimal.
        */
    

    Fixed:

    • lnum<<1; to lnum <<= 1;.
    • %x in final printf to %08lx.
    • %d in printf in loop to %u, in two places.

    Also, cleaned up:

    • Removed b= in initial b=iolpt(1); since it is unused.
    • Moved definition of b inside loop to limit its scope.
    • Moved definition of n into for to limit its scope.
    • Used proper capitalization and punctuation in comments to improve clarity and aesthetics.