Question about adc and adresL

Discussion in 'The Projects Forum' started by hunterage2000, May 22, 2015.

  1. hunterage2000

    Thread Starter Active Member

    May 2, 2010
    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 (Text):
    1. void main() {
    3.     TRISC = 0;
    4.     ANSELbits.ANS2 = 1;
    5.     CMCON0bits.CM = 0;
    6.     ADCON1bits.ADCS = 0b001;
    7.     ADCON0bits.ADFM = 1;
    8.     ADCON0bits.VCFG = 0;
    9.     ADCON0bits.CHS = 0b010;
    10.     ADCON0bits.ADON = 1;
    12.     for(;;)
    13.     {
    14.         __delay_us(10);
    15.         ADCON0bits.GO = 1;
    16.         while(ADCON0bits.nDONE)
    17.             ;
    18.         if (ADRESL > 0b00011111)
    19.             PORTCbits.RC2 = 1;
    20.         if (ADRESL < 0b00011111)
    21.             PORTCbits.RC2 = 0;
    23.     }
    25. }
  2. tshuck

    Well-Known Member

    Oct 18, 2012
    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.
  3. hunterage2000

    Thread Starter Active Member

    May 2, 2010
    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?
  4. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    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.
  5. tshuck

    Well-Known Member

    Oct 18, 2012
    Remember the shift operator in C? You could even use multiplication (the compiler should convert it to a shift operation anyway).
    Code (Text):
    2. //to get the 10-bit value
    3. int value = ADRESH;
    4. //left justified
    5. value = (value << 2) + (ADRESL >> 6);
    6. //right justified
    7. value = (value << 8) + ADRESL;