ADC精度测试
define USE_FLOAT 1
define PRINT_STATISTICS 1
define PRINT_SAMPLES 0
define PRINT_VOLTAGES 0
//----------------------------------------------------------------------------- // Includes //-----------------------------------------------------------------------------
include // SFR declarations
include // Standard I/O Library
include
//----------------------------------------------------------------------------- // 16-bit SFR Definitions for 'F35x //-----------------------------------------------------------------------------
sfr16 DP = 0x82; // data pointer sfr16 TMR3RL = 0x92; // Timer3 reload value sfr16 TMR3 = 0x94; // Timer3 counter sfr16 ADC0DEC = 0x9a; sfr16 TMR2RL = 0xca; // Timer2 reload value sfr16 TMR2 = 0xcc; // Timer2 counter sfr16 PCA0CP0 = 0xe9; // PCA0 Module 1 Capture/Compare sfr16 PCA0CP1 = 0xeb; // PCA0 Module 2 Capture/Compare sfr16 PCA0CP2 = 0xed; // PCA0 Module 2 Capture/Compare sfr16 PCA0 = 0xf9; // PCA0 counter
//----------------------------------------------------------------------------- // Global CONSTANTS //-----------------------------------------------------------------------------
define SYSCLK 49000000 // SYSCLK frequency (Hz)
define BAUDRATE 115200 // UART0 Baudrate (bps)
define MDCLK 2457600 // Modulator Clock (Hz)
define OWR 10 // desired Output Word Rate in Hz
define VREF 250L // External VREF (x 10^-2 V)
/*
define VREF 243UL // Internal VREF (x 10^-2 V)
*/
sbit LED0 = P0^6; // LED0='1' means ON sbit LED1 = P0^7; // LED1='1' means ON sbit SW2 = P1^0; // SW2='0' means switch pressed
//----------------------------------------------------------------------------- // Function PROTOTYPES //----------------------------------------------------------------------------- void SYSCLK_Init (void); void PORT_Init (void); void ADC0_Init (void); void IDA0_Init (void); void UART0_Init (void);
//----------------------------------------------------------------------------- // MAIN Routine //----------------------------------------------------------------------------- void main (void) {
volatile long ADC_OutputVal=0; // Concatenated ADC output value long xdata sample_array[64]; unsigned i; long min; long max; long l_temp; long l_average; long l_variance; long l_owr;
// float xdata tf[5]; // float *p=tf; // int c=0; // float d=0;
if (USE_FLOAT == 1)
float temp; float average; float variance; float stdev; float owr;
endif // USE_FLOAT
// disable watchdog timer PCA0MD &= ~0x40; // WDTE = 0 (clear watchdog timer // enable)
SYSCLK_Init(); // Initialize system clock to 49 MHz
PORT_Init(); // Initialize crossbar and GPIO
LED0 = 0; LED1 = 0;
ADC0_Init(); // Initialize ADC0
UART0_Init(); // Initialize UART0
EA = 1; // enable global interrupts
printf("\nMeasurements using the 24-bit ADC in C8051F350\n"); printf("\nCalibrating ...\n");
EIE1 &= ~0x08; // Disable ADC0 interrupts
ADC0MD |= 0x01; // Init Internal Full cal
while (!AD0CALC); // Wait for calibration complete
ADC0MD &= ~0x07; // clear bits (put ADC0 in IDLE // mode)
printf("Calibration complete\n\n");
AD0INT = 0; // clear pending sample indication ADC0MD = 0x83; // Start continuous conversions
while(1) {
// capture 128 samples
printf ("Collecting 64 samples...\n");
LED0 = 1;
for (i = 0; i < 64; i++)
{
while(!AD0INT); // wait till conversion complete
AD0INT = 0; // clear AD0 interrupt flag
// concatenate ADC0 data bytes to form the 24-bit value
ADC_OutputVal = (char)ADC0H;
ADC_OutputVal <<= 16;
ADC_OutputVal += (long)ADC0L + ((long)ADC0M << 8);
sample_array[i] = ADC_OutputVal;
}
LED0 = 0;
// calculate mean, min, and max
if (USE_FLOAT == 1)
average = 0;
endif // USE_FLOAT
l_average = 0L;
min = 0x7fffffffL;
max = 0x80000000L;
for (i = 0; i < 64; i++)
{
ADC_OutputVal = sample_array[i];
l_average = l_average + ADC_OutputVal;
if (ADC_OutputVal < min)
min = ADC_OutputVal;
if (ADC_OutputVal > max)
max = ADC_OutputVal;
if (USE_FLOAT == 1)
average = average + (float) ADC_OutputVal;
endif // USE_FLOAT
}
l_average = l_average / 64;
if (USE_FLOAT == 1)
average = average / 64.0;
endif // USE_FLOAT
// calculate variance
l_variance = 0L;
if (USE_FLOAT == 1)
variance = 0;
endif // USE_FLOAT
for (i = 0; i < 64; i++)
{
ADC_OutputVal = sample_array[i];
l_temp = ADC_OutputVal;
l_temp = l_temp - l_average;
l_temp = l_temp * l_temp;
l_variance = l_variance + l_temp;
if (USE_FLOAT == 1)
temp = (float) ADC_OutputVal;
temp = temp - average;
temp = temp * temp;
variance = variance + temp;
endif // USE_FLOAT
}
l_variance = l_variance / 63; // unbiased variance
l_owr = (long) SYSCLK / (long)(ADC0CLK + 1);
l_owr = (long) l_owr / (long)(ADC0DEC + 1);
l_owr = (long) l_owr / (long)64;
if (USE_FLOAT == 1)
variance = variance / 63; // unbiased variance
stdev = sqrt (variance);
owr = SYSCLK /(ADC0CLK + 1);
owr = owr / (ADC0DEC + 1);
owr = owr / 64;
endif // USE_FLOAT
// print statistics
if (PRINT_STATISTICS == 1)
LED1 = 1;
printf ("SYSCLK = %lu\n", (unsigned long) SYSCLK);
printf ("ADC0CLK = 0x%02x\n", (unsigned) ADC0CLK);
printf ("ADC0DEC = 0x%02x%02x\n", (unsigned) ADC0DECH,
(unsigned) ADC0DECL);
printf ("min = %ld\n", min);
printf ("max = %ld\n", max);
if (USE_FLOAT == 1)
// *p++=average;
// c++;
// printf("c=%d \n",c);
// if(c==5)
// {
// for(c=0;c<5;c++)
// {
// d+=tf[c];
// }
//
// printf("****");
// for(c=0;c<10;c++)
// printf(" \n");
// printf("0V输入:%.8f",d/5.0/8388607*2.5004-0.000689+0.001955);
// for(c=0;c<10;c++)
// printf(" \n");
// printf("****");
// p=tf;
// c=0;
// }
printf ("average = %.6f\n", average);
printf ("real = %.6f\n", average/8388607*2.5004-0.000689+0.001855);
printf ("stdev = %.5f\n", stdev);
printf ("variance = %.5f\n", variance);
printf ("OWR = %.5f Hz\n", owr);
else
printf ("average = %ld\n", l_average);
printf ("variance = %ld\n", l_variance);
printf ("OWR = %ld Hz\n", l_owr);
endif // USE_FLOAT
printf ("\n");
LED1 = 0;
endif // PRINT_STATISTICS
// print samples
if (PRINT_SAMPLES == 1)
for (i = 0; i < 64; i++)
{
ADC_OutputVal = sample_array[i];
printf ("%6ld\n", ADC_OutputVal);
// printf ("0x%06lx\n", ADC_OutputVal);
}
endif // PRINT_SAMPLES
// print voltages
if (PRINT_VOLTAGES == 1)
for (i = 0; i < 64; i++)
{
long Calculated_uV; // Measured voltage in uV
ADC_OutputVal = sample_array[i];
// Caculate measured voltage in uV:
// V (in uV) = ADCcode * VREF * 10 / 2^24
// Note1: Multiplying by 10 because VREF is in 10^-2 V
// Note2: Shifting by 4 before multiplying 10 to prevent overflow
// of unsigned long variable (32 bits)
Calculated_uV = ((((((ADC_OutputVal*2*VREF)/16)*10)/1024)*1000)/1024);
// Output result:
printf("ADC Output Code = %6ld [Calculated voltage = %+07ld uV]\n",
ADC_OutputVal, Calculated_uV);
}
endif // PRINT_VOLTAGES
}// end while(1) }
//----------------------------------------------------------------------------- // SYSCLK_Init //----------------------------------------------------------------------------- // // This routine initializes the system clock to use the internal 24.5MHz // oscillator as its clock source, with x 2 multiply for // 49 MHz operation. Also enables missing clock detector reset. // void SYSCLK_Init (void) { unsigned i;
OSCICN = 0x80; // enable intosc CLKSEL = 0x00; // select intosc as sysclk source
// INTOSC configure
OSCICN = 0x83;
// PLL configure
CLKMUL = 0x00; // Reset Clock Multiplier
CLKMUL &= ~0x03; // select INTOSC / 2 as PLL source
CLKMUL |= 0x80; // Enable 4x Multipler (MULEN = 1)
for (i = 0; i < 125; i++); // Delay for at least 5us
CLKMUL |= 0xC0; // Initialize Multiplier
while (!(CLKMUL & 0x20)); // Poll for Multiply Ready
// SYSCLK configure
VDM0CN = 0x80; // enable VDD monitor RSTSRC = 0x06; // enable missing clock detector // and VDD monitor reset sources CLKSEL = 0x02; // select PLL as clock source }
//----------------------------------------------------------------------------- // PORT_Init //----------------------------------------------------------------------------- // // Configure the Crossbar and GPIO ports. // P0.4 - TX0 (push-pull) // P0.5 - RX0 // P0.6 - LED1 (push-pull) // P0.7 - LED2 (push-pull) // void PORT_Init (void) { XBR0 = 0x01; // UART0 Selected XBR1 = 0x40; // Enable crossbar and weak pull-ups P0MDOUT |= 0xD0; // TX, LEDs = Push-pull }
//----------------------------------------------------------------------------- // ADC0_Init extVREF Bipolar AIN0.1-AIN0.0 //----------------------------------------------------------------------------- // // This function initializes the ADC to measure across AIN0.1 and AIN0.0 // on the Target Board (Differential measurements, Bipolar codes) // void ADC0_Init (void) { unsigned ADC0_decimation;
REF0CN &= ~0x01; // disable internal vref / REF0CN |= 0x01; // (enable if using internal vref) / ADC0CN = 0x10; // Bipolar output codes, GAIN=1
/ ADC0CF = 0x00; // interrupts upon SINC3 filter output // and uses internal VREF / ADC0CF = 0x04; // interrupts upon SINC3 filter output // and uses external VREF // Generate MDCLK for modulator. // Ideally MDCLK = 2.4576 ADC0CLK = (SYSCLK/MDCLK)-1; // Ideally, MDCLK = 2.4576 MHz // ADC0DEC = 0x7FF; // set slowest OWR // program decimation rate for desired OWR ADC0_decimation = (unsigned long) SYSCLK/ (unsigned long) OWR / (unsigned long) (ADC0CLK+1)/(unsigned long)128; ADC0_decimation--; ADC0DEC = ADC0_decimation; /****/ ADC0BUF = 0x00; // Turn off Input Buffers // Select Mux inputs
// ADC0MUX = 0x08; // Input pin selection: // Setup for differential measurements // AIN+ => AIN0.0 // AIN- => AGND // ADC0MUX = 0x00; // Input pin selection: // Setup for differential measurements // AIN+ => AIN0.0 // AIN- => AIN0.0 // ADC0MUX = 0x01; // Input pin selection: // Setup for differential measurements // AIN+ => AIN0.0 // AIN- => AIN0.1 // ADC0MUX = 0x10; // Input pin selection: // Setup for differential measurements // AIN+ => AIN0.1 // AIN- => AIN0.0 ADC0MUX = 0x32; // Input pin selection: // Setup for differential measurements // AIN+ => AIN0.3 // AIN- => AIN0.2 // ADC0MUX = 0x54; // Input pin selection: // Setup for differential measurements // AIN+ => AIN0.5 // AIN- => AIN0.4 // ADC0MUX = 0x76; // Input pin selection: // Setup for differential measurements // AIN+ => AIN0.7 // AIN- => AIN0.6 // ADC0MUX = 0xff; // Input pin selection: // Setup for differential measurements // AIN+ => Temp+ // AIN- => Temp- // ADC0MUX = 0x88; // Input pin selection: // Setup for differential measurements // AIN+ => AGND // AIN- => AGND ADC0MD = 0x80; // Enable the ADC0 (IDLE Mode) }
//-----------------------------------------------------------------------------
// UART0_Init
//-----------------------------------------------------------------------------
//
// Configure the UART0 using Timer1, for
- 分享
- 举报
-
浏览量:269次2019-11-18 11:15:10
-
浏览量:568次2019-04-23 10:15:20
-
浏览量:440次2019-11-23 09:24:28
-
浏览量:1745次2017-12-14 16:59:48
-
浏览量:398次2019-11-20 09:20:56
-
浏览量:459次2019-11-27 09:37:44
-
浏览量:498次2018-04-11 10:20:59
-
浏览量:421次2019-11-22 08:49:13
-
浏览量:412次2019-09-16 14:08:20
-
浏览量:246次2023-10-09 18:56:58
-
浏览量:533次2020-06-29 17:22:21
-
浏览量:353次2020-07-07 12:07:16
-
浏览量:456次2019-11-13 09:22:27
-
浏览量:366次2020-06-18 10:53:37
-
浏览量:222次2023-02-01 11:28:02
-
浏览量:445次2019-11-06 14:27:58
-
浏览量:214次2023-10-09 18:47:09
-
浏览量:288次2019-11-06 09:02:55
-
浏览量:561次2019-10-23 14:55:46
-
广告/SPAM
-
恶意灌水
-
违规内容
-
文不对题
-
重复发帖
我是会员







举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明
可以加点代码说明吗?