f362dc_adc0_temperaturesensor.c

来自「8051试验程序 基础教材」· C语言 代码 · 共 586 行 · 第 1/2 页

C
586
字号
//-----------------------------------------------------------------------------
// F362DC_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 'F36x
// 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 F362 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:            36X000003
// Target:         ToolStick C8051F362
// Tool chain:     Keil C51 7.50 / Keil EVAL C51
// Command Line:   None
//
//
// Release 1.0
//    -Initial Revision (TP)
//    -29 NOV 2006
//

//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------

#include <ioC8051F362.h>                 // SFR declarations
#include <stdio.h>
#include <stdbool.h>


//-----------------------------------------------------------------------------
// 16-bit SFR Definitions
//-----------------------------------------------------------------------------
__sfr __no_init volatile unsigned short TMR3        @ 0x94;
__sfr __no_init volatile unsigned short ADC0        @ 0xBD;
__sfr __no_init volatile unsigned short TMR2        @ 0xCC;
__sfr __no_init volatile unsigned short TMR2RL      @ 0xCA;


//-----------------------------------------------------------------------------
// 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
#define LEGACY_PAGE     0x00
#define CONFIG_PAGE     0x0F

//-----------------------------------------------------------------------------
// 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 const int __code 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

   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 = ");

      // This method of printing the temperature is an alternative to using
      // printf() and its capabilities

      IE_bit.EA = 0;
      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
      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)
{
   unsigned char SFRPAGE_save = SFRPAGE; // Save the current SFRPAGE

   SFRPAGE = CONFIG_PAGE;              // Switch to the necessary SFRPAGE

   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

   SFRPAGE = SFRPAGE_save;             // Restore the SFRPAGE
}

//-----------------------------------------------------------------------------
// 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)
{
   unsigned char SFRPAGE_save = SFRPAGE; // Save the current SFRPAGE

   SFRPAGE = CONFIG_PAGE;              // Switch to the necessary SFRPAGE

   OSCICN |= 0x03;                     // Configure internal oscillator for
                                       // its maximum frequency
   RSTSRC  = 0x04;                     // Enable missing clock detector

   SFRPAGE = SFRPAGE_save;             // Restore the SFRPAGE
}

//-----------------------------------------------------------------------------
// 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)
{
   unsigned char SFRPAGE_save = SFRPAGE; // Save the current SFRPAGE

   SFRPAGE = CONFIG_PAGE;              // Switch to the necessary SFRPAGE

   ADC0CN = 0x40;                      // ADC0 disabled; LP tracking
                                       // mode; ADC0 conversions are initiated
                                       // on a write to ADBusy
   AMX0P  = 0x1E;                      // Temp sensor selected at + input
   AMX0N  = 0x1F;                      // 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

   SFRPAGE = SFRPAGE_save;             // Restore the SFRPAGE
}

//-----------------------------------------------------------------------------
// UART0_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// Configure the UART0 using Timer1, for <BAUDRATE> and 8-N-1.
//
//-----------------------------------------------------------------------------
void UART0_Init (void)
{
   unsigned char SFRPAGE_save = SFRPAGE; // Save the current SFRPAGE

   SFRPAGE = CONFIG_PAGE;              // Switch to the necessary SFRPAGE

   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
   static volatile int apa;
   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;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?