f330dc_adc0_temperaturesensor.c
来自「8051试验程序 基础教材」· C语言 代码 · 共 547 行 · 第 1/2 页
C
547 行
//-----------------------------------------------------------------------------
// F330DC_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 'F33x
// 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 F330 Daughter Card
// 3) Connect to the ToolStick using ToolStick Terminal using the settings
// defined by <BAUD_RATE>
// 4) Check that the printed temperature is close to the ambient temperature
//
// FID: 33X000032
// Target: ToolStick C8051F330
// Tool chain: Keil C51 7.50 / Keil EVAL C51
// Command Line: None
//
//
// Release 1.0
// -Initial Revision (PD/GV/GP)
// -06 AUG 2006
//
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <ioC8051F330.h> // SFR declarations
#include <stdio.h>
#include <stdbool.h>
//-----------------------------------------------------------------------------
// 16-bit SFR Definitions
//-----------------------------------------------------------------------------
__sfr __no_init volatile unsigned short ADC0 @ 0xBD;
__sfr __no_init volatile unsigned short TMR2RL @ 0xCA;
__sfr __no_init volatile unsigned short TMR2 @ 0xCC;
//-----------------------------------------------------------------------------
// 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 2860 // Temp Sensor Gain in (uV / degC)
// Value obtained from datasheet
#define VREF 2430 // 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 Print_String (char pstring[]);
void Flash_ByteWrite (unsigned long * addr, char byte);
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);
// 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)
{
unsigned int temperature; // Stores last measurement
// Disable Watchdog timer
PCA0MD &= ~0x40; // WDTE = 0 (clear watchdog timer
// enable)
PORT_Init (); // Initialize Port I/O
OSCILLATOR_Init (); // Initialize Oscillator
ADC0_Init (); // Init ADC0
TIMER2_Init (SYSCLK/TIMER2_RATE); // Init Timer 2
UART0_Init ();
ADC0CN_bit.AD0EN = 1; // Enable ADC0
//Print_String ("Before CAL \n");
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");
}
//Print_String ("After CAL \n");
while (1)
{
temperature = Get_Temperature ();
Print_String ("Temperature = ");
// This method of printing the temperature is an alternative to using
// printf() and its capabilities
IE_bit.EA = 0;
putchar ((temperature / 10000) + 0x30); // Tens digit
putchar (((temperature / 1000) % 10) + 0x30); // Ones digit
putchar ('.');
putchar (((temperature / 100) % 10) + 0x30); // Tenths digit
// putchar ((temperature % 10) + 0x30); // Hundredths digit
IE_bit.EA = 1;
Print_String (" degrees C\n");
}
}
//-----------------------------------------------------------------------------
// Initialization Subroutines
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// PORT_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// P0.4 digital push-pull UART TX
// P0.5 digital open-drain UART RX
//
//-----------------------------------------------------------------------------
void PORT_Init (void)
{
P0SKIP |= 0x01; // Skip P0.0 for external VREF
P0MDIN |= 0x01; // Configure P0.0 as analog input.
P0MDOUT |= 0x10; // enable UTX as push-pull output
XBR0 = 0x01; // Enable UART on P0.4(TX) and P0.5(RX)
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 |= 0x03; // Configure internal oscillator for
// its maximum frequency
RSTSRC = 0x04; // Enable missing clock detector
}
//-----------------------------------------------------------------------------
// 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 = 0x40; // ADC0 disabled; LP tracking
// mode; ADC0 conversions are initiated
// on a write to ADBusy
AMX0P = 0x10; // Temp sensor selected at + input
AMX0N = 0x11; // Single-ended mode
ADC0CF = (SYSCLK/3000000) << 3; // ADC conversion clock <= 3MHz
ADC0CF &= ~0x04; // Make ADC0 right-justified
REF0CN = 0x0e; // enable temp sensor, VREF = VDD, bias
// generator is on.
EIE1 &= ~0x08; // 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;
} else if (SYSCLK/BAUDRATE/2/256 < 12) {
TH1 = (0xFF-(SYSCLK/BAUDRATE/2/12))+1;
CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 00
} else {
TH1 = (0xFF-(SYSCLK/BAUDRATE/2/48))+1;
CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 10
CKCON |= 0x02;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?