📄 f31x_adc0_externalinput.c
字号:
//-----------------------------------------------------------------------------
// F31x_ADC0_ExternalInput.c
//-----------------------------------------------------------------------------
// Copyright 2006 Silicon Laboratories, Inc.
// http://www.silabs.com
//
// Program Description:
// --------------------
//
// This example code takes and averages 2048 analog measurements from input
// P2.5 using ADC0, then prints the results to a terminal window via the UART.
//
// The system is clocked by the internal 24.5MHz oscillator. Timer 2 triggers
// a conversion on ADC0 on each overflow. The completion of this conversion
// in turn triggers an interrupt service routine (ISR). The ISR averages
// 2048 measurements, then prints the value to the terminal via printf before
// starting another average cycle.
//
// The analog multiplexer selects P2.5 as the positive ADC0 input. This
// port is configured as an analog input in the port initialization routine.
// The negative ADC0 input is connected via mux to ground, which provides
// for a single-ended ADC input.
//
// A 100kohm potentiometer may be connected as a voltage divider between
// P0.0 and AGND on the terminal strip as shown below:
//
// ---------
// |
// |
// |
// o| P0.0 ----|
// o| GND ---|<-|
// o| |
// o| P2.5--------|
// |
//----------
// C8051F310-TB
//
// Note that the ADC reference voltage is tied to Vdd, not a precision
// internal reference. This limits the precision of the measurement,
// as Vdd is set by the regulator on the board, not the C8051F310.
//
// Terminal output is done via printf, which directs the characters to
// UART0. A UART initialization routine is therefore necessary.
//
// ADC Settling Time Requirements, Sampling Rate:
// ----------------------------------------------
//
// The total sample time per input is comprised of an input setting time
// (Tsettle), followed by a conversion time (Tconvert):
//
// Tsample = Tsettle + Tconvert
//
// |--------Settling-------|==Conversion==|----Settling--- . . .
// Timer 2 overflow ^
// ADC0 ISR ^
//
// The ADC input voltage must be allowed adequate time to settle before the
// conversion is made. This settling depends on the external source
// impedance, internal mux impedance, and internal capacitance.
// Settling time is given by:
//
// | 2^n |
// Tsettle = ln | --- | * Rtotal * Csample
// | SA |
//
// In this application, assume a 100kohm potentiometer as the voltage divider.
// The expression evaluates to:
//
// | 2^10 |
// Tsettle = ln | ---- | * 105e3 * 5e-12 = 4.4uS
// | 0.25 |
//
// In addition, one must allow at least 1.5uS after changing analog mux
// inputs or PGA settings. The settling time in this example, then, is
// dictated by the large external source resistance.
//
// The conversion is 10 periods of the SAR clock <SAR_CLK>. At 3 MHz,
// this time is 10 * 400nS = 3.3 uS.
//
//
// Tsample, minimum = Tsettle + Tconvert
// = 4.4uS + 3.3uS
// = 7.7 uS
//
// Timer 2 is set to start a conversion every 100uS, which is far longer
// than the minimum required.
//
// F310 Resources:
// ---------------
// Timer1: clocks UART
// Timer2: overflow initiates ADC conversion
//
// How To Test:
// ------------
// 1) Download code to a 'F310 device on a C8051F310-TB development board
// 2) Connect serial cable from the transceiver to a PC
// 3) On the PC, open HyperTerminal (or any other terminal program) and connect
// to the COM port at <BAUDRATE> and 8-N-1
// 4) Connect a variable voltage source (between 0 and VDD)
// to P2.5, or a potentiometer voltage divider as shown above.
// 5) HyperTerminal will print the voltage measured by the device if
// everything is working properly
//
// FID: 31X000011
// Target: C8051F310
// Tool chain: Keil C51 7.50 / Keil EVAL C51
// Command Line: None
//
//
// Release 1.0
// -Initial Revision (clm)
// -24-Jul-06
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include "c8051F310.h" // SFR declarations
#include <stdio.h>
//-----------------------------------------------------------------------------
// 16-bit SFR Definitions for 'F31x
//-----------------------------------------------------------------------------
sfr16 TMR2RL = 0xca; // Timer2 reload value
sfr16 TMR2 = 0xcc; // Timer2 counter
sfr16 ADC0 = 0xbd; // ADC0 result
//-----------------------------------------------------------------------------
// Global CONSTANTS
//-----------------------------------------------------------------------------
#define SYSCLK 24500000 // SYSCLK frequency in Hz
#define BAUDRATE 115200 // Baud rate of UART in bps
sbit LED = P3^3; // LED='1' means ON
//-----------------------------------------------------------------------------
// Function PROTOTYPES
//-----------------------------------------------------------------------------
void SYSCLK_Init (void);
void PORT_Init (void);
void Timer2_Init(void);
void ADC0_Init(void);
void UART0_Init (void);
void ADC_Init()
{
int SARCLK=3000000; // 3 Mhz
// Use AD0BUSY as conversion enable
ADC0CN=0x40; // ADC with normal track mode
//REF0CN=0x0e; // Enable temp sensor and use on chip Vref (VDD)
// REF0CN=0x0A; // Enable temp sensor and use on external Vref
AMX0N=0x1F; // Single-Ended inputs
ADC0CF=(SYSCLK/SARCLK-1)<<3; // Conversion clock setting & results are right-justified
ADC0CF |= 0x00; // right-justify results
EIE1 &= 0xF1; // Disable ADC interrupt & disable win compare interrupts
AD0EN=1; // Enable ADC, ready for data conversion
}
unsigned int ADC_Read_Ch(unsigned char chan_num)
{
unsigned long result;
static int measure = 2048;
static unsigned long accumulator = 0;
unsigned long mV; // measured voltage in mV
AMX0P = chan_num; // Select chan to be read thru the MUX
AD0INT = 0; // Clear conversion complete indicator
AD0BUSY = 1; // Initiate conversion
while (!AD0INT); // Wait for convesion completed.
result = ADC0H; // Stuff converted data
result = (result << 8) | ADC0L;
accumulator += result;
measure--;
if(measure == 0)
{
measure = 2048;
result = accumulator / 2048;
accumulator=0;
// The 10-bit ADC value is averaged across 2048 measurements.
// The measured voltage applied to P1.4 is then:
//
// Vref (mV)
// measurement (mV) = --------------- * result (bits)
// (2^10)-1 (bits)
mV = result * 3250 / 1023;
printf("P3.1 voltage: %ld mV\n",mV);
}
return result;
}
//-----------------------------------------------------------------------------
// MAIN Routine
//-----------------------------------------------------------------------------
void main (void)
{
PCA0MD &= ~0x40; // WDTE = 0 (clear watchdog timer
// enable)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -