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.
#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;
}
}
CodePudding user response:
Apparently you are using the mode that aligns the result to the left (FM
= 0).
Then you can do the combination in two steps:
- Put both 8 bit values into a 16 bit variable.
- 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.