View previous topic :: View next topic |
Author |
Message |
2xhp
Joined: 14 Jan 2019 Posts: 39
|
setup_adc and ADC_CLOCK_INTERNAL |
Posted: Tue Apr 27, 2021 5:58 pm |
|
|
I'm running a 18F25K80 at 40 MHz (10 MHz crystal with 4x PLL). So I chose initially ADC_CLOCK_DIV_64. The readings were correct at some points, but as the input voltage to the ADC got closer to Vdd (Vdd is 5.0 V) ... like in the 3.8 V range, then the results started doing weird things like going down slightly instead of rising.
I've had some recent problems on some other chips with the ADC due to compiler version. I had been running PCH 5.087, so I decided to upgrade to 5.103. No change.
I then tried changing the ADC clock setting attempting the various options. Same result ... until I tried ADC_CLOCK_INTERNAL. Then the results started to be right on the money throughout the entire range.
Here's the list file for the ADC setup:
.................... setup_adc_ports(sAN0 | sAN1 | sAN2, VSS_VDD);
2DB0: MOVLB F
2DB2: MOVF x5C,W
2DB4: ANDLW 80
2DB6: MOVWF x5C
2DB8: MOVLW 07
2DBA: MOVWF x5D
2DBC: BCF FC1.3
2DBE: BCF FC1.4
2DC0: BCF FC1.5
.................... setup_adc(ADC_CLOCK_INTERNAL);
2DC2: MOVF FC0,W
2DC4: ANDLW C0
2DC6: IORLW 07
2DC8: MOVWF FC0
2DCA: BSF FC0.7
2DCC: BSF FC2.0
....................
From what I can tell looking at the datasheet register, this seems correct (but I'm not really proficient at reading assembly, so I might be missing something. For example, I don't understand why bits 0 and 7 have to be set when it seems to me they would already be set from the previous operations).
Any ideas why ADC_CLOCK_INTERNAL seems to cause it to work correctly and everything else produces problems? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Apr 27, 2021 6:09 pm |
|
|
According to the 18F25K80 data sheet, the correct divisor for 40 MHz is 32.
I was able to make an 18F46K80 give correct A/D results by adding
the ADC_TAD_MUL_20 parameter to setup_adc(). See the sample
code in this thread:
http://www.ccsinfo.com/forum/viewtopic.php?t=59279 |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1907
|
|
Posted: Tue Apr 27, 2021 6:18 pm |
|
|
Sounds like the acquisition time isn't sufficient. This is the time between connecting the A/D channel and when conversion actually begins. It needs to be sufficiently long to allow the PIC's internal sample capacitor to charge sufficiently. ACQT bits of the ADCON2 register. Look in the 18F25K80.h file, approximately line 590 or so. Try ORing ADC_TAD_MUL_xx (x = 0 to 20) with your clock divider in setup_adc(). Consult chapter 23 of the device's data sheet.
Edit: PCM beat me to the punch! |
|
|
2xhp
Joined: 14 Jan 2019 Posts: 39
|
|
Posted: Tue Apr 27, 2021 6:22 pm |
|
|
PCM programmer wrote: | According to the 18F25K80 data sheet, the correct divisor for 40 MHz is 32.
I was able to make an 18F46K80 give correct A/D results by adding
the ADC_TAD_MUL_20 parameter to setup_adc(). See the sample
code in this thread:
http://www.ccsinfo.com/forum/viewtopic.php?t=59279 |
I see that I should have gone with 32 to begin with. I had tried that afterwards though with the same bad results.
However, you are a genius ... setting it to 32 with ADC_TAD_MUL_20 works!
Thank you! |
|
|
2xhp
Joined: 14 Jan 2019 Posts: 39
|
|
Posted: Tue Apr 27, 2021 6:24 pm |
|
|
newguy wrote: | Sounds like the acquisition time isn't sufficient. This is the time between connecting the A/D channel and when conversion actually begins. It needs to be sufficiently long to allow the PIC's internal sample capacitor to charge sufficiently. ACQT bits of the ADCON2 register. Look in the 18F25K80.h file, approximately line 590 or so. Try ORing ADC_TAD_MUL_xx (x = 0 to 20) with your clock divider in setup_adc(). Consult chapter 23 of the device's data sheet.
Edit: PCM beat me to the punch! |
Wonderful - and appreciate the explanation (it really helps!) Thank you! |
|
|
|