Electrical – How to display potentiometer value from dspic33 microcontroller

adcmicrochipmicrocontrollerpicpotentiometer

I am new to the microcontroller world and am using a dsPIC33EP256MC506 controller and dsPICDEM -2 MCLV development board for a project. I am trying to read the value of the potentiometer that is on the dev board, but am having trouble. I just want to be able to run the program and move turn the potentiometer and see the program output the value. I know that I have to use ADC ports somehow to do this, but I'm not exactly sure how to use it. Documentation has not been very helpful on how to do this in the program either. If anyone can direct me to documentation that uses ADC to control the potentiometer or help me get started with this that would be great.

Also, does anyone know where this value will be displayed? It makes sense to me that it would be displayed in the Variables output tab, but no values seem to be populating for any variable.

Microcontroller: dsPIC33EP256MC506

Development Board: dsPICDEM -2 MCLV

Programmer/Debugger: REAL ICE

Compiler: MPLAB X – XC16

Thanks again!

#include <p33Exxxx.h>
/****************************CONFIGURATION****************************/

_FOSCSEL(FNOSC_FRC);
_FOSC(FCKSM_CSECMD & POSCMD_XT & OSCIOFNC_OFF & IOL1WAY_OFF);
_FWDT(FWDTEN_OFF);
_FPOR(ALTI2C1_ON & ALTI2C2_ON);
_FICD(ICS_PGD1 & JTAGEN_OFF);

void initAdc1(void);
void Delay_us(unsigned int);
int  ADCValue, i;
int  main(void)
{
// Configure the device PLL to obtain 40 MIPS operation. The crystal frequency is 8 MHz.
// Divide 8 MHz by 2, multiply by 40 and divide by 2. This results in Fosc of 80 MHz.
// The CPU clock frequency is Fcy = Fosc/2 = 40 MHz.
PLLFBD = 38;                    /* M  = 40 */
CLKDIVbits.PLLPOST = 0;         /* N1 = 2  */
CLKDIVbits.PLLPRE = 0;          /* N2 = 2  */
OSCTUN = 0;
/* Initiate Clock Switch to Primary Oscillator with PLL (NOSC = 0x3) */
__builtin_write_OSCCONH(0x03);
__builtin_write_OSCCONL(0x01);
while (OSCCONbits.COSC != 0x3);
while (_LOCK == 0);             /* Wait for PLL lock at 40 MIPS */
initAdc1();
while(1)
{
    AD1CON1bits.SAMP = 1;         // Start sampling
    Delay_us(10);                 // Wait for sampling time (10 us)
    AD1CON1bits.SAMP = 0;         // Start the conversion
    while (!AD1CON1bits.DONE);    // Wait for the conversion to complete
    ADCValue = ADC1BUF0;          // Read the ADC conversion result
}
}
    void initAdc1(void) {
     /* Set port configuration */ 
     ANSELA = ANSELB = ANSELC  = ANSELE = 0x0000;
    //ANSELBbits.ANSB5 = 1;           // Ensure AN5/RB5 is analog
    ANSELBbits.ANSB0 = 1;
    ANSELAbits.ANSA0 = 1;

// A0 and B0 are inputs
TRISAbits.TRISA0 = 1;
TRISBbits.TRISB0 = 1;

/* Initialize and enable ADC module */

AD1CON1 = 0x0000;
AD1CON2 = 0x0000;
AD1CON3 = 0x000F;
AD1CON4 = 0x0000;
AD1CHS0 = 0x0000;
// 0000 0000 0000 0101
AD1CHS123 = 0x0000;
AD1CSSH = 0x0000;
AD1CSSL = 0x0000;
AD1CON1bits.ADON = 1;
Delay_us(20);
}
void Delay_us(unsigned int delay)
{
for (i = 0; i < delay; i++)
{
    __asm__ volatile ("repeat #39");
    __asm__ volatile ("nop");
}
}

Best Answer

You are not waiting for conversion to complete.

Algorithm for ADC operations is as follows:

  1. Initialize ADC and Pin for Analog channel
  2. Start the conversion
  3. Wait for conversion to complete
  4. Read the result buffer when conversion is complete
  5. Go to step 3

In your case, you are not waiting or reading the result buffer. Datasheet is helpful enough to understand the registers.

Related Topic