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.

[PIC] PIC32mx440f256h controller interfacing with ADC

Status
Not open for further replies.

shrutipatel

Newbie level 4
Joined
Feb 21, 2018
Messages
7
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
62
Hi, I am trying to read analog inputs on channel RB8 to RB11 on pic32mx440f256h controller. I have built my own kit using pickit3 & MPLAB IDE for programming the same. If anybody is having the code for the same please help.

I am getting errors & unable to read the data every time getting values as 0

Thanks
 

Which compiler version you are using?

- - - Updated - - -

Install xc32 1.22 version or previous version.This compiler has inbuilt peripheral libraries.Latest XC32 version doesnt have inbuilt peripheral library.

- - - Updated - - -

You will find examples how tp read ADC using peripheral libraries (plib.h)
 

Can you show us your code including the config settings? Actually a small but complete program that exhibits the problem would be better.
Making several wild guesses as to the problem, check that:
- the JTAG config option is off - RB10 has the JTAG TMS function and RB11 has the JTAG TDO function on it that will stop the signal reaching the internal ADC
- the AD1PCFG register has been set correctly - while the POR default is akk 0 (i.e. all analog), if you are running a DEBUG build then the debugging kernel will alter all analog inputs to defaultto digital
- have you got the TRISB register set to 'input' for those pins (section 12.1.3 in the data sheet)
Susan
 

Which compiler version you are using?

- - - Updated - - -

Install xc32 1.22 version or previous version.This compiler has inbuilt peripheral libraries.Latest XC32 version doesnt have inbuilt peripheral library.

- - - Updated - - -

You will find examples how tp read ADC using peripheral libraries (plib.h)

>> I am using MPLAB IDE With MPLAB C32 v1.11
 

Here is my code to read adc values:

Code:
#include <p32xxxx.h>
#include <plib.h>
//#include <xc.h>

 // configuration bit settings, Fcy=72 MHz, Fpb=36 MHz
 #pragma config POSCMOD=XT, FNOSC=PRIPLL
 #pragma config FPLLIDIV=DIV_2, FPLLMUL=MUL_18, FPLLODIV=DIV_1
 #pragma config FPBDIV=DIV_2, FWDTEN=OFF, CP=OFF, BWP=OFF

 #define POT 8 // 10 k potentiometer 
 #define AINPUTS 0xff7f // Analog inputs POT, TSENS 

void initADC( int amask)
 {
 AD1PCFG = amask; // select analog input pins
 AD1CON1 = 0x00E0; // automatic conversion after sampling
 AD1CSSL = 0; // no scanning required
 AD1CON2 = 0; // use MUXA, use AVdd &AVss as Vref+/-
 AD1CON3 = 0x1F3F; // Tsamp = 32 x Tad;
 AD1CON1bits.ADON = 1; // turn on the ADC
} //initADC

 int readADC( int ch)
 {
 AD1CHSbits.CH0SA = ch; // 1. select input channel
 AD1CON1bits.SAMP = 1; // 2. start sampling
 while (!AD1CON1bits.DONE); // 3. wait conversion complete
 return ADC1BUF0; // 4. read conversion result
 } // readADC 


void DelayMs(unsigned int msec)
{
	unsigned int tWait, tStart;
		
    tWait=(80000000/2000)*msec;
    tStart=ReadCoreTimer();
    while((ReadCoreTimer()-tStart)<tWait);		// wait for the time to pass

}

 main ()
 {
 int i, a;
// initializations
 initADC( AINPUTS); // initialize the ADC

 // main loop
 while( 1)
 {
 a = readADC(8); // select the POT input and convert
 } // main loop
 } // main
 
Last edited by a moderator:

I have code for XC32 compiler but not for C32.
 

Here is my code to read adc values

Taking a look at your code, at the readADC() function it seems to be missing a main step, the conversion itself:

AD1CON1bits.SAMP = 0;
In addition, you are perhaps not providing enough time to internal A/D capacitance to hold sampled value.
 

Code:
int analogRead(char analogPIN)
{
     AD1CON1  = 0x000000E0;
    AD1CHS = 0;
    AD1CSSL = 0;
    AD1CON2 = 0x00000000;
    AD1CON3 = 0x00001F00;    

    AD1CON1bits.ADON = 1;
    AD1CHS = analogPIN << 16;       // AD1CHS<16:19> controls which analog pin goes to the ADC
 
     
    //AD1CON1bits.SAMP = 0;
    AD1CON1bits.ASAM = 1;
   delay_ms(500);
    while (!IFS0bits.AD1IF);
    IFS0bits.AD1IF = 0;   
    //AD1CON1bits.SAMP = 1;
    AD1CON1bits.DONE = 0;  // wait until conversion done
 
    return ADC1BUF0;                // result stored in ADC1BUF0
}
 

A bare code with no extra comments, do not add much for this thread.
Moreover, you did not what was above suggested.
 

Akshay - that code is wrong is a couple of places and is conflating the initialisation and reading functions.
While setting the ASAMP bit does have the side effect of setting the SAMP bit, it also means that you will automatically start another sample after the previous one has completed. The way you have written your code, this would cause a lot of unnecessary sampling.
Also it is not a good idea to use a delay function to see when the sampling and conversion process is complete - that is what the DONE bit will tell you but is really only useful in manual sampling mode. Also you do not stop a conversion by clearing this bit - the FRM states that it will not stop any operation that is in progress.
Shrutipatel - if you can then I would suggest that you download the latest MPLABx and XC32 compiler - they are both free. Also download and read the Family Reference Manual section of the ADC - it contains a complete description of the converter, the function of each register as well as examples of how the device should be used.
Susan
 

Akshay - that code is wrong is a couple of places and is conflating the initialisation and reading functions.
While setting the ASAMP bit does have the side effect of setting the SAMP bit, it also means that you will automatically start another sample after the previous one has completed. The way you have written your code, this would cause a lot of unnecessary sampling.
Also it is not a good idea to use a delay function to see when the sampling and conversion process is complete - that is what the DONE bit will tell you but is really only useful in manual sampling mode. Also you do not stop a conversion by clearing this bit - the FRM states that it will not stop any operation that is in progress.
Shrutipatel - if you can then I would suggest that you download the latest MPLABx and XC32 compiler - they are both free. Also download and read the Family Reference Manual section of the ADC - it contains a complete description of the converter, the function of each register as well as examples of how the device should be used.
Susan

But that code seems working fine.
 

But that code seems working fine.

It's a bit intriguing to understand what you meant by "seems to work" because it does not make it clear if the code was actually tested and approved. Regarding the code itself, the way as you have implemented, it does "seem not work" due to be missing important parts, but I may be wrong. Anyway, you still have not informed why you have posted it, whether it was just to point out the changes that were supposed to not suffice, or whether it was just to close the thread as resolved (which you have not done yet).
 

The reason it may seem to be working is as follows:
Every time you call the 'analogRead' function, it will initialise the the ADC. In fact the 2nd and subsequent times you call the function, the initialisation will simply over-write the control registers with the same value it should already have, except that the first write to ADCON1 will also turn off the ADC.
You then start the sampling process going by setting the ASAM bit.
The ADC will then go into a continuous cycle of sampling the channel, converting the value and saving it in the ADCxBUF array, and then starting the cycle all over again.
You wait for 500msec during which time the ADC will have made a large number of measurements), wait for the ADIF bit to be set (which is was after the first measurement cycle), clear the ADIF bit (and it will probably be set again very soon after as the next measurement cycle completes).
Next you try to set the DONE bit to 0. As explained in section 17.5.6 of the ADC FRM section for this device, manually doing anything with the DONE bit in automatic sample mode (which you are in with the ASAM bit set) doesn't achieve anything as the hardware is setting and clearing this bit on each measurement cycle.
You then leave the function with the ADC still working away making measurements automatically.
When you call the function again, you start the whole thing from the top but the end result is the same.
Therefore it appears that your function will be working but it is really just providing you with one of the huge number of measurements that it is making the whole time and then throwing away.
Just because it appears to work does not mean it is working the way you expect and (judging by the way the function is coded) have designed it to.
Susan
 

Akshay - that code is wrong is a couple of places and is conflating the initialisation and reading functions.
While setting the ASAMP bit does have the side effect of setting the SAMP bit, it also means that you will automatically start another sample after the previous one has completed. The way you have written your code, this would cause a lot of unnecessary sampling.
Also it is not a good idea to use a delay function to see when the sampling and conversion process is complete - that is what the DONE bit will tell you but is really only useful in manual sampling mode. Also you do not stop a conversion by clearing this bit - the FRM states that it will not stop any operation that is in progress.
Shrutipatel - if you can then I would suggest that you download the latest MPLABx and XC32 compiler - they are both free. Also download and read the Family Reference Manual section of the ADC - it contains a complete description of the converter, the function of each register as well as examples of how the device should be used.
Susan

Please suggest me what changes need to made?
 

All of the necessary changes have really be discussed above.
For example, everything down to turning the ADC on is the initialisation part. Depending on how you intend to use the ADC, setting the channel may or may not be part of the initialisation or the first thing to do in the main 'ADC-Read' function. (This assumes that you are setting the ADC up now the way you intend - reference sources, sample timing etc..) See Section 17.4 of the FRM section for all of the details for this part.
FRM Section 17.4.15 shows how to start the sampling process. Also look at Examples 17-1 to 17-5 for code examples (note that these examples also have the initialisation code at the top, separated by a couple of blank lines - the part you are interested in here is within the 'while' loop in those examples).
Susan
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top