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 + -
显示快捷键?