Search code examples
cconcatenationpic

Cant combine 2 values together?


I'm using the PIC18lF47k42 with XC8 compiler.
I'm trying to get this full 12bit ADC value so I have the full resolution however, I can't seem to get the 4 bits of data from ADRESL to go into result with the data from ADRESH.
Result is a 16bit variable so it can fit all 12 bits. Any ideas?

Example:

ADRESH = 00110101 ADRESL = 10100000, I want result to = 0000001101011010.

image of output during simulation

#include "myIncludes.h"

volatile unsigned char ZCDSoftwareFlag = 0;
volatile unsigned char switchValue = 0;

void main(void) 
{
    portInit();
    adcInit();
    uint16_t result;                
    while (1)
    {
        ADCON0bits.GO = 1; //Start conversion
        while (ADCON0bits.GO); //Wait for conversion done
       
        result = 0b0000000000000000;
        result = ADRESH << 4;
        result = (result)  | ADRESL;
        //result = (ADRESH << 4) | ADRESL;
    }
}

Solution

  • Apparently you are using the mode that aligns the result to the left (FM = 0).

    Then you can do the combination in two steps:

    1. Put both 8 bit values into a 16 bit variable.
    2. Shift down that value.
            /* ... */
            result = ADRESH;
            result <<= 8;
            result |= ADRESL;
    
            result >>= 4;
            /* ... */
    

    Or, very concise:

            /* ... */
            result = (((uint16_t)ADRESH << 8) | ADRESL) >> 4;
            /* ... */
    

    Notes:

    • If the compiler optimizes well, both suggestions result in the same machine code.
    • The left alignment (FM = 0) might be useful if you have signed results in two's complement. I did not dive into the documentation to see if that is possible.
    • If you select right alignment (FM = 1), you don't need the second step.