The current setup is shown below. PIC12F1822 with a 10-bit ADC.

PIC12F1822 0-20mA ADC issue

I'm using a 250R 0.05% precision resistor to get a nice 0-5V input to the analogue pin (AN2 if it matters). As far as I can tell I have the software side of things correct but I'll show the relevant parts of the code at the bottom.

I'm pushing the conversion results (ADRESH and ADRESL) straight to the SPI SDO pin which I know is correctly functioning.

The issue is that for a 0mA input (both input terminals grounded) I get an output of 00 0011 0011 (51 dec). With my current source connected and set as low as possible - about 34.6mV across the resistor - I get a result of 00 0011 1010 (58 dec). A value of 58 decimal should correspond to an input voltage of 0.283V giving quite a large

I'm struggling to see why there is an offset of around 5.6%. Is the internal setup a potential cause?

Figure 16-4 from PIC12F1822 datasheet

It is configured to use Vdd and Vss as the reference voltages, have conversion clock of Fosc/2 (250kHz) and the ADC module is switched on during a start-up routine.

Relevant code:

            banksel     ADCDATAH
            clrf        ADCDATAH
            banksel     ADCDATAL
            clrf        ADCDATAL
            banksel     ADCON0                  ;
            bsf         ADCON0,ADGO             ;Set ADGO conversion start bit
CONVTEST    clrwdt                              ;Clear Watchdog Timer
            call        DELAY                   ;Short delay
            btfsc       ADCON0,ADGO             ;If conversion finished skip next instr
            goto        CONVTEST                ;Conversion not yet finished
            call        DELAY
            banksel     ADRESH                  ;
            movf        ADRESH,0                ;Move the upper bits of conversion to W
            banksel     ADCDATAH
            movwf       ADCDATAH                ;W to ADCDATAH
            banksel     ADRESL                  ;
            movf        ADRESL,0                ;Move the lower bits of conversion to W
            banksel     ADCDATAL
            movwf       ADCDATAL                ;W to ADCDATAL

            banksel     PORTA
            bcf         CS                      ;Select DAC slave to receive data (16 bits)
            banksel     ADCDATAH
            movf        ADCDATAH,0              ;Move SPIDATAH data to W
            banksel     SSP1BUF
            movwf       SSP1BUF                 ;W to SSP1BUF
            call        DELAY                   ;Call delay (must be >8 inst cycles)
            banksel     ADCDATAL
            movf        ADCDATAL,0              ;Move SPIDATAL data to W
            banksel     SSP1BUF
            movwf       SSP1BUF
            call        DELAY
            banksel     PORTA
            bsf         CS

Should I only be turning the ADC module on when performing a conversion? Its only purpose is as an ADC so I didn't see any point in switching it off seeing as power usage isn't an issue.

  • \$\begingroup\$ When you say you had 34.6V across the resistor, is that measured with an oscilloscope or other high-accuracy voltmeter? Or is that assumed based on known current flow? Also, how long is the delay from when you select the channel to when you initiate the conversion? \$\endgroup\$
    – Dan Laks
    Commented Oct 22, 2014 at 17:43
  • 2
    \$\begingroup\$ This is unlikely, but do you have pull-ups enabled? They're disabled by default in the OPTION_REG register. \$\endgroup\$
    – Dan Laks
    Commented Oct 22, 2014 at 17:51
  • \$\begingroup\$ Great call on the Weak Pull-Ups being enabled, I didn't properly setup the OPTION_REG when I was configuring the Timer0 bits in that register. Would mark this comment as the answer if I could! \$\endgroup\$
    – JoshGreen1
    Commented Oct 23, 2014 at 9:15

1 Answer 1


Credit for this should go to Dan Laks (see comment on original question), but this question is still sitting in the 'unanswered' section, so I'm putting an answer to it.

Ensure that weak pull-ups in the OPTIONS_REG are not active.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.