PDA

View Full Version : ADC missing steps using 1 volt Vref



Marv
- 9th January 2012, 19:06
I am using An0 with a 4-20mA input and 1 volt on Vref- to get full 10 bit resolution. I have a 250 ohm resistor and a .1uF cap on An0 to ground. The problem is when the input voltage reaches 2.989 then my raw ADC reading stops at 511 and doesn't change till voltage reaches 3.156 at which time it jumps to 554. When I clear bit 5 of ADCON1 (Vref = Vss) then it works fine with no missing steps, only less resolution.I'm using a 18F4620 uC32MHz internal oscillator OSCCON = %01110000 ' configure 8Mhz OSCTUNE.6 = 1 ' turn on PLLEN ((4 times multiplier (8x4 for 32Mhz)) DEFINE OSC 32 ' Program to use 32Mhz clock TRISA = %11111111 ' all inputs CMCON = %00000111 ' Turn off comparators'--------- F con $FE ' funtion code for LCD Clr con $01 ' Clr LCD print on line 1 Ln1 con $80 ' line 1 on LCD Ln2 con $C0 ' line 2 on LCD Ln3 con $94 ' line 3 on LCD Ln4 con $D4 ' line 4 on LCDDisp: ADCON0 = %00000001 ' A/D module enabled, channel 0 ADCON1 = %00101100 ' Vref = Vdd & 1V ref, AN0 = analog ADCON2 = %10101111 ' Right justified, 12 Tad, Frc clock INTCON = %01000000 ' Global ints disabled, enable peripheral interrupts PIE1.6=1 ' A/D interrupt enabled (for wake from sleep) ADCON0.1=1 ' Start the A/D conversion @ SLEEP ' Sleep until A/D conversion finished WHILE ADCON0.1 ' A/D complete? WEND ' PIR1.6=0 ' Clear A/D int flag ASM ; Put upper and lower byte of A/D in ADResult MOVFF ADRESL,_ADResult ; get low byte MOVFF ADRESH,_ADResult+1 ; get high byte ENDASM LCDOUT F,Clr," AD 1 Vref = ",DEC ADResult'-------- ADCON0 = %00000001 ' A/D module enabled, channel 0 ADCON1 = %00001100 ' Vref = Vdd & 1V ref, AN0 = analog ADCON2 = %10101111 ' Right justified, 12 Tad, Frc clock INTCON = %01000000 ' Global ints disabled, enable peripheral interrupts PIE1.6=1 ' A/D interrupt enabled (for wake from sleep) ADCON0.1=1 ' Start the A/D conversion @ SLEEP ' Sleep until A/D conversion finished WHILE ADCON0.1 ' A/D complete? WEND ' PIR1.6=0 ' Clear A/D int flag ASM ; Put upper and lower byte of A/D in ADResult MOVFF ADRESL,_ADResult ; get low byte MOVFF ADRESH,_ADResult+1 ; get high byte ENDASM LCDOUT F,Ln2," AD 5 Vref = ",DEC ADResult'------- PAUSE 200 goto disp

Marv
- 9th January 2012, 19:26
I don't know why it looks like this, let me try again
I am using An0 with a 4-20mA input and 1 volt on Vref- to get full 10 bit resolution. I have a 250 ohm resistor and a .1uF cap on An0 to ground. The problem is when the input voltage reaches 2.989 then my raw ADC reading stops at 511 and doesn't change till voltage reaches 3.156 at which time it jumps to 554. When I clear bit 5 of ADCON1 (Vref = Vss) then it works fine with no missing steps, only less resolution.
I'm using a 18F4620 uC32MHz internal oscillator

'************************************************* ***************
OSCCON = %01110000 ' configure 8Mhz
OSCTUNE.6 = 1 ' turn on PLLEN ((4 times multiplier (8x4 for 32Mhz))
DEFINE OSC 32 ' Program to use 32Mhz clock

'--LCD port and command definitions--
DEFINE LCD_DREG PORTB ' Lcd data port
DEFINE LCD_DBIT 4 ' Start bit ( 4 bit bus / 0 = low nibble, 4 = high nibble )
DEFINE LCD_RSREG PORTB ' Register select port
DEFINE LCD_RSBIT 2 ' Register select bit
DEFINE LCD_EREG PORTB ' Enable port
DEFINE LCD_EBIT 3 ' Enable bit
DEFINE LCD_BITS 4 ' Bus size ( 4 0r 8 bits )
DEFINE LCD_LINES 4 ' # of lines on lcd
DEFINE LCD_COMMANDUS 5000 ' Command delay time in us
DEFINE LCD_DATAUS 100 ' Data delay time in us
'--constants
F con $FE ' funtion code for LCD
Clr con $01 ' Clr LCD print on line 1
Ln1 con $80 ' line 1 on LCD
Ln2 con $C0 ' line 2 on LCD
Ln3 con $94 ' line 3 on LCD
Ln4 con $D4 ' line 4 on LCD

'Variables:
ADResult VAR WORD
TRISA = %11111111
CMCON = %00000111 ' Turn off comparators

Disp:
ADCON0 = %00000001 ' A/D module enabled, channel 0
ADCON1 = %00101100 ' Vref = Vdd & 1V ref, AN0 = analog
ADCON2 = %10101111 ' Right justified, 12 Tad, Frc clock (ADCON2 = %10101011)
INTCON = %01000000 ' Global ints disabled, enable peripheral interrupts
PIE1.6=1 ' A/D interrupt enabled (for wake from sleep)
ADCON0.1=1 ' Start the A/D conversion
@ SLEEP ' Sleep until A/D conversion finished
WHILE ADCON0.1 ' A/D complete?
WEND '
PIR1.6=0 ' Clear A/D int flag
ASM ; Put upper and lower byte of A/D in ADResult
MOVFF ADRESL,_ADResult ; get low byte
MOVFF ADRESH,_ADResult+1 ; get high byte
ENDASM
lcdout f,clr," AD 1 Vref = ",dec adresult
'--------
ADCON0 = %00000001 ' A/D module enabled, channel 0
ADCON1 = %00001100 ' Vref = Vdd & 1V ref, AN0 = analog
ADCON2 = %10101111 ' Right justified, 12 Tad, Frc clock (ADCON2 = %10101011)
INTCON = %01000000 ' Global ints disabled, enable peripheral interrupts
PIE1.6=1 ' A/D interrupt enabled (for wake from sleep)
ADCON0.1=1 ' Start the A/D conversion
@ SLEEP ' Sleep until A/D conversion finished
WHILE ADCON0.1 ' A/D complete?
WEND '
PIR1.6=0 ' Clear A/D int flag
ASM ; Put upper and lower byte of A/D in ADResult
MOVFF ADRESL,_ADResult ; get low byte
MOVFF ADRESH,_ADResult+1 ; get high byte
ENDASM
lcdout f,ln2," AD 5 Vref = ",dec adresult
'-------
pause 200
goto disp

Acetronics2
- 10th January 2012, 08:57
Hi,

Just check your Pic Datasheet and see what are the ALLOWED ranges for Vref ...

Alain

amgen
- 10th January 2012, 12:31
Hi,
The V-in has to be less than V-ref at least by a little (dynamic range of v-in), so
use 5 Volt ref or use 50 ohm dropping R ( gives 1 volt at 20 ma)
Don

Marv
- 10th January 2012, 16:23
Alain,
I found in TABLE 26-24: - A/D Converter Characteristics, that (VREFH - VREFL) is 3v min.
Thanks for pointing me in the right direction.