Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

PIC18f2431 Simple ADC?

Status
Not open for further replies.

Athosza

Newbie level 5
Joined
Aug 3, 2010
Messages
8
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Location
South Africa
Activity points
1,363
Greetings all,

I am having a problem with getting a simple ADC working. I have tried to read the data sheet of the PIC with as much understanding as possible but I am still stuck. What I am trying to do is simply read a change in voltage and get the PIC to convert the value to digital and store it in 'variable'. I am simply using either 0V or 5V however no matter what I select my TAD or TOSC the only value that is stored in variable is 0x03FF and this is why I included the LED code so that if there was a change I could see it straight away. I am not sure if my code is correct perhaps I am making a mistake somewhere.

Any help/feedback will be greatly appreciated.

Thanks
Athosza

my code: (C 18 compiler)

#include <p18f2431.h>
#include <stdlib.h>
#include <adc.h>

#define ADC_CH0 0x00 //Select Channel 0

void oscillator_setup()
{
OSCCON = 0x76; // 8MHz internal clock frequency
TRISB = 0;
PORTB = 0;
}

void Setup_ADC()
{
ADCON0 = 0x03;// Group A is taken
ADCON1 = 0x18; // AVdd and AVss selected as voltage reference
ADCON2 = 0xc7; // 20 TAD and RC Tosc
ADCON3 = 0xc0; // No trigers in use
ADCHS = 0x00; // All channels are selected, only AN0 is in Group A
ANSEL0 = 0x11; // AN0 is selected as analog input
}

void main()
{

int variable = 0;
oscillator_setup();
Setup_ADC();


while(1) {

ConvertADC();
BusyADC();
variable = ReadADC();
variable = variable;

if (variable == 0x03FF)
PORTB = 0x03;
else if (variable != 0x03FF)
PORTB = 0x0c;
}
}
 

Hi,

I assume you are using C18 from Microchip, if you are then using ADC is a lot easier than you think. if you look at page number 18 of MPLAB-C18-Libraries_51297f.pdf
located in MCC18\doc you will see how easy it is.

here is the example from the file:


2.2.2 Example Use of the A/D Converter Routines
Code:
#include <p18C452.h>
#include <adc.h>
#include <stdlib.h>
#include <delays.h>
int result;
void main( void )
{
// configure A/D convertor
OpenADC( ADC_FOSC_32 & ADC_RIGHT_JUST & ADC_8ANA_0REF,
ADC_CH0 & ADC_INT_OFF );
Delay10TCYx( 5 ); // Delay for 50TCY
ConvertADC(); // Start conversion
while( BusyADC() ); // Wait for completion
result = ReadADC(); // Read result
CloseADC(); // Disable A/D converter
}

so if you see here, the BusyADC(); is used to halt the processor till the conversion is complete.
 

    Athosza

    Points: 2
    Helpful Answer Positive Rating
Hi,

Thank you for your reply, I am aware of the C18 compiler libraries. I have attempted to use them unsuccessfully. The pic 18F2431 does not support the SetChanADC(); command, this makes it tough to select which channel is to be used. For this reason I have tried to set all of the configuration bits myself. Perhaps there is an alternative to the SetChanADC command that I am unaware of, however if there is it does not appear in the C18 compiler libraries.

Thanks again,
Athosza
 

Hi,

well there is support, some reverse engineering tells that the compiler defines the ADC for this PIC as ADC_V7_1. If you search for this in files in the folder : MCC18\src\pmc_common\ADC you will see statements defined as :

#elif defined (ADC_V7_1)

anything defined in these blocks is specific to this processor. The alternative is SelChanConvADC.

Its documented here: MCC18\doc\periph-lib\AD Converter.htm

Hope it helps.

regards

Added after 42 minutes:

Ok ive made an example for you. Its a simple ADC implemented to read channel 0
Ive tried it in simulation as I don't have this PIC. but it works.


Code:
#include <p18Cxxx.h>
#include <adc.h> 
#include <stdlib.h> 
#include <delays.h> 
int result; 
void main( void ) 
{ 
	TRISA = 0xFF;
	TRISB = 0x00;

// configure A/D convertor 
OpenADC( ADC_CONV_SINGLE_SHOT    &
         ADC_MODE_SINGLE_CH    &
         ADC_CONV_SEQ_SEQM1 &
         ADC_INT_OFF,
         ADC_REF_VDD_VSS      &
         ADC_FIFO_DIS         &
         ADC_TRIG_TMR_5,     
         ADC_RIGHT_JUST       & 
         ADC_10_TAD           &
         ADC_FOSC_8           

         );
while(1){
SelChanConvADC(0);
Delay10TCYx( 5 ); // Delay for 50TCY 
ConvertADC(); // Start conversion 
while( BusyADC() ); // Wait for completion 
result = ReadADC(); // Read result 
}
CloseADC(); // Disable A/D converter 


}

In the image the result value is displayed and it changed from 0-1022 with the trimmer so it works. Please double check the configuration as I might have missed some bits and bobs.
 

Greetings Spiralbrain,

Thanks for your help and the code. I have still been unable to implement it correctly however due to the fact that I am using a PICDEM 2 Plus Demo board and I have been told by one of my colleagues that it is virtually impossible to get ADC working on this board due to the Vref pin AVDD (pin 7) not having any power at all. I check the board and found this to be correct. So there is no reference voltage for the PIC to use.

As such I have moved my efforts onto a bread board with a PICkit 2 but I am having difficulty getting In circuit debugging working as the PICkit 2 wont recognize my device. Hence I am seeking help again here:

Thanks again.

Added after 1 hours 59 minutes:

Hello spiralbrain,

I finally sorted out my PICkit 2 issues and now have been able to test my code as well as your code and they both work great. Thanks so much for the help :D
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top