• AVR Freaks

Hot!Problem reading ADC ADRESH and ADRESL registers; result out of range

Page: 123 > Showing page 1 of 3
Author
mlman
New Member
  • Total Posts : 18
  • Reward points : 0
  • Joined: 2020/03/16 09:13:57
  • Location: 0
  • Status: offline
2020/04/04 17:41:24 (permalink)
0

Problem reading ADC ADRESH and ADRESL registers; result out of range

PIC: 12F1572 (Enhanced 8-bit)
Dev: MPLAB X IDE
Brd: Curiosity 8-Bit
 
I have larger assembly language program reading the 10-bit ADC output and storing it in an array to average using the timer 0 and ADC interrupts and everything seems to work except the AD readings do not change and/or are invalid.. The ADC results are right justified.
 
In my main project, I have the Curiosity board potentiometer output jumpered to RA0 pin 7 making RA0 input voltage adjustable from 0-3.0V (Vdd=3.3V). At 1.0V on RA0, I would expect the ADC reading to be ~0X0136 (0310D) but it reads 0X0009 to 0X000B regardless of the voltage at RA0?
 
To troubleshoot my problem, I copied the following code from the 12F157X datasheets to see if I could just read the ADC without the extra junk.  Now RA0 input reads 0X35CD (>10 bits!). I change the voltage to RA0 but it always reads 0X35CD???
 
#include    "p12f1572.inc"
    LIST    P=12F1572, N=44, B=4 ;12F1572,44 Lines/Pg Landscape,4 Spaces/Tab       

;CONFIGURATION
            ;Int reset, internal oscillator (no clock out), no watchdog,
            ;Brownout resets on, no power-up timer, no code protect
            ;No write protection, stack resets on, low brownout voltage,
            ;No low-power brownout reset, high-voltage programming, no pwm

    __CONFIG _CONFIG1, _MCLRE_OFF & _FOSC_INTOSC & _CLKOUTEN_OFF & _WDTE_OFF & _BOREN_ON & _PWRTE_OFF & _CP_OFF
    __CONFIG _CONFIG2, _LVP_ON & _WRT_OFF & _STVREN_ON & _BORV_LO & _PLLEN_OFF
     UDATA
ADCRESULT       res 2          ;ADC result storage register

RESVECT CODE  0x0000
    BANKSEL      ADCON1 ;
    MOVLW        b'11110000' ;Right justify, FRC oscillator
    MOVWF        ADCON1      ;Vdd and Vss Vref+
    BANKSEL      TRISA
    BSF             TRISA,0       ;Set RA0 to input
    BANKSEL     ANSELA
    BSF             ANSELA,0    ;Set RA0 to analog
    BANKSEL     WPUA
    BCF            WPUA,0        ;Disable weak pull-up on RA0
    BANKSEL    ADCON0
    MOVLW      b'00000001'  ;Select channel AN0
    MOVWF      ADCON0       ;Turn ADC On
    BSF           ADCON0,0     ;Start conversion set bit 0=1 ADCON0
    BTFSC       ADCON0,0     ;Is conversion done? ADCON0 bit 0=0
    GOTO        $-1               ;No, check again
    BANKSEL ADRESH          ;Yes, read ADC
    MOVF ADRESH,W           ;Read upper 2 bits
    MOVWF ADCRESULT+1   ;Store in GPR space
    BANKSEL ADRESL
    MOVF ADRESL,W            ;Read lower 8 bits
    MOVWF ADCRESULT       ;Store in GPR space
    
MAINLP    goto $
    END
I have spent a lot of time on this but am unable to figure it out.  How hard can it be to read the ADC?  Any help would be greatly appreciated.
 
#1

41 Replies Related Threads

    jtemples
    عُضْوٌ جَدِيد
    • Total Posts : 11813
    • Reward points : 0
    • Joined: 2004/02/13 12:31:19
    • Location: Southern California
    • Status: offline
    Re: Problem reading ADC ADRESH and ADRESL registers; result out of range 2020/04/04 18:09:11 (permalink)
    +2 (2)
    Several of your comments on the ADC are wrong, most notably you're not checking the GO/DONE  bit.
    #2
    ric
    Super Member
    • Total Posts : 26942
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: Problem reading ADC ADRESH and ADRESL registers; result out of range 2020/04/04 19:28:41 (permalink)
    +3 (3)
    jtemples
    Several of your comments on the ADC are wrong, most notably you're not checking the GO/DONE  bit.

    +1
    The code is attempting to, but it is setting & checking the wrong bit.
    i.e
        BSF ADCON0,0        ;Start conversion set bit 0 ADCON0
        BTFSC ADCON0,0      ;Is conversion done? ADCON0 bit 0 = 0

    should be:
        BSF ADCON0,1        ;Start conversion set GO bit in ADCON0
        BTFSC ADCON0,1      ;Is conversion done? ADCON0 GO bit = 0

     
    It would be safer to use the predefined names
        BSF ADCON0,GO        ;Start conversion set GO/DONE bit in ADCON0
        BTFSC ADCON0,GO      ;Is conversion done? ADCON0 GO/DONE = 0

     
    All the bits of that register are defined in p12F1572.inc
    ;----- ADCON0 Bits -----------------------------------------------------
    ADON             EQU  H'0000'
    GO_NOT_DONE      EQU  H'0001'
    CHS0             EQU  H'0002'
    CHS1             EQU  H'0003'
    CHS2             EQU  H'0004'
    CHS3             EQU  H'0005'
    CHS4             EQU  H'0006'

    ADGO             EQU  H'0001'

    GO               EQU  H'0001'

    NOT_DONE         EQU  H'0001'


    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #3
    1and0
    Access is Denied
    • Total Posts : 10779
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Problem reading ADC ADRESH and ADRESL registers; result out of range 2020/04/04 22:09:38 (permalink)
    +1 (1)
    • As others said, the GO/DONE bit is bit 1 of ADCON0. Use symbol instead of magic number.
    • There's no acquisition delay (sampling time).
    • How do you know ADCRESULT registers are located in same bank as ADRESH:L?
    • Try reading the ADC in the main loop.
    #4
    mlman
    New Member
    • Total Posts : 18
    • Reward points : 0
    • Joined: 2020/03/16 09:13:57
    • Location: 0
    • Status: offline
    Re: Problem reading ADC ADRESH and ADRESL registers; result out of range 2020/04/05 07:18:29 (permalink)
    0
    Thanks everyone for all the input but, after the changes, the ADC readings now match my original project where
    the ADC reads 0X000A regardless of the voltage at RA0.  This occurred both with and without the new delay loop in this revised code.  I still cannot read the voltage on RA0!
     
    #include    "p12f1572.inc"
          LIST    P=12F1572, N=44, B=4 ;12F1572,44 Lines/Pg Landscape,4 Spaces/Tab       
                    ;CONFIGURATION
                    ;Int reset, internal oscillator (no clock out), no watchdog,
                    ;Brownout resets on, no power-up timer, no code protect
                    ;No write protection, stack resets on, low brownout voltage,
                    ;No low-power brownout reset, high-voltage programming, no pwm

        __CONFIG _CONFIG1, _MCLRE_OFF & _FOSC_INTOSC & _CLKOUTEN_OFF & _WDTE_OFF & _BOREN_ON & _PWRTE_OFF & _CP_OFF
        __CONFIG _CONFIG2, _LVP_ON & _WRT_OFF & _STVREN_ON & _BORV_LO & _PLLEN_OFF
         UDATA
    ADCRESULT res 2                 ;10-bit ADC result
    DC1            res 1                 ;Delay loop counters
    DC2            res 1

    RESVECT CODE        0x0000
                BANKSEL        ADCON1
                MOVLW        b'11110000'     ;Right justify, FRC oscillator
                MOVWF        ADCON1          ;Vdd and Vss Vref+
                BANKSEL     TRISA
                BSF             TRISA,0           ;Set RA0 to input
                BANKSEL      ANSELA
                BSF              ANSELA,0       ;Set RA0 to analog
                BANKSEL      WPUA
                BCF              WPUA,0         ;Disable weak pull-up on RA0
                BANKSEL       ADCON0
                MOVLW          b'00000001' ;Select channel AN0
                MOVWF         ADCON0       ;Turn ADC On

    MAINLP
                BANKSEL      ADCON0
                BSF             ADCON0,GO   ;Start conversion set GO/DONE bit in ADCON0
                BTFSC         ADCON0,GO   ;Is conversion done? ADCON0 GO/DONE = 0    
                GOTO          $-1                ;No, test again
                BANKSEL     ADRESH         ;Yes, read ADC
                MOVF          ADRESH,W     ;Read upper 2 bits
                BANKSEL     ADCRESULT
                MOVWF       ADCRESULT+1 ;Store in GPR space
                BANKSEL     ADRESL
                MOVF          ADRESL,W     ;Read lower 8 bits
                BANKSEL     ADCRESULT
                MOVWF       ADCRESULT   ;Store in GPR space
                ;Delay 500 ms
                banksel       DC1              ;Outer loop: 81 x (767 + 3) + 3
                movlw         .81               ;  = 62,373 cycles
                movwf         DC2             ;  = 499.0 ms @ 8 us/cycle
                clrf              DC1             ;Inner loop: 256 x 3 - 1
    DLY1     decfsz         DC1,f           ;  = 767 cycles
                goto            DLY1
                decfsz         DC2,f
                goto           DLY1
                ;Delay complete, repeat forever
                goto           MAINLP
                END
    #5
    davea
    Super Member
    • Total Posts : 228
    • Reward points : 0
    • Joined: 2016/01/28 13:12:13
    • Location: 0
    • Status: offline
    Re: Problem reading ADC ADRESH and ADRESL registers; result out of range 2020/04/05 09:22:51 (permalink)
    0
    MOVLW          b'00000001' ;Select channel AN1
    MOVLW          b'00000000' ;Select channel AN0
    #6
    1and0
    Access is Denied
    • Total Posts : 10779
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Problem reading ADC ADRESH and ADRESL registers; result out of range 2020/04/05 11:54:45 (permalink)
    +1 (1)
    davea
    MOVLW          b'00000001' ;Select channel AN1
    MOVLW          b'00000000' ;Select channel AN0

    WRONG !!!
    #7
    Beau Schwabe
    Starting Member
    • Total Posts : 25
    • Reward points : 0
    • Joined: 2019/09/23 21:16:53
    • Location: 0
    • Status: offline
    Re: Problem reading ADC ADRESH and ADRESL registers; result out of range 2020/04/05 12:50:44 (permalink)
    +2 (2)
    Yep... what 1and0 said ... I suggest you look at the PDF manual for the micro.
    http://ww1.microchip.com/...eviceDoc/40001723D.pdf
     
    I had a similar go round with a PIC18F57K42 that I am using right now... The ADC BLOCK DIAGRAM looks identical to your micro.  Note: The example code assumes you have some other things setup specifically "ADC Acquisition Requirements".
     
    Some of the things to pay attention to ...
    ADCON0 - Channel selection bits ... Page 135 of the manual
    ADCON1 - All of it .. understand the bit positions of the register ... Page 135 of the manual
    ADCON2 - You can skip if you arenot using auto conversion ... Page 137 of the manual
    ADRESH and ADRESL - Depending on the ADFM (Frame Value) ... Page 138-139 of the manual
     
    "ADC Acquisition Requirements" ... Page 140-141 of the manual
    Depending on your processor speed, this makes a difference... FRC is the safe bet, but if you need faster conversion times you can adjust Fosc/N to obtain the result you need ... see Figure 15-2 ... Page 131 of the manual
     
     
     
     
     
     
    #8
    davea
    Super Member
    • Total Posts : 228
    • Reward points : 0
    • Joined: 2016/01/28 13:12:13
    • Location: 0
    • Status: offline
    Re: Problem reading ADC ADRESH and ADRESL registers; result out of range 2020/04/05 13:40:20 (permalink)
    0
    I don't know what data sheet I was looking at ....
    sad: sad
    #9
    1and0
    Access is Denied
    • Total Posts : 10779
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Problem reading ADC ADRESH and ADRESL registers; result out of range 2020/04/05 13:44:51 (permalink)
    +1 (1)
    mlman
     
                   ;No low-power brownout reset, high-voltage programming, no pwm

       __CONFIG _CONFIG2, _LVP_ON & _WRT_OFF & _STVREN_ON & _BORV_LO & _PLLEN_OFF

    Don't think is the cause of your issue, but try _LVP_OFF.
    #10
    1and0
    Access is Denied
    • Total Posts : 10779
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Problem reading ADC ADRESH and ADRESL registers; result out of range 2020/04/05 13:46:37 (permalink)
    0
    davea
    I don't know what data sheet I was looking at ....

    Bit 0 is typically the ADON bit. ;)
     
    #11
    mlman
    New Member
    • Total Posts : 18
    • Reward points : 0
    • Joined: 2020/03/16 09:13:57
    • Location: 0
    • Status: offline
    Re: Problem reading ADC ADRESH and ADRESL registers; result out of range 2020/04/05 17:18:50 (permalink)
    0
    Thanks for everyone's help.  It would not allow HV programming so I didn't try it but I am confident the 12F1572 is setup properly after correcting my code but my AD readings still continue to read 0x000D (only 13 of 1024 bits so the value read is close to 0) regardless of the voltage on RA0 adjustable 0-3V.
    Just prior to the read, the SFR's are as follows:
           BIT   7  6  5  4  3  2  1  0
       WPUA   -   -   1  1  1  1  1  1
    ANSELA   -   -   -   1  -  1  1  1
       TRISA   -   -   1  1  1  1  1  1
    ADCON0  -   0   0  0  0  0  0  1 Bit 1 was set just prior to read
    ADCON1  1   1  1  1   -  -  0  0
    ADRESL   0   0  0  0  1  1  0  1
    ADRESH  0   0   0  0  0  0  0  0
     
           CPU Vcc: 3.3V
      RA0 (Pin 7): 1.0V       Read with a mult-meter but any voltage on RA0 does not change reading of 0x000D
          AD Read: 0x000D ADRESL and H
    AD Expected: 0x0136
     
    I must be missing something very simple and at my wits end??
    #12
    ric
    Super Member
    • Total Posts : 26942
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: Problem reading ADC ADRESH and ADRESL registers; result out of range 2020/04/05 17:25:03 (permalink)
    +2 (2)
    You've had several hints about "acquisition delay", but don't seem to have noticed them.
    Once again, read "15.4 ADC Acquisition Requirements" in the datasheet.
    The code you posted is only allowing a couple of instruction cycles of acquisition time, so the internal charge capacitor has no time to get charged.
     
    Edit: Corrected chapter reference.
    post edited by ric - 2020/04/05 18:42:38

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #13
    mlman
    New Member
    • Total Posts : 18
    • Reward points : 0
    • Joined: 2020/03/16 09:13:57
    • Location: 0
    • Status: offline
    Re: Problem reading ADC ADRESH and ADRESL registers; result out of range 2020/04/06 05:43:03 (permalink)
    0
    Throughout my troubleshooting, I have inserted acquisition delays (i.e. 30 nops) after turning on the AD (Bit 0=1 ADCON0) but before I set the GO bit (Bit 1=1).  The acquisition delay makes no difference and the AD result always reads 0X000E or 0X000D).
     
    Additionally, after my first reading, I wait 500ms before I reset the go bit (AD is ON the whole time) looping to read the AD and still get the same read result regardless of the voltage applied to the input RA0.
     
    In all my debugging, reading and studying registers I have yet to get a valid read on the AD using this small test program or my main program.  Both read identically.
     
     
    #14
    davea
    Super Member
    • Total Posts : 228
    • Reward points : 0
    • Joined: 2016/01/28 13:12:13
    • Location: 0
    • Status: offline
    Re: Problem reading ADC ADRESH and ADRESL registers; result out of range 2020/04/06 10:07:57 (permalink)
    0
    things to try
    ADON always ON
    change input to FVR  
    The FVR can be enabled by setting the FVREN bit of
    the FVRCON register
    and see if anything changes
    #15
    jtemples
    عُضْوٌ جَدِيد
    • Total Posts : 11813
    • Reward points : 0
    • Joined: 2004/02/13 12:31:19
    • Location: Southern California
    • Status: offline
    Re: Problem reading ADC ADRESH and ADRESL registers; result out of range 2020/04/06 10:17:01 (permalink)
    +2 (2)
    Describing what you think your code is doing doesn't help anyone solve your problem.  Always post your code.
    #16
    1and0
    Access is Denied
    • Total Posts : 10779
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Problem reading ADC ADRESH and ADRESL registers; result out of range 2020/04/06 11:14:46 (permalink)
    +1 (1)
    mlman
    Throughout my troubleshooting, I have inserted acquisition delays (i.e. 30 nops) after turning on the AD (Bit 0=1 ADCON0) but before I set the GO bit (Bit 1=1).  The acquisition delay makes no difference and the AD result always reads 0X000E or 0X000D).
     
    Additionally, after my first reading, I wait 500ms before I reset the go bit (AD is ON the whole time) looping to read the AD and still get the same read result regardless of the voltage applied to the input RA0.
     
    In all my debugging, reading and studying registers I have yet to get a valid read on the AD using this small test program or my main program.  Both read identically.

    Did you measure the voltage on the RA0 pin directly?  If so, then do you have another PIC device to try?
     
    #17
    Beau Schwabe
    Starting Member
    • Total Posts : 25
    • Reward points : 0
    • Joined: 2019/09/23 21:16:53
    • Location: 0
    • Status: offline
    Re: Problem reading ADC ADRESH and ADRESL registers; result out of range 2020/04/06 13:13:35 (permalink)
    +2 (2)
    I don't see in your code where you are sending the received data from the ADC to be able to determine what values it has taken on.   Your statement "...the AD result always reads 0X000E or 0X000D"   ... is it possible you are returning the ADDRESS of the ADCRESULT and not the actual result?
     
    Please post your complete code
     
    There are also things you can do from a DEBUG perspective in code to make sure certain things are happening the way you expect them to...  i.e.
     
    after...

    MOVF          ADRESH,W     ;Read upper 2 bits

     
    add this ...

    movlw     d'4'

     
    and after this ...

    MOVF          ADRESL,W     ;Read lower 8 bits

     
    add this ...

    movlw     d'210'

     
    rerun your program and you should return a value '1234'   ... 4 x 256 + 210 = 1234
     
     
    #18
    1and0
    Access is Denied
    • Total Posts : 10779
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: Problem reading ADC ADRESH and ADRESL registers; result out of range 2020/04/06 19:20:48 (permalink)
    0
    Beau Schwabe
    I don't see in your code where you are sending the received data from the ADC to be able to determine what values it has taken on.   Your statement "...the AD result always reads 0X000E or 0X000D"   ... is it possible you are returning the ADDRESS of the ADCRESULT and not the actual result?
     
    Please post your complete code

    See OP's Post #5, which contains:
                BANKSEL     ADRESH         ;Yes, read ADC
                MOVF        ADRESH,W     ;Read upper 2 bits
                BANKSEL     ADCRESULT
                MOVWF       ADCRESULT+1 ;Store in GPR space\

                BANKSEL     ADRESL
                MOVF        ADRESL,W     ;Read lower 8 bits
                BANKSEL     ADCRESULT
                MOVWF       ADCRESULT   ;Store in GPR space

    Edit: Besides, the UDATA GPRs on OP's PIC device are located at 0x020-0x06F, 0x0A0-0x0EF, and 0x120-0x16F; addresses 0x00D and 0x00E are unimplemented.
    post edited by 1and0 - 2020/04/06 19:28:09
    #19
    Beau Schwabe
    Starting Member
    • Total Posts : 25
    • Reward points : 0
    • Joined: 2019/09/23 21:16:53
    • Location: 0
    • Status: offline
    Re: Problem reading ADC ADRESH and ADRESL registers; result out of range 2020/04/06 22:58:34 (permalink)
    0
    1and0 ... Right, no I understand that the OP is sending ADRESH to ADCRESULT+1 and ADRESL to ADCRESULT but where is he going from there to determine what is inside of ADCRESULT+1 and ADCRESULT ?  IOW how is he debugging the ADC values ?
    #20
    Page: 123 > Showing page 1 of 3
    Jump to:
    © 2020 APG vNext Commercial Version 4.5