我在 MPLAB® Starter Kit for Intelligent.Integrated.Analog 上使用 PIC24FJ128GC010 和编译器 XC16。我将读取 16 位 Sigma-Delta ADC 并在 LCD 显示器上显示结果。我在 C 语言中找到了一些用于电路板的示例代码,但它现在不起作用。当我运行代码时,编译器没有出错,但他在每个“LCDPSbits”下划线。和“LCDREFbits”。红色,显示屏上不显示任何内容。这是我最新状态的代码。谁能帮我?
#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;
}