f362dc_adc0_temperaturesensor.c
来自「8051试验程序 基础教材」· C语言 代码 · 共 586 行 · 第 1/2 页
C
586 行
CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 00
} else {
TH1 = (0xFF-(SYSCLK/BAUDRATE/2/48))+1;
CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 10
CKCON |= 0x02;
}
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
SFRPAGE = SFRPAGE_save; // Restore the SFRPAGE
}
//-----------------------------------------------------------------------------
// 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)
{
unsigned char SFRPAGE_save = SFRPAGE; // Save the current SFRPAGE
SFRPAGE = CONFIG_PAGE; // Switch to the necessary SFRPAGE
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
SFRPAGE = SFRPAGE_save; // Restore the SFRPAGE
}
//-----------------------------------------------------------------------------
// 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.ADC0BUSY = 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.ADC0BUSY = 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;
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
unsigned char SFRPAGE_save = SFRPAGE; // Save the current SFRPAGE
SFRPAGE = LEGACY_PAGE; // Switch to the necessary SFRPAGE
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
SFRPAGE = SFRPAGE_save; // Restore the SFRPAGE
}
//-----------------------------------------------------------------------------
// End Of File
//-----------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?