News:

Let's find out together what makes a PIC Tick!

Main Menu

12 bit ADIn available in 16-bit PICs?

Started by trastikata, Feb 11, 2023, 12:19 AM

Previous topic - Next topic

trastikata

Hello Les,

does the compiler support 12-bit ADC results through the ADIn command?

I've just tried using "Declare Adin_Res = 12" however with ADIn I get only 10 bit readings, whereas manually writing an ADC procedure returns 12 bit results?



trastikata

Quote from: Ivano on Feb 11, 2023, 05:15 PMRead this
https://protoncompiler.com/index.php/topic,1464.msg11452.html#msg11452

Hello Ivano, ADC modules in 16-bit devices are different from 8-bit PICs.

What I am presuming is that Positron16 doesn't support 12-bit ADIn command.

Ivano

Hello Trastikata,
I've never used 16 bit,
in this case only Les can give the answer

david

#4
Quote from: trastikata on Feb 11, 2023, 05:29 PM
Quote from: Ivano on Feb 11, 2023, 05:15 PMRead this
https://protoncompiler.com/index.php/topic,1464.msg11452.html#msg11452

Hello Ivano, ADC modules in 16-bit devices are different from 8-bit PICs.

What I am presuming is that Positron16 doesn't support 12-bit ADIn command.

Hi,
Some time back I used 16LF1783 devices and they provided 12 bit output when using the ADIn command.
Check bit 7 of ADCON0

These are a few snippets from the old code-

ADCON0=%00000001      'AN0 selected, ADC On
ADCON1=%11010000      '2's compliment, Fosc/16.  -ve ref=Gnd, +ve ref=Vdd
ADCON2=%00001111      '-ve ref selected by ADNREF

therm=ADIn 0        'returns 12 bit 0-4096 from thermistor (no averaging)
therm=therm/4       'rescale back to 0-1023 range


Sadly the chip was plagued by clock crosstalk within the silicon which Microchip eventually admitted to and provided a rather useless work around (averaging).
(Sorry - this wasn't Positron 16 but the earlier Proton 8 bit)

Cheers,
David

flosigud

12bit ad on 16 bit pic is so complicated and has so many options, like sound recording, so it would be quite overwhelming to cater for all that in a single command, let alone all the differences between different devices. 

trastikata

#6
Quote from: flosigud on Feb 11, 2023, 08:13 PM12bit ad on 16 bit pic is so complicated and has so many options, like sound recording, so it would be quite overwhelming to cater for all that in a single command, let alone all the differences between different devices.

On 16-bit devices full 10-bit ADC implementation is more complex than 12-bit ADC reading because of the additional  4 channel mux and S&H options for 10-bit ;) . For basic ADC usage - there's really no difference between 10 and 12 bit to take care off, except the different ADC Clock Period, which is normal for all devices.

Anyway, my question was:

- Does the 16-bit compiler support 12-bit ADIn when "Declare Adin_Res = 12" is used and I have stumbled onto anomaly?

- Or "Declare Adin_Res = 12" is not supported in the 16-bit compiler and ADIn returns the 10-bit as it is supposed to do.

All I currently do is testing code and peripherals on dsPIC33EP256MU806 which is rich on HW options - for the ease of use I first try compiler commands and then I replace them with code wrapped in procedures to get advantage of the additional functionality that I need. Thus, naturally if I notice a strange behavior, I am reporting it.

top204

#7
The declare is not actually valid anymore with the newer devices, and especially the 16-bit devices. It is left in place for backward compatability.

With the 16-bit devices, the ADin command returns a 16-bit variable type read from the ADC's SFR. So if the ADC is 10-bit, a 10-bit value will be returned, and if 12-bit, a 12-bit value will be returned. But make sure the justification is setup correctly and the ADC is setup correctly, because the ADon command does not setup the ADC peripheral, it just sets the channel and reads the SFRs.

trastikata

Quote from: top204 on Feb 13, 2023, 01:43 PMThe ADin command returns a 16-bit value read from the ADC's SFRs. So if the ADC is 10-bit, a 10-bit value will be returned, and if 12-bit, a 12-bit value will be returned. But make sure the justification is setup correctly and the ADC is setup correctly, because the ADon command does not setup the ADC peripheral, it just sets the channel and reads the SFRs.

Hello Les,

I think there's anomaly here because I've investigated the odd behaviour. There's no justification for the 10 or 12 bit in those devices, see the attached snippet.

ADC.jpg

So when I set manually the ADC module:

Proc SetADC()
    ANSELB.2 = 1                'AN2 set to analog
   
    AD1CON1.15 = 0              'ADON: ADC Operating Mode bit OFF
    AD1CON1.10 = 1              '12-bit, 1-channel ADC operation
    AD1CON1.7 = 1               'SSRC<2:0>: Sample Clock Source Select bits - Internal counter ends sampling and starts conversion (auto-convert)
    AD1CON1.6 = 1
    AD1CON1.5 = 1
   
    AD1CHS0.4 = 0               'CH0SA<4:0>: Channel 0 Positive Input Select for Sample A bits - set to AN2
    AD1CHS0.3 = 0
    AD1CHS0.2 = 0
    AD1CHS0.1 = 1
    AD1CHS0.0 = 0

    AD1CON3.12 = 1              'SAMC<4:0>: Auto-Sample Time bits 16 TAD
    AD1CON3.11 = 0
    AD1CON3.10 = 0
    AD1CON3.9 = 0
    AD1CON3.8 = 0
    AD1CON3.7 = 0               'ADCS<7:0>: ADC Conversion Clock Select bits = 17
    AD1CON3.6 = 0
    AD1CON3.5 = 0
    AD1CON3.4 = 1
    AD1CON3.3 = 0
    AD1CON3.2 = 0
    AD1CON3.1 = 0
    AD1CON3.0 = 1
   
    AD1CON1.15 = 1              'ADON: ADC Operating Mode bit ON
EndProc

And I use this code to read the ADC:

    AD1CON1.1 = 1               'SAMP: ADC Sample Enable bit
    While AD1CON1.0 = 0 : Wend  'DONE: ADC Conversion Status bit
    wVoltageAdc = ADC1BUF0      'Read ADC buffer result


When the ADC is set to either 10b or 12b and I use my procedure to read the ADC buffer, I get correct 10b and 12b readings. Thus, directly reading the ADC buffer yields correct result.

However if I use wVoltageAdc = ADIn 2, I always get 10b readings regardless if set to 12b conversion or not.


top204

#9
I am mistaken in stating the ADin command does not do any setting up. On the 16-bit devices, it must perform some setting up to actually get an ADC reading if a user does not understand how to setup the ADC peripheral before using the command. It has been such a long, long time since I worked on the assembler code for them, I have forgotten a lot. It has been about 13 years since I created the compiler's library assembler code for the 16-bit compiler.

Include the "ADin.inc" file and you will see what I mean. It reproduces the ADin command's routine, but in Positron16 BASIC.

You will see that they are slightly different depending on what type of device is being used, but all run similarly. But I would not put it past microchip to make changes in some of the device setups. The PIC24 and dsPIC33 devices used to be very regular in their setups, but probably different now. In the "ADin.inc" file you will see a line of code such as:

    AD1CON1 = %1000010011100100
'              ||||||||||||||||_____________________ Bit-0 : No ADC conversion yet
'              |||||||||||||||______________________ Bit-1 : ADC Sample and Hold amplifiers are holding
'              ||||||||||||||_______________________ Bit-2 : Sampling begins immediately after last conversion. SAMP bit is auto-set.
'              |||||||||||||________________________ Bit-3 : Samples multiple channels individually in sequence
'              ||||||||||||_________________________ Bit-4 : Sample Clock Source Group Bit
'              |||||||||||__________________________ Bit-5 :\
'              ||||||||||___________________________ Bit-6 :| Internal Counter ends sampling and starts conversion (auto-convert)
'              |||||||||____________________________ Bit-7 :/
'              ||||||||_____________________________ Bit-8 :\ ADC is using integer mode
'              |||||||______________________________ Bit-9 :/
'              ||||||_______________________________ Bit-10: 12-Bit, 1-channel ADC operation
'              |||||________________________________ Bit-11: Unimplemented
'              ||||_________________________________ Bit-12: DMA buffers are written in Scatter/Gather mode
'              |||__________________________________ Bit-13: Continue module operation in Idle mode
'              ||___________________________________ Bit-14: Unimplemented
'              |____________________________________ Bit-15: Enable the ADC

However, I never got around to creating a section for the dsPIC33E types or the dsPIC33CK types in the "ADin.inc" library file.

trastikata

Quote from: top204 on Feb 13, 2023, 06:02 PMHowever, I never got around to creating a section for the dsPIC33E types or the dsPIC33CK types in the "ADin.inc" library file.

I see, the dsPIC33E has not been included and the ADIn doesn't actually do any set-up for those PICs, which leaves the default register values, which is 10b?

Interesting, why then if I preset AD1CON1 to 12b, the ADIn still returns 10b? 

Stephen Moss

Quote from: trastikata on Feb 13, 2023, 06:46 PMInteresting, why then if I preset AD1CON1 to 12b, the ADIn still returns 10b? 
Have you tried reading the AD12B bit and outputting it to a pin to see if has been set or cleared, that should tell you if something is altering its status or if the problem lies elsewhere.

trastikata

Quote from: Stephen Moss on Feb 14, 2023, 08:51 AMHave you tried reading the AD12B bit and outputting it to a pin to see if has been set or cleared, that should tell you if something is altering its status or if the problem lies elsewhere.

Good idea Stephen Moss! It seems that ADIn clears the AD12B bit (AD1CON1.10).

In the following code I set AD1CON1.10 to 1 and then I print the register bit as confirmation, after ADIn has been called, the AD1CON1.10 is displayed again and it seems is being cleared to 0.

    AD1CON1.10 = 1                      '12-bit, 1-channel ADC operation
    PrintNumber(6, 6, AD1CON1.10, 2)    'Display AD1CON1.10
    wVoltageAdc = ADIn 2                'Read ADC
    PrintNumber(7, 6, AD1CON1.10, 2)    'Display AD1CON1.10