I want to use the MAX1032 ADC (datasheet) to measure a voltage (Vin) through a voltage divider (30K/3K) with a PIC microcontroller over SPI. I have written a simple library for Single-Ended Unipolar measurements which works.. However the voltage doesn't correspondent with the theoretical value it should be. To clarify the problem:

  • Voltage divider disconnected from adc: Vin=45.8V, Vadc=4.16V (as it should be theoretically).
  • Voltage divider connected to ADC: Vin=45.8V, Vadc=3.95V (0,21V error)
  • ADC inputs floating: I measure around 2.35V at the inputs

It looks like the 2.35V conflicts with Vadc resulting in erratic voltages (which are being read correctly, checked with multimeter..). Could this be due to a wrong configuration or am I processing the input wrong?

Additional info:
VREF is configured to internal 4.096V by bypassing REFCAP pin with 0.1μF to AGND1 and REF pin with 1.0μF to AGND1).
At startup a Analog Input Configuration Byte is written for each channel (see datasheet Table 2 and Table 6) . This byte configures each channel to be Single-Ended Unipolar 0 to (+3 x VREF)/2. FSR = (3 x VREF)/2).

#define START 1 << 7   /* defines the beginning of the analog input configuration byte */
#define DIF_SGL 0 << 3 /* Single ended: input voltages are measured between the selected input channel and AGND1 */
#define RANGE_SELECT_BITS 0b011  /* Table 6. Range-Select Bits: R2, R1, R0 (Single-Ended Unipolar 0 to (+3 x VREF)/2. FSR = (3 x VREF)/2) */

void max1032_inputConfigSingleEndedUnipolar(max1032_channel_t ch){
    spiWrite((uint8_t)(START | (ch << 4)| DIF_SGL | RANGE_SELECT_BITS));

The function below is used for reading raw adc values. Vadc is acquired by multiplying the adc value with 6.144/16384 according to ((3 x VREF)/2)/14bit. Then Vin is acquired by multiplying Vadc with (30K + 3K) / 3K

#define CONVERSION_START_BYTE 0b10000000 /* D7 start bit high, edit with [6...4]:Channel-Select */
uint16_t max1032_readRaw(max1032_channel_t ch){
    uint8_t dataRawHi; 
    uint8_t dataRawLo; 
    spiWrite((uint8_t)(CONVERSION_START_BYTE | (ch << 4)));
    dataRawHi = spiRead();
    dataRawLo = spiRead();
    return (uint16_t)((dataRawHi << 6) | (dataRawLo >> 2));   /* response: B13-B0 */

MAX1032 circuit with voltage divider example: enter image description here


1 Answer 1


Your ADC has a low input impedance of 17 kOhm as per the datasheet. I think that explains the error — you'd need to buffer the input.

See the figure on the bottom left of page 10 which gives you the input current into CH_X for a given input voltage, and also figure 19 for a typical application.

You could also switch to an ADC with a higher input impedance.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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