View previous topic :: View next topic |
Author |
Message |
madcat
Joined: 30 Jul 2008 Posts: 17
|
ADC does not work after PIC18F4520 to PIC18F4620 upgrade |
Posted: Tue Dec 16, 2008 5:30 pm |
|
|
Hi to all,
I've used an 4520 to develop my software & hardware until 4620 arrived.
I had a perfectly working ADC routines.
I use MPLAB 8.1 as my IDE, ICD2 as debugger and CCS v4.068 compiler
After I've got the 4620 I replaced the chip and changed the include to <18F4620.h> (+ selected 4620 as target.)
I don't see any other changes I have to make. Both have AN0 on pin#2
128x64 LCD works fine, PWM controls the backlight fine. ADC reads a constant 0 (zero) output out of my light sensor at AN0
If I switch back to 4520 - it works fine.
My ADC init code is :
Code: |
setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
Then : light_lvl = read_adc(); inside the loop to read the sensor
|
Any ideas on what may be different on the 4620 compared to 4520 in relation to ADC ? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
madcat
Joined: 30 Jul 2008 Posts: 17
|
|
Posted: Tue Dec 16, 2008 5:59 pm |
|
|
Here is my test program (simplified from the one that works with 4520)
I don't feel comfortable with the "itoa" but even when I watch the value of "light_lvl" in IDE it is zero.
If I change #device ADC=10 the value becomes "2" ...
Code: |
#include <18F4620.h>
#device ADC=8
#device ICD=TRUE
#fuses HS, NOWDT, NOLVP, NOBROWNOUT, NOPROTECT, PUT, CCP2C1
#zero_ram
#use delay(clock=37188789)
#define FAST_GLCD
#include <HDM64GS12.h>
#include <graphics.h >
#include <stdlib.h>
void main()
{
char txt[8];
int16 light_lvl;
// Setup Light Sensor
setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
// Init LCD
glcd_init(ON);
glcd_fillScreen(OFF);
glcd_update();
while(TRUE) {
glcd_fillScreen(OFF);
light_lvl = read_adc();
itoa(light_lvl, 10, txt);
glcd_text57(20, 55,txt, 1, ON);
glcd_update();
delay_ms(40);
}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Dec 16, 2008 6:32 pm |
|
|
Download the 18F4620 data sheet and look in this section:
Quote: | 19.3 Selecting the A/D Conversion Clock
TABLE 19-1: TAD vs. DEVICE OPERATING FREQUENCIES |
Notice the maximum oscillator frequency restriction on using the
internal R/C oscillator for the ADC. You're running at almost 40 MHz.
The table gives two divisors that are more appropriate for that frequency.
Look in the 18F4620.H file (in the A/D section), to find the CCS constants
for those divisors. Use one of those constants instead of ADC_CLOCK_INTERNAL.
18F4620 Data sheet:
http://ww1.microchip.com/downloads/en/DeviceDoc/39626e.pdf |
|
|
madcat
Joined: 30 Jul 2008 Posts: 17
|
|
Posted: Tue Dec 16, 2008 6:47 pm |
|
|
The table says that 18F4620 at 40MHz needs TAD of 32 TOSC or 64 TOSC
from the .h file :
Code: |
// Constants used for SETUP_ADC() are:
#define ADC_OFF 0 // ADC Off
#define ADC_CLOCK_DIV_2 0x100
#define ADC_CLOCK_DIV_4 0x04
#define ADC_CLOCK_DIV_8 0x01
#define ADC_CLOCK_DIV_16 0x05
#define ADC_CLOCK_DIV_32 0x02
#define ADC_CLOCK_DIV_64 0x06
#define ADC_CLOCK_INTERNAL 0x07 // Internal 2-6us
// The following may be OR'ed in with the above using |
#define ADC_TAD_MUL_0 0x00
#define ADC_TAD_MUL_2 0x08
#define ADC_TAD_MUL_4 0x10
#define ADC_TAD_MUL_6 0x18
#define ADC_TAD_MUL_8 0x20
#define ADC_TAD_MUL_12 0x28
#define ADC_TAD_MUL_16 0x30
#define ADC_TAD_MUL_20 0x38
|
I've tried both setup_adc(ADC_CLOCK_DIV_64) and setup_adc(ADC_CLOCK_DIV_32);
Both give ZERO :(
EDIT: also payed attention that this table is same for both 4520 and 4620.
4520 works even with ADC_CLOCK_INTERNAL ... |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Dec 16, 2008 6:53 pm |
|
|
Quote: | #use delay(clock=37188789) |
Do you really have a crystal or oscillator that runs at that frequency ? |
|
|
madcat
Joined: 30 Jul 2008 Posts: 17
|
|
Posted: Tue Dec 16, 2008 7:08 pm |
|
|
PCM programmer wrote: | Quote: | #use delay(clock=37188789) |
Do you really have a crystal or oscillator that runs at that frequency ? |
Yes I do. Exactly at this frequency.
Also I've just tried the :
#fuses INTRC and setup_adc(ADC_CLOCK_INTERNAL);
That supposed to be at 31Khz ? gives ZERO as well ....... |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Dec 16, 2008 7:25 pm |
|
|
I would make a test program that only uses RS-232 to display the output.
Use printf to display the "%LX" 16-bit adc result.
I would get rid of all the GLCD code, #zero_ram, etc., and also put in
a much larger loop delay, such as 500 ms. |
|
|
madcat
Joined: 30 Jul 2008 Posts: 17
|
|
Posted: Tue Dec 16, 2008 7:41 pm |
|
|
PCM programmer wrote: | ......I would get rid of ...... #zero_ram..... |
THANK YOU !
It works and even in my original test program (with GLCD, PWM etc..)
and even with ADC_CLOCK_INTERNAL and 40 MHz
I've just removed the #zero_ram .... WHY not with 4620 ?! bug ?
Interesting is that if I keep the #zero_ram and measure the actual voltage on the A0 pin it is really ZERO ! means it pulls it to ground. Do you have any idea why ? |
|
|
madcat
Joined: 30 Jul 2008 Posts: 17
|
|
|
|