f530dc_adc0_temperaturesensor.c
来自「8051试验程序 基础教材」· C语言 代码 · 共 565 行 · 第 1/2 页
C
565 行
//-----------------------------------------------------------------------------
// F530DC_ADC0_TemperatureSensor.c
//-----------------------------------------------------------------------------
// Copyright 2006 Silicon Laboratories, Inc.
// http://www.silabs.com
//
// Program Description:
//
// This program is used to measure the temperature sensor on an 'F53x
// device. It uses 1-point calibration and stores the offset value
// in Flash memory. The program outputs the temperature with accuracy to
// 100ths of a degree Celsius using the UART.
//
//
// How To Test:
//
// 1) Change the #define AMBIENT_TEMPERATURE to accurately reflect the
// the temperarture of the testing environment
// 2) Compile and download the code to a ToolStick LIN Daughter Card
// 3) Connect to the ToolStick using ToolStick Terminal using the settings
// defined by <BAUD_RATE>
// 4) Confirm that the printed temperature is close to the ambient temperature
//
//
// FID: 52X000006
// Target: C8051F530 (Toolstick LIN DC)
// Tool chain: Keil C51 7.50 / Keil EVAL C51
// Command Line: None
//
// Release 1.0
// -Initial Revision (GP)
// -04 OCT 2006
//
//-----------------------------------------------------------------------------
// Global Defines
//-----------------------------------------------------------------------------
// The UART signals TX and RX are assigned to port pins through the device's
// crossbar. The behavior of the crossbar with respect to the UART pins is
// different between C8051F52x-53x Revision A devices and C8051F52x-53x
// Revision B and later devices. Revision A devices assign TX to P0.3 and
// RX to P0.4. Revision B and later devices assign TX to P0.4 and RX to P0.5.
// See the C8051F52x-F53x datasheet for more details.
// Change the revision below to match the revision of the device.
#define REVISION 'A' // Revision of the 'F53x Device (A or B)
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <ioC8051F530.h> // SFR declarations
#include <stdio.h>
#include <stdbool.h>
//-----------------------------------------------------------------------------
// 16-bit SFR Definitions
//-----------------------------------------------------------------------------
__sfr __no_init volatile unsigned short TMR2RL @ 0xCA;
__sfr __no_init volatile unsigned short TMR2 @ 0xCC;
__sfr __no_init volatile unsigned short ADC0 @ 0xBD;
//-----------------------------------------------------------------------------
// Global CONSTANTS
//-----------------------------------------------------------------------------
#define SYSCLK 24500000 // SYSCLK frequency in Hz
#define BAUDRATE 115200 // Baud rate of UART in bps
#define TIMER2_RATE 1000 // Timer 2 overflow rate in Hz
//-----------------------------------------------------------------------------
// Temperature Sensor Calibration Parameters
//-----------------------------------------------------------------------------
#define AMBIENT_TEMPERATURE 25 // Ambient Calibration Temperature
// (degC)
#define TEMP_SENSOR_GAIN 2700 // Temp Sensor Gain in (uV / degC)
#define VREF 2250 // ADC Voltage Reference (mV)
#define SOAK_TIME 5 // Soak Time in Seconds
//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
// TEMP_OFFSET allocates two bytes of code memory space in FLASH
// that will be used to store the calibrated temperature value
unsigned int TEMP_OFFSET = 0xFFFF;
//-----------------------------------------------------------------------------
// Function Prototypes
//-----------------------------------------------------------------------------
void OSCILLATOR_Init (void);
void ADC0_Init (void);
void UART0_Init (void);
void PORT_Init (void);
void TIMER2_Init (int);
void Wait_Soak_Time (unsigned char soak_time);
void Wait_One_Second (void);
int Get_Temperature (void);
void Calibrate_TempSensor (void);
unsigned int Measure_Temperature (void);
void Print_String (char pstring[]);
void Flash_ByteWrite (unsigned long* addr, char byte);
// ISRs defined: None.
//-----------------------------------------------------------------------------
// PUTCHAR Routine
//-----------------------------------------------------------------------------
int putchar(int ch)
{
if (ch == '\n') {
while (!SCON0_bit.TI0);
SCON0_bit.TI0 = 0;
SBUF0 = 0x0d; // output CR
}
while (!SCON0_bit.TI0);
SCON0_bit.TI0 = 0;
return (SBUF0 = ch);
}
//-----------------------------------------------------------------------------
// main Routine
//-----------------------------------------------------------------------------
void main (void)
{
int temperature; // Stores last measurement
PCA0MD &= ~0x40; // Disable the watchdog timer
PORT_Init (); // Initialize Port I/O
OSCILLATOR_Init (); // Initialize Oscillator
ADC0_Init (); // Init ADC0
TIMER2_Init (SYSCLK/TIMER2_RATE); // Init Timer 2
UART0_Init (); // Initialize UART0
ADC0CN_bit.AD0EN = 1; // Enable ADC0
putchar ('\f'); // Clear screen
if (TEMP_OFFSET == 0xFFFF) // True if first-time to execute
{
Print_String ("Calibrating...\n");
Calibrate_TempSensor (); // Execute calibration sequence
}
else {
Print_String ("Calibration previously completed\n");
}
while (1)
{
temperature = Get_Temperature ();
Print_String ("Temperature = ");
putchar ((temperature / 1000) + 0x30); // Tens digit
putchar (((temperature / 100) % 10) + 0x30); // Ones digit
putchar ('.');
putchar (((temperature / 10) % 10) + 0x30); // Tenths digit
putchar ((temperature % 10) + 0x30); // Hundredths digit
Print_String (" degrees C\n");
}
}
//-----------------------------------------------------------------------------
// Initialization Subroutines
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// PORT_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// Initializes the port pins
//
// P0.3 digital push-pull UART TX (Rev A)
// P0.4 digital open-drain UART RX (Rev A)
//
// P0.4 digital push-pull UART TX (Rev B)
// P0.5 digital open-drain UART RX (Rev B)
//
//-----------------------------------------------------------------------------
void PORT_Init (void)
{
#if REVISION == 'A'
P0MDOUT |= 0x08; // Enable UTX as push-pull output
#else
P0MDOUT |= 0x10; // Enable UTX as push-pull output
#endif
XBR0 = 0x01; // Enable UART
XBR1 = 0x40; // Enable crossbar and weak pull-ups
}
//-----------------------------------------------------------------------------
// OSCILLATOR_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// This routine initializes the system clock to use the internal 24.5MHz
// oscillator as its clock source. Also enables missing clock detector reset.
//
//-----------------------------------------------------------------------------
void OSCILLATOR_Init (void)
{
OSCICN |= 0x07; // Configure internal oscillator for
// its maximum frequency
RSTSRC = 0x06; // Enable missing clock detector
// Enable VREGOUT monitor
}
//-----------------------------------------------------------------------------
// ADC0_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// Configure ADC0 to use ADBUSY as conversion source, and to sense the output
// of the temp sensor. Disables ADC end of conversion interrupt. Leaves ADC
// disabled.
//
//-----------------------------------------------------------------------------
void ADC0_Init (void)
{
ADC0CN = 0x00; // ADC0 disabled; Burst mode disabled;
// ADC0 conversions are initiated on a
// write to ADBusy;
// Right-justified output
ADC0MX = 0x18; // Temperature sensor selected as input
ADC0CF = (SYSCLK/3000000) << 3; // ADC conversion clock <= 3MHz
ADC0CF &= ~0x07; // Clear bits 2:0; 1 conversion per
// trigger; disable attenuation
REF0CN = 0x1E; // Enable temp sensor, VREF = VDD, bias
// generator is on. Output is 2.25V
EIE1 &= ~0x02; // Disable ADC0 EOC interrupt
}
//-----------------------------------------------------------------------------
// UART0_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// Configure the UART0 using Timer1, for <BAUDRATE> and 8-N-1.
//
//-----------------------------------------------------------------------------
void UART0_Init (void)
{
SCON0 = 0x10; // SCON0: 8-bit variable bit rate
// level of STOP bit is ignored
// RX enabled
// ninth bits are zeros
// clear RI0 and TI0 bits
if (SYSCLK/BAUDRATE/2/256 < 1) {
TH1 = (0xFF-(SYSCLK/BAUDRATE/2))+1;
CKCON &= ~0x0B; // T1M = 1; SCA1:0 = xx
CKCON |= 0x08;
} else if (SYSCLK/BAUDRATE/2/256 < 4) {
TH1 = (0xFF-(SYSCLK/BAUDRATE/2/4))+1;
CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 01
CKCON |= 0x09;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?