//-----------------------------------------------------------------------------
// F06x_ADC0_ExternalInput.c
//-----------------------------------------------------------------------------
// Copyright 2005 Silicon Laboratories, Inc.
// http://www.silabs.com
//
// Program Description:
//
// This program measures the voltage on an external ADC input and prints the
// result to a terminal window via the UART.
// 作为电压输入ADC然后在终端上显示。
// The system is clocked using the internal 24.5MHz oscillator. 系统时钟内部晶振24.5
// Results are printed to the UART from a loop with the rate set by a delay
// based on Timer 2. This loop periodically reads the ADC value from a global
// variable, Result.
//
// The ADC makes repeated measurements at a rate determined by SAMPLE_RATE
// using Timer 3. The end of each ADC conversion initiates an interrupt which
// calls an averaging function.
// <INT_DEC> samples are averaged then the Result value updated.
//
// For each power of 4 of <INT_DEC>, you gain 1 bit of effective resolution.
// For example, <INT_DEC> = 256 gain you 4 bits of resolution: 4^4 = 256.
//
// The ADC input multiplexer is set for a single-ended input at AIN2.1.
// The input amplifier is set for unity gain so a voltage range of 0 to Vref
// (2.43V) may be measured. Although voltages up to Vdd may be applied without
// damaging the device, only the range 0 to Vref may be measured by the ADC.
//
// A 100kohm potentiometer may be connected as a voltage divider between
// VREF and AGND as shown below: (minimum value = 12Kohms as the maximum
// recommended current through the Vref is of 200uA @2.4V)
//
// ---------
// |
// 8 o| AGND ----|
// o| VREF ----|<-|
// o| AIN2.1 | |
// o| | |
// o| --------
// o|
// o|
// 1 o|
// |
//----------
//
// How To Test:
//
// 1) Download code to a 'F06x device that is connected to a UART transceiver
// 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 Vref)
// to AIN 2.1, or a potentiometer voltage divider as shown above.
// 5) HyperTerminal will print the voltage measured by the device if
// everything is working properly
//
// FID: 06X000022
// Target: C8051F06x
// Tool chain: Keil C51 7.50 / Keil EVAL C51
// Command Line: None
//
//
// Release 1.0
// -Initial Revision (CG)
// -8-June-06
//
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <c8051F060.h> // SFR declarations
#include <stdio.h>
//-----------------------------------------------------------------------------
// 16-bit SFR Definitions for 'F06x
//-----------------------------------------------------------------------------
//sfr16 ADC2L = 0xbe; // ADC2 data
sfr16 RCAP2 = 0xca; // Timer2 capture/reload
sfr16 RCAP3 = 0xca; // Timer3 capture/reload
sfr16 TMR2 = 0xcc; // Timer2
sfr16 TMR3 = 0xcc; // Timer3
sfr16 ADC2=0xbe;
//-----------------------------------------------------------------------------
// Global Constants
//-----------------------------------------------------------------------------
#define BAUDRATE 9600 // Baud rate of UART in bps
#define SYSCLK 24500000 // System Clock
#define SAMPLE_RATE 50000 // Sample frequency in Hz
#define INT_DEC 256 // Integrate and decimate ratio
#define SAR_CLK 2500000 // Desired SAR clock speed
#define SAMPLE_DELAY 50 // Delay in ms before taking sample
sbit LED = P2^0; // LED='1' means ON
sbit LED1 = P2^1;
sbit SW1 = P3^7; // SW1='0' means switch pressed
//-----------------------------------------------------------------------------
// Function Prototypes
//-----------------------------------------------------------------------------
void OSCILLATOR_Init (void);
void PORT_Init (void);
void UART1_Init (void);
void ADC2_Init (void);
void TIMER3_Init (void);
void TIMER3_ISR (void);
void ADC2_ISR (void);
void Wait_MS (unsigned int ms);
//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
long Result; // ADC0 decimated value
int lchhxy=0;
int lch=0;
//-----------------------------------------------------------------------------
// main() Routine
//-----------------------------------------------------------------------------
void main (void)
{
long measurement=0; // Measured voltage in mV
// long Mu,Md;
WDTCN = 0xde; // Disable watchdog timer
WDTCN = 0xad;
OSCILLATOR_Init (); // Initialize oscillator
PORT_Init (); // Initialize crossbar and GPIO
UART1_Init (); // Initialize UART1
TIMER3_Init (); // Initialize Timer3 to overflow at
// sample rate 用TM3满足采样频率。
ADC2_Init (); // Init ADC
SFRPAGE = ADC2_PAGE;
AD2EN = 1; // Enable ADC
EA = 1; // Enable global interrupts
while (1)
{
EA = 0; // Disable interrupts
// The 10-bit ADC2 value is averaged across INT_DEC measurements.
// The result is then stored in Result, and is right-justified
// The measured voltage applied to AIN 2.1 is then:
//
// Vref (mV)
// measurement (mV) = --------------- * Result (bits)
// (2^10)-1 (bits)
if(lchhxy==1)
{
measurement = Result;
lch=1;
lchhxy=0;
}
EA = 1;
if(lch==1)
{ // Re-enable interrupts
measurement = (measurement*2.43)/(2^11); // 将偏差校正到 0度 0V
measurement = (measurement -0.776)/0.00289; // 2.5mV/摄氏度
/* Mu=measurement/100;
Md= measurement- Mu*100; */
SFRPAGE = UART1_PAGE;
printf("Temperature: %ld C\n",measurement);
SFRPAGE = CONFIG_PAGE;
LED = ~LED; // LED reflects state of switch
lch=0;
}
Wait_MS(SAMPLE_DELAY); // Wait 50 milliseconds before taking
// another sample
}
}
//-----------------------------------------------------------------------------
// Initialization Subroutines
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// OSCILLATOR_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// This function initializes the system clock to use the internal oscillator
// at 24.5 MHz.
//
//-----------------------------------------------------------------------------
void OSCILLATOR_Init (void)
{
char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR page
SFRPAGE = CONFIG_PAGE; // Set SFR page
OSCICN = 0x83; // Set internal oscillator to run
// at its maximum frequency
CLKSEL = 0x00; // Select the internal osc. as