1

I work with the PIC24FJ128GC010 on the MPLAB® Starter Kit for Intelligent.Integrated.Analog with the compiler XC16. I will read the 16-bit-Sigma-Delta ADC and show the result on the LCD-Display. I found some example codes in C for the board but it doesn't work now. When I run the code I get no mistake from the compiler but he underlines every "LCDPSbits." and "LCDREFbits." red and nothing is shown on the display. Here is my code in the latest state. Can anyone help me?

#include <xc.h>
#include "lcd.h"
#include "main.h"
#include "ADC_SigmaDelta.h"
#include "ui.h"
#include <math.h>


static signed long int offset;
static double SD_gain;

_CONFIG4(DSWDTPS_DSWDTPS1F // 1:68719476736 (25.7 Days)
        & DSWDTOSC_LPRC // DSWDT uses LPRC as reference clock
        & DSBOREN_OFF // DSBOR Disabled
        & DSWDTEN_OFF // DSWDT Disabled
        & DSSWEN_OFF // Deep Sleep operation is always disabled
        & RTCBAT_ON // RTC operation is continued through VBAT
        & PLLDIV_DIV2 // Oscillator divided by 2 (8 MHz input)
        & I2C2SEL_SEC // I2C2 is multiplexed to SDA2/RF4 and SCL2/RF5 (not used for demo)
        & IOL1WAY_OFF) // The IOLOCK bit can be set and cleared using the unlock sequence

_CONFIG3(WPFP_WPFP0 // Page 0 (0x00)
        & SOSCSEL_ON // SOSC circuit selected
        & WDTWIN_PS25_0 // Watch Dog Timer Window Width is 25 percent
        & BOREN_OFF // Brown-out Reset Disabled
        & WPDIS_WPDIS // Disabled
        & WPCFG_WPCFGDIS // Disabled
        & WPEND_WPSTARTMEM) // Write Protect from page 0 to WPFP

_CONFIG2(POSCMD_XT // XT Oscillator Enabled
        & WDTCLK_LPRC // WDT uses SOSC input
        & OSCIOFCN_ON // OSCO/CLKO/RC15 functions as port I/O (RC15)
        & FCKSM_CSDCMD // Clock switching and Fail-Safe Clock Monitor are disabled
        & FNOSC_PRIPLL // Primary Oscillator with PLL module (XTPLL,HSPLL, ECPLL)
        & ALTADREF_AVREF_RB // AVREF+/AVREF- are mapped to RB0/RB1
        & ALTCVREF_CVREF_RB // CVREF+/CVREF- are mapped to RB0/RB1
        & WDTCMX_LPRC // WDT always uses LPRC as its clock source
        & IESO_OFF) // Disabled

_CONFIG1(WDTPS_PS32768 // 1:32,768 (not used)
        & FWPSA_PR128 // 1:128
        & WINDIS_OFF // Standard Watchdog Timer
        & FWDTEN_WDT_DIS // WDT disabled in hardware; SWDTEN bit disabled
        & ICS_PGx3 // Emulator functions are shared with PGEC3/PGED3
        & LPCFG_ON // Low voltage regulator controlled in sw by RETEN bit
        & GWRP_OFF // Disabled
        & GCP_OFF // Code protection is disabled
        & JTAGEN_OFF) // Disabled

#define USE_SOSC        // Use the on-board 32.768KHz SOSC for RTCC and for the LCD timing generator

#define TC77CS _LATE9
#define TC77CS_TRIS _TRISE9

#define SW_VDD _LATA9
#define SW_VDD_TRIS _TRISA9
#define LED1 _LATE7
#define LED2 _LATB6

#define CLOCK 0
#define ADC_16BIT_SIGMA_DELTA 1
#define ADC_12BIT_PIPELINE 2
#define DAC_10BIT 3
#define TEMPERATURE 4
#define LCD_TEST 5
#define AUDIO 6
#define MAX_STATE 7

#define FOSC 32000000   /*Hz*/

lcd *LCD37x7;
ui *gcui;


uint16_t adcPotReading;
uint16_t adcLiteReading;
int16_t  adcExtReading;

uint16_t adc16_reading_ch0;
int16_t adc16_reading_ch1;
uint8_t temperature;

// Stores screen state when switched to sleep
volatile int8_t previousMenu;
volatile int8_t previousSubMenu;

int main(void) {
    // Disable nested interrupts
    _NSTDIS = 1;

    
    
    ADC_SD_Init();
    ADC_SD_GetRawResult();
    ADC_SD_GetCalibratedResult();
    LCDInit();
    
   int lcd_printf(const char * OffsetCalibratedResult);
    
   return 0; 
}

void LCDInit() {
    // Initialize LCD: no charge pump, 8 common drivers
    LCDPSbits.WFT = 0; // Type A waveform
    LCDPSbits.LP = 2; // LCD Prescaller 1:3
    LCDCONbits.LMUX = 0x07; // 8 commons, 1/3 Bias
#ifdef USE_SOSC
    LCDCONbits.CS = 2; // Clock is SOSC
#else
    LCDCONbits.CS = 1; // Clock is LPRC
#endif
    LCDREFbits.VLCD1PE = 0; // Enable internal bias
    LCDREFbits.VLCD2PE = 0;
    LCDREFbits.VLCD3PE = 0;
    LCDREFbits.LRLAP = 0x03; // ladder in High-Power Interval A (transition)
    LCDREFbits.LRLBP = 0x03; // ladder in High-Power Interval B (steady state, for higher contrast ratio))
    LCDREFbits.LRLAT = 0x03; // Internal LCD reference ladder is in A Power mode for 3 clocks and B Power mode for 13 clocks
    LCDREFbits.LCDIRE = 1; // Internal Reference Enable
    LCDREFbits.LCDCST = 2; // Contrast is 2/7ths of maximum
    LCDCONbits.LCDEN = 1; // enable LCD module
    
}

void ADC_SD_Init()
{
    unsigned int i;
    unsigned char count;
    
    signed long int maxValue;
    #define EXPECTED_MAX_VALUE  (double)32767 // 0x7FFF is full scale positive
    
    //Disable ADC while (re-)configuring it.
        SD1CON1 = 0x0000;

    //Setup Sigma Delta ADC Module, so that it is ready to perform gain and
    //offset measurements (so we get proper gain and offset calibration values to use later).

        SD1CON1bits.PWRLVL = 1; // High power mode
        SD1CON1bits.SDREFP = 0; // Positive Voltage Reference is SVDD
        SD1CON1bits.SDREFN = 0; // Negative Voltage Reference is SVSS
        SD1CON1bits.VOSCAL = 1; // Internal Offset Measurement Enable
        SD1CON1bits.DITHER = 1; // Low Dither, because using SVDD as reference
        SD1CON1bits.SDGAIN = 0; // Gain is 1:1

        SD1CON2bits.RNDRES = 2; // Round result to 16-bit
        SD1CON2bits.SDWM = 1;   // SDxRESH/SDxRESL updated on every Interrupt
        SD1CON2bits.SDINT = 3;  // Interrupt on every data output
        SD1CON2bits.CHOP = 3;   // Chopping should be enabled always

        SD1CON3bits.SDCH = 1;   // Channel 1 is used for this demo code
        SD1CON3bits.SDCS = 1;   // Clock Source is a 8 MHz FRC
        SD1CON3bits.SDOSR = 0;  // Oversampling Ratio (OSR) is 1024 (best quality)
        SD1CON3bits.SDDIV = 1;  // Input Clock Divider is 2 (SD ADC clock is 4MHz)


    //Enable the ADC module now that it is configured
        SD1CON1bits.SDON = 1;

    //Wait for a minimum of five interrupts to be generated.  Need to throw at least
    //the first four away when using interrupt every period option, since the
    //low pass SINC filter needs to be flushed with new data when we change
    //ADC channel or initialize the ADC.  If the external power supply control
    //loop for the SVDD/SVSS supplies will deviate slightly upon step function
    //increase in loading, it is recommended to wait for more than the minimum
    //samples, before using the data and considering it valid, so as to allow
    //the external power supply to settle.

    for(i = 0; i<6; i++)           // (value must be >= 5)
    {
        IFS6bits.SDA1IF = 0;            //Clear interrupt flag
        while(IFS6bits.SDA1IF == 0);    //Wait until hardware says we have a result ready.
        IFS6bits.SDA1IF = 0;            //Clear interrupt flag
    }
    
        while(IFS6bits.SDA1IF == 0);    //Wait until hardware says we have a result ready.
        IFS6bits.SDA1IF = 0;            //Clear interrupt flag
        offset = (signed short int)SD1RESH;     // cast to accomodate the sign bit extend

    //Switch off offset measurement mode, now that we have the value
        SD1CON1bits.SDON = 0;
        SD1CON1bits.VOSCAL = 0;

    //Now reconfigure ADC so as to measure the SVdd through channel 1,
    //and compare it against the expected result (after offset correction).
    //Use the comparison to compute the optimum gain calibration factor, and
    //save the value, so that it may be used later.

        SD1CON3bits.SDCH = 3;           // point to the SVDD voltage
        SD1CON1bits.SDON = 1;           // SD_ADC back on to make next measurement

    // Wait for a minimum of five interrupts to be generated.
        for(count=0; count<6; count++)
    {
    //Clear interrupt flag.
        IFS6bits.SDA1IF = 0;
    //Wait for the result ready.
        while(IFS6bits.SDA1IF == 0);
    }
    // Save the maximum value to calculate the gain.
        maxValue = (signed short int) SD1RESH;    // must cast as signed as is declared unsigned in header
   
    // Calculate gain.
        SD_gain = EXPECTED_MAX_VALUE/((double)((signed long int)maxValue-offset));

    //Disable ADC while re-configuring it (for normal operation mode, now that
    //we have establish gain/offset calibration values for the ADC).
        SD1CON1bits.SDON = 0;    //Setup Sigma Delta ADC Module for normal reads on CH1
        SD1CON3bits.SDCH = 1;
        SD1CON1bits.SDON = 1;
    
    //Wait for SYNC filter to flush, so the next result the application tries 
    //to read will be valid
        for(count = 0; count < 6; count++)  //throw away first >=4 samples for SINC filter delay
    {
        while(IFS6bits.SDA1IF == 0);    //Wait until hardware says we have a result ready.
        IFS6bits.SDA1IF = 0;            //Clear interrupt flag
    }
    
    //The ADC is now ready, and the first sample of the newly selected channel
    //should be available in SD1RESH.
}    

//------------------------------------------------------------------------------
//Function: signed short int ADC_SD_GetCalibratedResult(BYTE Channel)
//Description: Does what is needed to get an ADC sample from the channel
//specified.  The value that is returned is the raw result generated by
//the hardware, and will therefore contain offset and gain error.
//------------------------------------------------------------------------------
signed short int ADC_SD_GetRawResult()
{
   
    //Wait for a new result
        IFS6bits.SDA1IF = 0;            //Clear interrupt flag
        while(IFS6bits.SDA1IF == 0);    //Wait until hardware says we have a result ready.

         return SD1RESH;
}    

//------------------------------------------------------------------------------
//Function: signed short int ADC_SD_GetCalibratedResult(BYTE Channel)
//Description: Does what is needed to get an ADC sample from the channel
//specified, and then compensate it for offset and gain.  The calibrated
//result is then returned.
//------------------------------------------------------------------------------
signed short int ADC_SD_GetCalibratedResult()
{
    signed long int OffsetCalibratedResult;
    double GainAndOffsetCorrectedResult;
    
    //Get the raw ADC result
        OffsetCalibratedResult = ADC_SD_GetRawResult();
    
    //Correct for offset error measured previously
        OffsetCalibratedResult -= offset;

    //Now compute the gain corrected result.  
        GainAndOffsetCorrectedResult = (double)OffsetCalibratedResult * (double) SD_gain;
    
    //Convert the double into a signed long int.    
        OffsetCalibratedResult = (signed long int)GainAndOffsetCorrectedResult;
    
    //Make sure the result fits in a signed short int.  If not, saturate it so it does.
        if(OffsetCalibratedResult > 32767)
        {
            OffsetCalibratedResult = 32767;
    }    
        else if(OffsetCalibratedResult < -32768)
    {
            OffsetCalibratedResult = -32768;
    }    
        
        
        return (signed short int)OffsetCalibratedResult;
}
VGDS
  • 11
  • 2
  • 1
    Be more explicit. What doesn't work? – drum Oct 23 '21 at 21:03
  • The red lines are just an error in MPLABx. Close MPLABx, clear the cache of MPLABx and then restart the IDE. Or just ignore the red lines... see:https://www.microchip.com/forums/m971980.aspx – Mike Oct 25 '21 at 04:53
  • @Mike Thanks, but the red lines are not the problem. The problem is that nothing is shown on the display although the code ran without an error message. – VGDS Oct 26 '21 at 08:10

0 Answers0