Help on 12bit ADC for PIC18F2523

29 views
Skip to first unread message

flyway38

unread,
Sep 13, 2022, 10:54:36 AM9/13/22
to jallib
Hello all,

New question.
My PIC is reading ok ADC values if below 2.5V (1/2 of range VCC/GND).
It seems like 11bit ADC behaviour.

My code:
-- ok, now let's configure ADC
-- Step 1: ADC analog input pin setup
const byte ADC_CHANNEL = 0                       -- port 0 is analog input (default)
pin_AN0_direction = input
const byte ANSEL_ANS0 = TRUE                     -- potmeter connected to pin_AN0
-- Step 2: Set VDD and VSS as Vref
const byte ADCON0_VCFG = FALSE
-- Step 3: Use Frc as ADC clock
const byte ANSEL_ADCS = 0b110
--
const ADC_RSOURCE = 500                          -- Input Resistance
const ADC_TEMP = 20                              -- PIC Temperature
-- We want the fastest possible ADC timing, so we specify here the
--const ADC_MIN_TAD = 1
const ADC_MAX_TAD = 10
-- Now we can include the library
include adc
-- And initialize the whole with our parameters
adc_init()

Inside Forever Loop:
   iVal = 0 -- Its a DWord
   --
   for AdcReadings loop
      AdcData = adc_read_high_res(AdcChnn)
      iVal = iVal + dword(AdcData)
   end loop
   --
   mVal = word(iVal / dword(AdcReadings))

Any help would be great.
Thank you very much.

Kind regrads,
Filipe Santos

vsurducan

unread,
Sep 14, 2022, 7:57:26 AM9/14/22
to jal...@googlegroups.com
If your Vref + is +5V and Vref- is GND, full scale means 4095 at 5V.
One issue might appear if acquisition time is too short or you have messed something with references.
|Vref+| - |Vref-| >=3V

--
You received this message because you are subscribed to the Google Groups "jallib" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jallib+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jallib/5c020fb1-f8fa-4684-9284-1dc3a1793ca4n%40googlegroups.com.

flyway38

unread,
Sep 14, 2022, 8:43:19 AM9/14/22
to jallib
Hello Vasile,

Thank you for your input.
About Vref it should be set to VCC (5V) and GND. It's the default anyways (by the Datasheet info).
Have, however, noticed that the ADC initial configuration constants don't match with the needed ones.
EX: ANSEL_ADCS, ADCON0_VCFG, ANSEL_ANS0, etc.. aren't used in ADC lib or even in PIC(18F2523) lib.

About convertion time and MAX_TAD, have already tested longer time values with no sucess...
Any more ideas?
Thanks anyways.

Cheers,
Filipe Santos.

flyway38

unread,
Sep 14, 2022, 10:40:26 AM9/14/22
to jallib
Hey all,

Problem solved. Had to redo all ADC code.
Here is the working code. Maybe this is usefull for the coders here;

-- ok, now let's configure ADC
pin_AN0_direction = input
-- ADCON0 CONFIG
ADCON0_CHS0 = OFF -- Channel at 0 (Bit 0)
ADCON0_CHS1 = OFF -- Channel at 0 (Bit 1)
ADCON0_CHS2 = OFF -- Channel at 0 (Bit 2)
ADCON0_CHS3 = OFF -- Channel at 0 (Bit 3)
-- ADCON1 CONFIG
ADCON1_PCFG0 = OFF -- AN0 as Analog ONLY (Bit 0)
ADCON1_PCFG1 = ON  -- AN0 as Analog ONLY (Bit 1)
ADCON1_PCFG2 = ON  -- AN0 as Analog ONLY (Bit 2)
ADCON1_PCFG3 = ON  -- AN0 as Analog ONLY (Bit 3)
ADCON1_VCFG0 = OFF -- Vref+ at VDD
ADCON1_VCFG1 = OFF -- Vref- at VSS
-- ADCON2 CONFIG
ADCON2_ADCS0 = OFF -- AD Conversion Clock at Fosc/64 (Bit 0)
ADCON2_ADCS1 = ON  -- AD Conversion Clock at Fosc/64 (Bit 1)
ADCON2_ADCS2 = ON  -- AD Conversion Clock at Fosc/64 (Bit 2)
ADCON2_ACQT0 = ON  -- AD Acq. Time at 2xTAD (Bit 0)
ADCON2_ACQT1 = OFF -- AD Acq. Time at 2xTAD (Bit 1)
ADCON2_ACQT2 = OFF -- AD Acq. Time at 2xTAD (Bit 2)
ADCON2_ADFM = ON   -- AD Result Justify at Right
--
const word ADC_RSOURCE = 2_500                        -- Input Resistance
const byte ADC_TEMP = 85                              -- PIC Max. Temperature
const byte ADC_MAX_TAD = 6                            -- (0.8us < TAD < 12.5us as per
--                                                        Datasheet, Pag. 41)
-- AD ACQUISITION TIME (Original VAR: adc_conversion_delay)
-- Tacq = Tamp + Tc + Tcoff
const word tamp = 1 -- (=> 0.2us as per Datasheet, Pag. 30)
const word adc_tc = 2 -- ((TEMP – 25°C)x(0.02 us/°C) => 1.2us as per Datasheet, Pag. 30))
const word adc_tcoff = 2 -- (-(25 pF)x(1 kohm + 4 kohm + RSOURCE)xln(0.0004883)
--                          => 1.56us as per Datasheet, Pag. 30)
const byte ADC_TACQ = byte(tamp + adc_tc + adc_tcoff)
-- (Original VAR: adc_conversion_delay)
--
var word adc_word                               -- return value
var byte adc_byte[2] at adc_word                -- byte array overlay
--
function adc_read_high_res(byte in adc_chan) return word is
pragma inline
   --
   -- Original Code has here the Channel and L/R Justifying
   --  These parameters are set above...
  --
  ADCON0_ADON = TRUE                              -- turn on ADC module
   --
   for ADC_TACQ loop
      _usec_delay(1)                              -- wait acquisition time
      -- Original: _usec_delay(10)
   end loop
   --
   ADCON0_GO = TRUE                                -- start conversion
   while ADCON0_GO == TRUE loop                    -- wait until conversion completed
      -- Empty loop.
   end loop
   --
   adc_byte[1] = ADRESH                         -- copy high order bits
   adc_byte[0] = ADRESL                         -- copy low order bits
   -- Choosed High Resolution options here, from Original Code...
   --
   -- Honor 2 * max Tad time. Note the value is not very accurate, but safe.
   _usec_delay(2 * ADC_MAX_TAD) -- As per Datasheet, Pag. 29
   --
   ADCON0_ADON = false                             -- turn off ADC module
   return adc_word                                 -- back to caller
end function

Best regrads,
FS

vsurducan

unread,
Sep 14, 2022, 11:16:36 AM9/14/22
to jal...@googlegroups.com
congrats, but it still be simplified a bit...:)

flyway38

unread,
Sep 14, 2022, 2:12:21 PM9/14/22
to jallib
Hi Vasile,

Thank you.
Yes, That code was the testing code. Right now am using the "compact" side of ANCON Vars :D

-- ADCON0 CONFIG
--ADCON0_CHS0 = OFF -- Channel at 0 (Bit 0)
--ADCON0_CHS1 = OFF -- Channel at 0 (Bit 1)
--ADCON0_CHS2 = OFF -- Channel at 0 (Bit 2)
--ADCON0_CHS3 = OFF -- Channel at 0 (Bit 3)
ADCON0_CHS = 0 -- Channel at 0
-- ADCON1 CONFIG
--ADCON1_PCFG0 = OFF -- AN0 as Analog ONLY (Bit 0)
--ADCON1_PCFG1 = ON  -- AN0 as Analog ONLY (Bit 1)
--ADCON1_PCFG2 = ON  -- AN0 as Analog ONLY (Bit 2)
--ADCON1_PCFG3 = ON  -- AN0 as Analog ONLY (Bit 3)
ADCON1_PCFG = 14 -- AN0 as Analog ONLY
--ADCON1_VCFG0 = OFF -- Vref+ at VDD
--ADCON1_VCFG1 = OFF -- Vref- at VSS
ADCON1_VCFG = 0 -- Vref+ at VDD, Vref- at VSS
-- ADCON2 CONFIG
--ADCON2_ADCS0 = OFF -- AD Conversion Clock at Fosc/64 (Bit 0)
--ADCON2_ADCS1 = ON  -- AD Conversion Clock at Fosc/64 (Bit 1)
--ADCON2_ADCS2 = ON  -- AD Conversion Clock at Fosc/64 (Bit 2)
ADCON2_ADCS = 6 -- AD Conversion Clock at Fosc/64
--ADCON2_ACQT0 = ON  -- AD Acq. Time at 2xTAD (Bit 0)
--ADCON2_ACQT1 = OFF -- AD Acq. Time at 2xTAD (Bit 1)
--ADCON2_ACQT2 = OFF -- AD Acq. Time at 2xTAD (Bit 2)
ADCON2_ACQT = 1 -- AD Acq. Time at 2xTAD

ADCON2_ADFM = ON   -- AD Result Justify at Right

Thanks once again.
Cheers.
FS

flyway38

unread,
Sep 14, 2022, 2:15:43 PM9/14/22
to jallib
PS:
I mean ADCON Compacted Vars.
Reply all
Reply to author
Forward
0 new messages