Question about adc and adresL

Thread Starter

hunterage2000

Joined May 2, 2010
487
I have tried using the following code to turn on an led if a pot is below halfway and off if above it but it is not working. I'm still trying to figure out how the adresh and adresl works. I thought I could just use a decimal value of < 511 of 1023 but that didn't allow it. Can anyone help?

Code:
void main() {

    TRISC = 0;
    ANSELbits.ANS2 = 1;
    CMCON0bits.CM = 0;
    ADCON1bits.ADCS = 0b001;
    ADCON0bits.ADFM = 1;
    ADCON0bits.VCFG = 0;
    ADCON0bits.CHS = 0b010;
    ADCON0bits.ADON = 1;

    for(;;)
    {
        __delay_us(10);
        ADCON0bits.GO = 1;
        while(ADCON0bits.nDONE)
            ;
        if (ADRESL > 0b00011111)
            PORTCbits.RC2 = 1;
        if (ADRESL < 0b00011111)
            PORTCbits.RC2 = 0;

    }
   
}
 

tshuck

Joined Oct 18, 2012
3,534
Without knowing what PIC you are using, this will have to be generic information.

ADRESL is an 8-bit register (i.e. it only has the ability to hold 0-255). ADRESH is another 8-bit register that will contain the other part of the conversion.

Now, the ADC result is 10-bit, so the result will be placed in both ADRESL and ADRESH. How it is placed depends on what justification you have set in the ADCONn register. One way (left justification) will place the most significant 8-bits in ADRESH and the least significant two bits in the upper two bits of ADRESL. The other way (right justification) will place the least significant 8-bits in ADRESL while planning the two most significant bits into the lower two bits of ADRESH.

This information will be in the datasheet.

So, if you want a 10-bit number, you'll have to read the data from the two locations and shift and concatenate as applicable for your data justification.
Note: make sure you use a data type that is large enough for the manipulations.

However, an easier way, since you don't really need 10 bits, would be to set the ADC to use left justification, read ADRESH, and test the most significant bit of ADRESH - if it is set, the voltage is above half of the ADC reference voltage, otherwise, or is less or equal.
 

Thread Starter

hunterage2000

Joined May 2, 2010
487
so what if I wanted to store a 10 bit value. Can you take an upper 8 bit value and a lower 2 bit value and put them in a single variable?
 

ErnieM

Joined Apr 24, 2011
8,377
I can, do it all the time.

Hint: it is easier if they are right justified.

I leave left justified for those times I just want 8 bits out of 10.
 

tshuck

Joined Oct 18, 2012
3,534
so what if I wanted to store a 10 bit value. Can you take an upper 8 bit value and a lower 2 bit value and put them in a single variable?
Remember the shift operator in C? You could even use multiplication (the compiler should convert it to a shift operation anyway).
Code:
//to get the 10-bit value
int value = ADRESH;
//left justified
value = (value << 2) + (ADRESL >> 6);
//right justified
value = (value << 8) + ADRESL;
 
Top