View previous topic :: View next topic |
Author |
Message |
Spero
Joined: 25 Nov 2012 Posts: 4 Location: South Africa
|
ADC issue with PIC24F |
Posted: Fri Jan 04, 2013 1:05 pm |
|
|
PIC: 24FJ64GA006
PCD: ver 4.132
Hi guys,
I'm trying to implement a simple ADC driver. I have a 3V lithium coin cell connected to RB3 (AN3) and the PIC is powered from 3.3V. On detecting a button press, the ADC should run and sample once and print out the cell voltage however I always get zero.
Tried two options, one using the built in CCS commands and the other setting up the registers and controlling the ADC manually - both no luck...
Can anyone see what I'm doing wrong?
Thanks,
Spero
OPTION 1
Code: |
long ADC_value;
.
.
void main() {
.
.
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(sAN3);
set_adc_channel(3);
.
.
.
if(!input(BUTTON)) {
ADC_value = read_adc(ADC_START_ONLY);
fprintf(1,"\r\nADC_value: %LX", ADC_value);
BUTTON_release_debounce();
}
} |
OPTION 2
Code: |
long ADC_value;
#byte ADC1BUF0 = 0x0300
#byte AD1CON1 = 0x0320
#byte AD1CON2 = 0x0322
#byte AD1CON3 = 0x0324
#byte AD1CHS = 0x0328
#byte AD1PCFG = 0x032C
#byte AD1CSSL = 0x0330
#bit ADON = 0x0320.15
#bit SAMP = 0x0320.1
#bit DONE = 0x0320.0
.
.
void main() {
.
.
// Initialise A/D module - manual sampling and manual conversion control
AD1PCFG = 0xFFF7; // RB3 (AN3) configured as A/D input for RTC Vbat - all other RB pins are digital I/O
AD1CON1 = 0x0000; // A/D converter off (ADON = 0)
// Continue in idle mode
// Integer data format
// Clearing SAMP bit ends sampling and starts conversion (SSRC = 000)
// Sampling begins when the SAMP bit is set (ASAM = 0, no auto start)
AD1CHS = 0x0003; // Channel 0 negative input is Vr- (CH0NA = 0)
// Channel 0 positive input is AN3 (CH0SA = 3)
AD1CSSL = 0x0000; // No inputs are scanned
AD1CON3 = 0x0002; // A/D conversion clock derived from system clock
// A/D conversion clock = Tcy (Fcy = 12MHz => Tcy = 83.3nS which is greater then the min Tad of 75nS)
AD1CON2 = 0x0000; // Voltage reference: Vr+ = Avdd and Vr- = Avss
// No scanning of inputs (CSCNA = 0)
// A/D data buffer configured as one 16-word buffer
// Always uses MUX A input multiplexor settings (ALTS = 0)
ADON = 1;
.
.
if(!input(BUTTON)) {
SAMP = 1; // Start sampling
delay_us(10);
SAMP = 0; // Stop sampling and initiate conversion
while(!DONE)
delay_us(2);
delay_ms(200);
ADC_value = ADC1BUF0;
fprintf(1,"\r\nADC_value: %LX", ADC_value);
BUTTON_release_debounce();
}
}
|
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Fri Jan 04, 2013 1:30 pm |
|
|
ok..I'll offer a few tips though I don't use the 24 series PICs..
1) trim your program down to.. a simple loop of reading the ADC,display, wait 1/2 second,loop again...eliminates any 'switch bounce',button pressing,etc. 'problems'...allows 'handsfree' testing( twiddling of pot...)
2) I don't see all the ADC setup( vref...etc) and 'adc_clock_internal' may not be the correct choice.speed of adc is related to processor clock( it's in the datasheets.....)
3) have a look at the examples CCS supplies in the examples folder.I think it has a simple pot tied to adc00,dumps data to PC comport...
4)also don't see a complete program( fuses,ADCc setup, use rs232, etc...)
5) is there a 'pin select' feature with this PIC ?
6) compiler version...might be buggy ?
7) analog ground not grounded ?
as I said, I don't have that chip but making a bare minimum program should help see what's wrong.
hth
jay |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jan 04, 2013 2:46 pm |
|
|
I don't have the PCD compiler, but the read_adc() function is similar
so I can make some comments:
Don't do this. You're doing only a partial operation:
Quote: | ADC_value = read_adc(ADC_START_ONLY); |
Use the basic form and let the compiler do everything that it needs to do
to read the ADC. This is the normal usage:
Code: | ADC_value = read_adc(); |
|
|
|
Spero
Joined: 25 Nov 2012 Posts: 4 Location: South Africa
|
|
Posted: Sat Jan 05, 2013 12:56 pm |
|
|
Thanks for the input - got it working now.
It was due to a few misplaced delays and a suspect port pin on the PIC. The 'ADC_value = read_adc();' also helps.
Having said that though, the ADC module needs some trial & error to get stable... |
|
|
|