View previous topic :: View next topic |
Author |
Message |
pekka1234
Joined: 28 May 2017 Posts: 100
|
ADC=12 in PIC16-series! |
Posted: Tue Sep 02, 2025 1:10 am |
|
|
Hey, I have found a new feature in CCS
A normal 16F-series ADC setup uses #device ADC=10 as the setup.
Or it can also #device ADC=8
I needed more accuracy on analog measurement, and I used certain
PIC18F-series with #device ADC=12.
I needed it for the length measurement with a potentiometer.
It worked, and then I tried a normal PIC16F886 with #device ADC=12.
It worked! Fine.
Then I used #device ADC=14 and #device ADC=13, but they don't work.
Are both series inside similar?
Code: |
#include <16F886.h>
#device ADC=12 // it should be normally ADC=10, but it works with ADC=12
#fuses NOWDT, INTRC_IO, NOPROTECT, NOLVP, NOMCLR
#use delay(internal=8000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,INVERT)
// I use a normal RS232 connection with 1k input from pin 3 and direct to in 2, with a normal DB9 connection
unsigned int16 measurement;
void measure ()
{
measurement= read_adc();
printf("%lu\r",measurement);
}
void main(void) {
char x,c;
setup_oscillator(OSC_8MHZ); // 8 MHz internal
set_tris_c(0b00000001); // RC0 (T1CKI) input
set_tris_c(get_tris_c() & ~0x02); // RC1 output for debug LED
printf("Lenght measurement 2.9.2025\r");
setup_adc_ports(ALL_ANALOG); // All pins analog (that can be)
setup_adc_ports(sAN0, VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
while(TRUE) {
measure(); // send a new measurement
c=getc(); // wait a character
output_toggle(pin_c4);// show with LED when a new ask signal has come
if(c==13) // a new Enter signal
printf("Got a CR\r\n");// wait when the master ask a new measurement
}
}
| [/code] |
|
 |
gaugeguy
Joined: 05 Apr 2011 Posts: 338
|
|
Posted: Tue Sep 02, 2025 5:59 am |
|
|
There are no cheat codes you can unlock. With 10 bit A/D hardware in the PIC16F886 you will not get 12 bit resolution. |
|
 |
temtronic
Joined: 01 Jul 2010 Posts: 9578 Location: Greensville,Ontario
|
|
Posted: Tue Sep 02, 2025 6:15 am |
|
|
gg is right.
I assume the compiler knows 8,10, and 12 are 'valid' options so allows those values but doesn't error check IF they are valid on a PIC by PIC basis.
Simple task....dump the listing and see how the compiler coded the ADC registers. |
|
 |
pekka1234
Joined: 28 May 2017 Posts: 100
|
|
Posted: Tue Sep 02, 2025 8:22 am |
|
|
Ok, I try, but you can be right.
It appears to be the correct value, 0-4095.
Pekka |
|
 |
jaka
Joined: 04 May 2014 Posts: 41 Location: Finland
|
|
Posted: Tue Sep 02, 2025 11:28 pm |
|
|
Some weeks ago I tried to be smart with the #device ADC setting, but failed. Be careful.
I had existing NTC temperature lookup code developed with PIC16F1789 which has 12-bit ADC. I re-used the code on PIC16F15355 which has 10-bit ADC. I tried to cheat by setting #device ADC=12 with PIC16F15355 so I could use the same ntc_lookup.c file without changes in the code.
But somehow it failed even though initially seemed it should work. So I set #device ADC=10 and just oversampled 4x more. |
|
 |
pekka1234
Joined: 28 May 2017 Posts: 100
|
|
Posted: Wed Sep 03, 2025 2:40 am |
|
|
Well. It may be a different CPU.
I have used PIC16F886 and many more. It accepts 12-bit, but not 13 or more bits.
It needs more examinations
Pekka |
|
 |
gaugeguy
Joined: 05 Apr 2011 Posts: 338
|
|
Posted: Wed Sep 03, 2025 5:56 am |
|
|
The data sheet is how you determine the hardware capabilities. |
|
 |
sadier
Joined: 14 Sep 2025 Posts: 1
|
RE |
Posted: Sun Sep 14, 2025 5:34 am |
|
|
Interesting find! 👍
What’s happening here is that the CCS compiler directive #device ADC=x doesn’t actually change the hardware resolution of the ADC — it just tells the compiler what size result you expect from read_adc().
On PIC16F886, the hardware ADC is fixed at 10-bit resolution.
When you set #device ADC=12, CCS pads the 10-bit result into a 16-bit integer so your code still compiles and runs fine. You’re just getting the same 10-bit data, not true 12-bit accuracy.
That’s why #device ADC=13 or #device ADC=14 don’t work — CCS only supports valid compiler options (8, 10, or 12).
On the PIC18F-series parts you mentioned, some do indeed have true 12-bit ADC hardware. In that case #device ADC=12 matches the silicon.
So in short:
âś… Your PIC16F886 is still giving you 10-bit results, even though ADC=12 compiles.
❌ No hidden 12-bit (or higher) mode is unlocked — the hardware limits the resolution.
If you really need more resolution for your potentiometer measurement, you could:
Oversample and average readings to simulate higher resolution.
Use a PIC with a true 12-bit (or 16-bit) ADC.
Or use an external higher-resolution ADC chip. _________________ mGBA Emulator |
|
 |
|