f330dc_adc0_temperaturesensor.c

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

C
547
字号
   TL1 = TH1;                          // Init Timer1
   TMOD &= ~0xf0;                      // TMOD: timer 1 in 8-bit autoreload
   TMOD |=  0x20;
   TCON_bit.TR1 = 1;                            // START Timer1
   SCON0_bit.TI0 = 1;                            // Indicate TX0 ready
}

//-----------------------------------------------------------------------------
// TIMER2_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   :
//   1)  int counts - number of milliseconds of delay
//                    range is postive range of integer: 0 to 32767
//
// Configure Timer2 to auto-reload at interval specified by <counts> (no
// interrupt generated) using SYSCLK as its time base.
//
//-----------------------------------------------------------------------------
void TIMER2_Init (int counts)
{
   TMR2CN = 0x00;                      // STOP Timer2; Clear TF2H and TF2L;
                                       // disable low-byte interrupt; disable
                                       // split mode; select internal timebase
   CKCON |= 0x10;                      // Timer2 uses SYSCLK as its timebase

   TMR2RL  = -counts;                  // Init reload values
   TMR2    = TMR2RL;                   // Init Timer2 with reload value
   IE_bit.ET2 = 0;                            // Disable Timer2 interrupts
   TMR2CN_bit.TR2 = 1;                            // Start Timer2
}

//-----------------------------------------------------------------------------
// Support Subroutines
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Wait_Soak_Time
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   :
//   1)  unsigned char soak_time - number of seconds of delay
//                    range is postive range of integer: 0 to 255
//
// This routine waits for the number of seconds indicated in the constant
// <soak_time>.
//
//-----------------------------------------------------------------------------
void Wait_Soak_Time (unsigned char soak_time)
{
   unsigned char i;

   for( i = soak_time; i != 0; i--)
   {
      Wait_One_Second();
      Print_String ("Soaking\n");
   }
}

//-----------------------------------------------------------------------------
// Wait_One_Second
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// This routine uses Timer2 to insert a delay of approximately one second.
// Timer 2 overflows <TIMER2_RATE> times per second.
//
//-----------------------------------------------------------------------------
void Wait_One_Second (void)
{
   unsigned int count;
   TMR2CN_bit.TF2H = 0;                           // Clear Timer2 overflow flag
   TMR2CN_bit.TR2 = 1;                            // Start Timer2

   for (count = TIMER2_RATE; count != 0; count--)
   {
      while (!TMR2CN_bit.TF2H);                   // Wait for overflow
      TMR2CN_bit.TF2H = 0;                        // Clear overflow indicator
   }

   TMR2CN_bit.TR2 = 0;                            // Stop Timer2
}

//-----------------------------------------------------------------------------
// Calibrate_TempSensor
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// This routine waits for the device to heat to operating temperature, takes an
// ADC measurement, and calculates a temperature.  It compares this measured
// value to AMBIENT_TEMPERATURE and calculates an offset, which is stored in a
// Flash memory location for later measurements.
//
//-----------------------------------------------------------------------------
void Calibrate_TempSensor (void)
{

   bool EA_state = IE_bit.EA;                  // Preserves EA state
   unsigned long offset_address;       // Used to write calibration
                                       // Value into FLASH memory

   long temp_offset;                   // Stores returned value from ADC

   Wait_Soak_Time (SOAK_TIME);         // Let temperature of device stabilize

   temp_offset= (long) Measure_Temperature ();     // Read oversampled ADC code


   // Now calculate the 0 DEG C offset value using temp_offset, the
   // temp sensor gain, and the ambient temperature.

   temp_offset = temp_offset - ((long) AMBIENT_TEMPERATURE *
                 TEMP_SENSOR_GAIN / VREF * 65536 / 1000);


   offset_address = (long)&TEMP_OFFSET;      // Point to TEMP_OFFSET

   Flash_ByteWrite (&offset_address, temp_offset >> 8);

   offset_address++;                   // Move to low byte of TEMP_OFFSET in
                                       // Flash to store low byte of offset

   Flash_ByteWrite (&offset_address, temp_offset);

   IE_bit.EA = EA_state;                      // Restore interrupt state

}

//-----------------------------------------------------------------------------
// Measure_Temperature
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// This routine averages 16383 ADC samples and returns a 16-bit unsigned
// result.
//
//-----------------------------------------------------------------------------
unsigned int Measure_Temperature (void)
{
   unsigned i;                         // Sample counter
   unsigned long accumulator = 0L;     // Where the ADC samples are integrated

   unsigned int currval;

   ADC0CN_bit.AD0INT = 0;                         // Clear end-of-conversion indicator
   ADC0CN_bit.AD0BUSY = 1;                        // Initiate conversion

   // read the ADC value and add to running total
   i = 0;
   do
   {
      while (!ADC0CN_bit.AD0INT);      // Wait for conversion to complete
      ADC0CN_bit.AD0INT = 0;           // Clear end-of-conversion indicator

      currval = ADC0;                  // Store latest ADC conversion
      ADC0CN_bit.AD0BUSY = 1;          // Initiate conversion
      accumulator += currval;          // Accumulate
      i++;                             // Update counter
   } while (i != 16383);

   return (unsigned int) (accumulator >> 8);  // Obtain a 16-bit result
                                              // (14 + 10 = 24 - 8 = 16) bits
}

//-----------------------------------------------------------------------------
// Get_Temperature
//-----------------------------------------------------------------------------
//
// Return Value : int - returns the temperature in hundredths of degrees
// Parameters   : None
//
// This routine averages 16383 ADC samples and returns a 16-bit unsigned
// result.
//
//-----------------------------------------------------------------------------
int Get_Temperature (void)
{
   unsigned int ADC_code;
   unsigned long result;

   ADC_code = Measure_Temperature ();

   result = ADC_code - TEMP_OFFSET;

   //result = result * (VREF / 65536) * (1000 / TEMP_SENSOR_GAIN) * ( 100 );
   // the equation below is re-arranged for fixed-point math.
   result = result * (long) VREF / 256 * 1000 / TEMP_SENSOR_GAIN * 100 / 256;
   return (int) result;
}

//-----------------------------------------------------------------------------
// Support Functions
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Print_String
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   :
//         1) char pstring[] - null terminated character string
//
// Prints the strings stored in pstring to the UART.
// This function is used instead of printf() because printf() consumes
// a considerable amount of code space.
//
//-----------------------------------------------------------------------------

void Print_String (char pstring[])
{
   unsigned char i = 0;
   while (pstring[i])
   {
      putchar(pstring[i++]);
   }
}

//-----------------------------------------------------------------------------
// Flash_ByteWrite
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   :
//         1) unsigned int addr - location in Flash to write the byte
//         2) char byte - data to store to Flash
//
// Stores <byte> in address pointed to by <addr>.
// This function was obtained from Application Note 201.
//
//-----------------------------------------------------------------------------

void Flash_ByteWrite (unsigned long * addr, char byte)
{
   bool EA_SAVE = IE_bit.EA;                   // Preserve EA
   unsigned long * pwrite;           // FLASH write pointer

   IE_bit.EA = 0;                             // Disable interrupts

   VDM0CN = 0x80;                      // Enable VDD monitor

   RSTSRC = 0x02;                      // Enable VDD monitor as a reset source

   pwrite = addr;       // Point to Flash location

   FLKEY  = 0xA5;                      // Key Sequence 1
   FLKEY  = 0xF1;                      // Key Sequence 2
   PSCTL |= 0x01;                      // PSWE = 1

   VDM0CN = 0x80;                      // Enable VDD monitor

   RSTSRC = 0x02;                      // Enable VDD monitor as a reset source


   *pwrite = byte;                     // Write the byte


   PSCTL &= ~0x01;                     // PSWE = 0; disable writes

   IE_bit.EA = EA_SAVE;                       // Restore interrupts
}

//-----------------------------------------------------------------------------
// End Of File
//-----------------------------------------------------------------------------

⌨️ 快捷键说明

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