chipKIT® Development Platform

Inspired by Arduino™

ADC Vreff

Created Wed, 19 Mar 2014 22:13:15 +0000 by superheterodino


Wed, 19 Mar 2014 22:13:15 +0000

Hi, I new in the forum, so I don't know if I'm writting in the correct place XD. I'm trying to sample a signal between 1.5 Vp and -1.5Vp and I don't want to modify it (add an offset to it) so change the vref- of the adc. But uno32 only let me to sample with precision at the intervals of 500 mv and -500mv, and if I put a bigger vref+(pin42) and Vref-(pin 41), the uno32 starts to read strange values. This is my code:

#include <plib.h>

int ADCValue=0;
void setup() {

AD1PCFG = 0xFFFB; // PORTB = Digital; RB2 = analog A0
 AD1CON1 = 0x00E0; // SAMP bit = 0 ends sampling ... automaticamente conviete el bit
// and starts converting
 AD1CHS = 0x00020000; // Connect RB2/AN2 as CH0 input .. seleccionamos el adc a usar osea el A0
// in this example RB2/AN2 is the input
 AD1CSSL = 0;
 AD1CON3 = 0x0002; // Manual Sample, Tad = internal 2 Tcy
 AD1CON2 = 0x6000;// con un 4 al principio Referenca negativa  la positiva se deja
 AD1CON1SET = 0x8000;// enable
//Timer 1 8Khz
T1CON = 0x10; // Stop the Timer and Reset Control register
// Set prescaler at 1:8, internal clock source 2 bits de escalado
TMR1 = 0x0; // Clear timer register, reiniciamos contador
PR1 = 0x04E2; // Load period register, fin de cuenta
IPC1SET = 0x0008; // Set priority level=2
IPC1SET = 0x0001; // Set subpriority level=1
IFS0CLR = 0x0010; // Clear Timer interrupt status flag
 IEC0SET = 0x00000010;  // enable timer interrupts


void loop() {}

extern "C"
void __ISR(_TIMER_1_VECTOR,ipl3) algo(void)

AD1CON1SET = 0x0002;
//AD1CON1CLR = 0x0002;
while (!(AD1CON1 & 0x0001)){// conversion done?
ADCValue = ADC1BUF0;
ADCValue-=500; //offset eliminated


/*  delay(50);
  Serial.print(" valor: ");
 // Clear interrupt flag
IFS0CLR = 0x0010;


PD. I also tried to change only vref-

Thank you very mucho for your attention, and forgive me because of my worst english


Thu, 20 Mar 2014 10:26:56 +0000

I think you are misunderstanding what the Vref+ and Vref- actually are and how they work.

They don't mean + and - as in "above" or "below" 0V, but + and - as in "upper" and "lower".

Say you have a voltage that varies between 1V and 2V. You can set Vref+ to 2V and Vref- to 1V and you can sample at maximum resolution between those two voltages (1V = 0, 2V = 1023).

You cannot sample below 0V (well, you can, but only slightly, and it's not chip friendly), nor apply a Vref- voltage below 0V, as the lowest voltage you can apply to any pin is Vss-0.3V. That is because of the ESD protection diodes on the pins which route any voltage < -0.3V (or thereabouts) through to ground (and any voltage > 3.6V [or Vdd + 0.3] to the Vcc rail).

In order to sample negative voltages you will HAVE to apply an offset to the signal. This can best be done using a non-inverting op-amp circuit with unity gain (or increase the gain if you fancy?) with a 50% Vcc offset imposed on it:

If you have a split-rail power supply you could first buffer the signal to completely isolate it from the offset. You could also add a - input and make it a full instrumentation amplifier.


Thu, 20 Mar 2014 23:25:58 +0000

Okay, I understand. Thank you very much. :)