//-----------------------------------------------------------------------------
// F35x_ADC0_Buffered.c
//-----------------------------------------------------------------------------
// Copyright 2004 Silicon Laboratories, Inc.
//
// AUTH: BD / PC / BW
// LMOD: BW 15 JUL 2004
// DATE: 06 APR 2004
//
// This program demonstrates taking measurements using the 24-bit ADC on the
// C8051F350/51 devices.
//
// Input pin configuration shown in ADC0_Init().
//
// For a Noise measurement, connect AIN0 and AIN1 to AGND at the terminal
// block. Set "USE_FLOAT" to '1', "PRINT_STATISTICS" to '1',
// "PRINT_SAMPLES" to '0', and "PRINT_VOLTAGES" to '0'.
//
// This software configures the ADC to use an external VREF. Therefore,
// on the 'F350 target board, J13 and J14 should have their shorting blocks
// installed.
//
// The standard deviation (Sigma) of a sample set is equivalent to the
// effective RMS noise of the conversion system. "Sigma", when converted
// to Volts, is equivalent to the input-referred noise floor of the
// sampling system.
//
// Typical values of Sigma from the C8051F350 rev B target board with
// AIN0 and AIN1 grounded at the terminal block are around 9 to 11 LSBs
// in bipolar mode. For a DC measurement, this is equivalent to a Signal-
// to-Noise ratio of about 117dB, or about 20 bits of effective dynamic
// range.
//
// 117dB = 20 log10 ( 11 / 2^23)
// 20 bits = 117dB / 6dB/bit
//
// Another parameter of note for integrating converters is the number of
// Noise-Free bits. For a Gaussian-distributed noise floor, this number
// can be obtained by multiplying Sigma by 6, evaluating the number of
// bits required to contain the result, and subtracting this number of
// bits from the 24 available bits, as follows:
//
// 10 LSBs * 6 = 60 LSBs, which can be contained in 6 bits. Noise-free
// resolution is 24bits - 6 bits = 18 bits.
//
// Refer to 'F350 datasheet tables "ADC0 Electrical Characteristics" and
// "Absolute Maximum Ratings" for the MIN/MAX voltage range on input pins.
//
// If using the eval version of the Keil compiler, set "USE_FLOAT" to '0'
// and calculate the standard deviation by taking the square root
// of "variance".
//
// Target: C8051F35x
//
// Tool chain: KEIL C51
//
// v1.0 PC 26 MAY 2004
// Initial Revision (Adapted from 'F350 Temp Sensor Demo)
//
// set USE_FLOAT to '0' to use EVAL version of Keil compiler
#define USE_FLOAT 1
#define PRINT_STATISTICS 1
#define PRINT_SAMPLES 0
#define PRINT_VOLTAGES 0
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <c8051f350.h> // SFR declarations
#include <stdio.h> // Standard I/O Library
#include <math.h>
//-----------------------------------------------------------------------------
// 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[128];
unsigned i;
long min;
long max;
long l_temp;
long l_average;
long l_variance;
long l_owr;
#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 128 samples...\n");
LED0 = 1;
for (i = 0; i < 128; 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 < 128; 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 / 128;
#if (USE_FLOAT == 1)
average = average / 128;
#endif // USE_FLOAT
// calculate variance
l_variance = 0L;
#if (USE_FLOAT == 1)
variance = 0;
#endif // USE_FLOAT
评论0