分三个文件,
ds18b20.c
/*
****************************************************************************************************
* SSAC_A1
* Main Controller Board
* File name : DS18B20.c
* Version : 1.0
* Use for : Detect temperature
* Summary : The C code for DS18B20
* Author : Shensong (E_mail:webmaster@shensong.com / QQ:2939603 / Mob:13016461980)
* Date : 2005-05-22
****************************************************************************************************
*/
#include "DS18B20.h"
#include "DS18B20_ports.h"
////////// Bit operation macro
#define Set_Bit(Address,Bit) ((Address) |= (1 << Bit))
#define Clear_Bit(Address,Bit) ((Address) &= ~(1 << Bit))
#define Test_Bit(Address,Bit) ((Address) & (1 << Bit))
//--------------------------------------------------------------------------------------------------
////////// Make a Master reset to DS18B20, and check the result
// Input:
// None
// Return:
// 0: There is no DS18B20 or master reset operation false
// 1: There is and has be 1-Wire reset
static unsigned char DS18B20_Master_Reset (void)
{
unsigned char Value;
Value = 0;
DS18B20_Tx_Obtain (); // Set to low for 720us to reset slave device
Soft_Delay_us (480); // 720us
DS18B20_Tx_Release (); // Release the 1-Wire Bus
Soft_Delay_us (70); // 68us. Check the reset result, slave will set the 1-Wire Bus to low
Value = DS18B20_Rx ();
Soft_Delay_us (410); // 480us. Wait for cycle end
if (Value) return 0;
return 1;
}
//--------------------------------------------------------------------------------------------------
////////// Write bit to DS18B20
// Input:
// Value: bit value will be writed
// Return:
// None
static void DS18B20_Write_Bit (unsigned char Value)
{
if (Value == 0) // Master Write "0" SLOT
{
DS18B20_Tx_Obtain ();
Soft_Delay_us (65); // 70us
DS18B20_Tx_Release ();
Soft_Delay_us (10); // No this line
}
else // Master Write "1" SLOT
{
DS18B20_Tx_Obtain ();
Soft_Delay_us (10); // 7us
DS18B20_Tx_Release ();
Soft_Delay_us (65); // 63us
}
//Soft_Delay_us (10); // Wait for 1-wire restore
}
//--------------------------------------------------------------------------------------------------
////////// Read bit from DS18B20
// Input:
// None
// Return:
// The bit value that has be read out
static unsigned char DS18B20_Read_Bit (void)
{
unsigned char Value;
DS18B20_Tx_Obtain (); // Start a read time slot
Soft_Delay_us (5);
DS18B20_Tx_Release (); // Release and sample 1-Wire Bus
Soft_Delay_us (5); // 13us
Value = DS18B20_Rx (); // Wait for read cycle end
Soft_Delay_us (55); // 52us
//Soft_Delay_us (10); // Wait for 1-wire restore
if (! Value) return 0;
return 1;
}
//--------------------------------------------------------------------------------------------------
////////// Write byte to DS18B20
// Input:
// The byte will be writed
// Return:
// None
static void DS18B20_Write_Byte (unsigned char Value)
{
unsigned char i;
for (i = 0; i < 8; i++)
{
DS18B20_Write_Bit ( Test_Bit (Value, i) );
}
}
//--------------------------------------------------------------------------------------------------
////////// Read byte from DS18B20
// Input:
//
// Return:
// The byte that has be read out
static unsigned char DS18B20_Read_Byte (void)
{
unsigned char i;
unsigned char Value;
Value = 0;
for (i = 0; i < 8; i++)
{
if ( DS18B20_Read_Bit () ) Set_Bit (Value, i);
}
return Value;
}
//--------------------------------------------------------------------------------------------------
////////// Multi Write byte to DS18B20
// Input:
// * Value: The source data
// Number: number of the data
// Return:
// None
static void DS18B20_Multi_Write_Byte (unsigned char * Value, unsigned char Number)
{
unsigned char i;
if (Number == 0) return;
for (i = 0; i < Number; i++)
{
DS18B20_Write_Byte ( * (Value + i) );
}
}
//--------------------------------------------------------------------------------------------------
////////// Multi Read byte from DS18B20
// Input:
// * Value: The source data
// Number: number of the data
// Return:
// None
static void DS18B20_Multi_Read_Byte (unsigned char * Value, unsigned char Number)
{
unsigned char i;
if (Number == 0) return;
for (i = 0; i < Number; i++)
{
* (Value + i) = DS18B20_Read_Byte ();
}
}
//--------------------------------------------------------------------------------------------------
////////// 8-bit CRC check, X8+X5+X4+1, to check the data get from DS18B20
// Input:
// Crc_Org: Oringal crc value
// * Value: the data need do a crc check
// Length: The length of data
// Return:
// Return = crc result
static unsigned char DS18B20_Crc_Check (unsigned char Crc_Org, unsigned char * Value, unsigned char Length)
{
unsigned char i;
while (Length--)
{
for (i = 0x01; i != 0; i <<= 1)
{
if ( (Crc_Org & 0x01) != 0) // LSB of crcorg
{
Crc_Org >>= 1;
Crc_Org ^= 0x8C;
}
else
{
Crc_Org >>= 1;
}
if ( ((* Value) & i) != 0)
{
Crc_Org ^= 0x8C;
}
}
Value ++;
}
return Crc_Org;
}
//--------------------------------------------------------------------------------------------------
////////// Laser ROM check
// Input:
// * UID: Laser rom data to check
// Return:
// 0: Opt. false
// 1: Opt. OK
static unsigned char DS18B20_UID_Check (unsigned char * UID)
{
if ( * (UID + 0) != 0x28 ) return 0; // DS18B20's family code is 0x28. To avoid always 0 error
if ( DS18B20_Crc_Check (0x00, UID, 7) != * (UID + 7) ) return 0; // CRC check error;
return 1;
}
//--------------------------------------------------------------------------------------------------
////////// Scratchpad check
// Input:
// * SCT: scratchpad
// Return:
// 0: Opt. false
// 1: Opt. OK
static unsigned char DS18B20_SCT_Check (unsigned char * SCT)
{
if ( ((* (SCT + 4)) & 0x9F) != 0x1F) return 0; // To avoid always 0 error
if ( (DS18B20_Crc_Check (0x00, SCT, 8)) != (* (SCT + 8)) ) return 0; // Crc check error
return 1;
}
//--------------------------------------------------------------------------------------------------
////////// Temperature format transfer
// Input:
//
// * sct: The data need to transfer. 8 bytes
// * result: 3 bytes, is insignificant byte, integer byte, low bytes
// Return:
// None
static void DS18B20_Temperature_Format_Transfer (unsigned char * sct, unsigned char * result)
{
unsigned char res_t; // Resolution
unsigned int low_t; // Dept. Dot. use
res_t = * (sct + 4) & 0x60; // Get resolution from scratchpad data
if ( Test_Bit (* (sct + 1), 7) )
{
* (result + 0) = 0xFF; // Insignificant, 0x00 is +, 0xFF is -
}
else
{
* (result + 0) = 0x00;
}
switch (res_t)
{
case 0x00: // for 9-bit resolution
* (result + 1) = * (sct + 0) >> 1; // Dept. Int.
* (result + 2) = (* (sct + 0) & 0x01) * 50; // Dept. Dot.
break;
case 0x20: // for 10-bit resolution
* (result + 1) = ( (* (sct + 0) >> 2) | (((* (sct + 1)) << 6) & 0x7F) ); // Dept. Int.
* (result + 2) = (* (sct + 0) & 0x03) * 25; // Dept. Dot.
break;
case 0x40: // for 11-bit resolution
* (result + 1) = ( (* (sct + 0) >> 3) | (((* (sct + 1)) << 5) & 0x7F) ); // Dept. Int.
low_t = (unsigned int)(* (sct + 0) & 0x07) * 125; // Dept. Dot.
low_t /= 10;
* (result + 2) = (unsigned char)low_t;
break;
case 0x60: // for 12-bit resolution
* (result + 1) = ( (* (sct + 0) >> 4) | (((* (sct + 1)) << 4) & 0x7F) ); // Dept. Int.
low_t = (unsigned int)(* (sct + 0) & 0x0F) * 625; // Dept. Dot.
low_t /= 100;
* (result + 2) = (unsigned char)low_t;
break;
} // end switch (res_t)
}
//--------------------------------------------------------------------------------------------------
////////// Read the value of temperature from DS18B20. Match passed
// Input:
//
// * Value: will storage temperature.
// * (Value + 0): = 0x00 is above 0, = 0xFF is lower 0
// * (Value + 1): Int. of temperature value
// * (Value + 2): dot. of temperature value, 0x00 to 0x63 (0.00 to 0.99)
// Return:
// 0: Opt. false
// 1: Opt. OK
unsigned char DS18B20_Single_Read_Temperature (unsigned char * Value)
{
unsigned char cpu_sr;
unsigned char sct[9]; // For temp storage scratchpad data
Enter_Critical ();
// Start convert cycle
if (DS18B20_Master_Reset () != 1) // Master reset
{
Exit_Critical ();
return 0;
}
DS18B20_Write_Byte (0xCC); // Skip ROM command
DS18B20_Write_Byte (0x44); // Convert temperature command
Exit_Critical ();
Soft_Delay_ms (751); // Wait for convert complete
Enter_Critical ();
// Cycle end
// Start read SCT cycle
if (DS18B20_Master_Reset () != 1) // Master reset
{
Exit_Critical ();
return 0;
}
DS18B20_Write_Byte (0xCC); // Skip ROM command
DS18B20_Write_Byte (0xBE); // Read SCT
DS18B20_Multi_Read_Byte (sct, 9); // Read scratchpad data, 8 Bytes + 1 Byte CRC
// Cycle end
if (DS18B20_SCT_Check (sct) != 1) // Check scratchpad with CRC and CONFIG register
{
Exit_Critical ();
return 0;
}
DS18B20_Temperature_Format_Transfer (sct, Value);
Exit_Critical ();
return 1;
}
//--------------------------------------------------------------------------------------------------
////////// Read the Laser ROM from from DS18B20 // Notice: Only for single device on 1-Wire Bus
// Input:
// * Value: the point for UID data storage. LSB first, MSB last
// Return:
// 0: Opt. false
// 1: Opt. OK
__monitor unsigned char DS18B20_Single_Read_ROM (unsigned char * Value)
{
unsigned char i;
unsigned char rom_temp[8];
if (DS18B20_Master_Reset () != 1) // Master reset and check, error to return 0
{
return 0;
}
DS18B20_Write_Byte (0x33); // 0x33 is Read ROM command
DS18B20_Multi_Read_Byte (rom_temp, 8);
if ( DS18B20_UID_Check (rom_temp) != 1)
{
return 0;
}
for (i = 0; i < 8; i++)
{
* (Value + i) = rom_temp[i]; // CRC OK, Write back result
}
return 1;
}
//--------------------------------------------------------------------------------------------------
////////// Only convert temperature without delay. Single
// Input:
// None
// Return:
// 0: Opt. false
// 1: Opt. OK
unsigned char DS18B20_Single_Only_Convert_Temperature (void)
{
unsigned char cpu_sr;
Enter_Critical ();
// Start convert cycle
if (DS18B20_Master_Reset () != 1) // Master reset
{
Exit_Critical ();
return 0;
}
DS18B20_Write_Byte (0xCC); // Skip ROM command
DS18B20_Write_Byte (0x44); // Convert temperature command
Exit_Critical ();
return 1;
}
//--------------------------------------------------------------------------------------------------
////////// Only read SCT data from DS18B20. Single
// Input:
//
// * Value: will storage temperature.
// * (Value + 0): = 0x00 is above 0, = 0xFF is lower 0
// * (Value + 1): Int. of temperature value
// * (Value + 2): dot. of temperature value, 0x00 to 0x63 (0.00 to 0.99)
// Return:
// 0: Opt. false
// 1: Opt. OK
unsigned char DS18B20_Single_Only_Read_Temperature (unsigned char * Value)
{
unsigned char cpu_sr;
unsigned char sct[9]; // For temp storage scratchpad data
Enter_Critical ();
// Start read SCT cycle
if (DS18B20_Master_Reset () != 1) // Master reset
{
Exit_Critical ();
return 0;
}
DS18B20_Write_Byte (0xCC); // Skip ROM command
DS18B20_Write_Byte (0xBE); // Read SCT
DS18B20_Multi_Read_Byte (sct, 9); // Read scratchpad data, 8 Bytes + 1 Byte CRC
// Cycle end
if (DS18B20_SCT_Check (sct) != 1) // Check scratchpad with CRC and CONFIG register
{
Exit_Critical ();
return 0;
}
DS18B20_Temperature_Format_Transfer (sct, Value);
Exit_Critical ();
return 1;
}
//--------------------------------------------------------------------------------------------------
////////// 以指定的ROM去读温度
// Input:
//
// * UID: ROM (8 bytes)
// * Value: will storage temperature.
// * (Value + 0): = 0x00 is above 0, = 0xFF is lower 0
// * (Value + 1): Int. of temperature value
// * (Value + 2): dot. of temperature value, 0x00 to 0x63 (0.00 to 0.99)
// Return:
// 0: Opt. false
// 1: Opt. OK
unsigned char DS18B20_UID_Read_Temperature (unsigned char * Value, unsigned char * UID)
{
unsigned char cpu_sr;
unsigned char sct[9]; // For temp storage scratchpad data
Enter_Critical ();
if (DS18B20_UID_Check (UID) != 1)
{
Exit_Critical ();
return 0;
}
// Start convert cycle
if (DS18B20_Master_Reset () != 1) // Master reset
{
Exit_Critical ();
return 0;
}
DS18B20_Write_Byte (0x55); // Match ROM command
DS18B20_Multi_Write_Byte (UID, 8);
DS18B20_Write_Byte (0x44); // Convert temperature command
Exit_Critical ();
Soft_Delay_ms (751); // Wait for convert complete
Enter_Critical ();
// Cycle end
// Start read SCT cycle
if (DS18B20_Master_Reset () != 1) // Master reset
{
Exit_Critical ();
return 0;
}
DS18B20_Write_Byte (0x55); // Skip ROM command
DS18B20_Multi_Write_Byte (UID, 8);
DS18B20_Write_Byte (0xBE); // Read SCT
DS18B20_Multi_Read_Byte (sct, 9); // Read scratchpad data, 8 Bytes + 1 Byte CRC
// Cycle end
if (DS18B20_SCT_Check (sct) != 1) // Check scratchpad with CRC and CONFIG register
{
Exit_Critical ();
return 0;
}
DS18B20_Temperature_Format_Transfer (sct, Value);
Exit_Critical ();
return 1;
}
//--------------------------------------------------------------------------------------------------
ds18b20.h
/*
****************************************************************************************************
* SSAC_A1
* Main Controller Board
* File name : ds18b20.h
* Version : 1.0
* Use for : To detect temperature
* Summary : The include file
* Author : Shensong (E_mail:webmaster@shensong.com / QQ:2939603 / Mob:13016461980)
* Date : 2005-05-21
****************************************************************************************************
*/
#ifndef __DS18B20_H
#define __DS18B20_H
////////// Read the Laser ROM from from DS18b20 // Notice: Only for single device on 1-Wire Bus
// Input:
// * Value: the point for UID data storage
// Return:
// 0: Opt. false
// 1: Opt. OK
__monitor extern unsigned char DS18B20_Single_Read_ROM (unsigned char * Value);
//--------------------------------------------------------------------------------------------------
////////// Read the value of temperature from DS18b20
// Input:
// // * UID: which device with the UID will be read out
// * Value: will storage temperature.
// * (Value + 0): = 0x00 is above 0, = 0xFF is lower 0
// * (Value + 1): Int. of temperature value
// * (Value + 2): dot. of temperature value, 0x00 to 0x63 (0.00 to 0.99)
// Return:
// 0: Opt. false
// 1: Opt. OK
extern unsigned char DS18B20_Single_Read_Temperature (unsigned char * Value);
//--------------------------------------------------------------------------------------------------
////////// Only convert temperature without delay. Single
// Input:
// None
// Return:
// 0: Opt. false
// 1: Opt. OK
extern unsigned char DS18B20_Single_Only_Convert_Temperature (void);
//--------------------------------------------------------------------------------------------------
////////// Only read SCT data from DS18B20. Single
// Input:
//
// * Value: will storage temperature.
// * (Value + 0): = 0x00 is above 0, = 0xFF is lower 0
// * (Value + 1): Int. of temperature value
// * (Value + 2): dot. of temperature value, 0x00 to 0x63 (0.00 to 0.99)
// Return:
// 0: Opt. false
// 1: Opt. OK
extern unsigned char DS18B20_Single_Only_Read_Temperature (unsigned char * Value);
//--------------------------------------------------------------------------------------------------
////////// 以指定的ROM去读温度
// Input:
//
// * UID: ROM (8 bytes)
// * Value: will storage temperature.
// * (Value + 0): = 0x00 is above 0, = 0xFF is lower 0
// * (Value + 1): Int. of temperature value
// * (Value + 2): dot. of temperature value, 0x00 to 0x63 (0.00 to 0.99)
// Return:
// 0: Opt. false
// 1: Opt. OK
extern unsigned char DS18B20_UID_Read_Temperature (unsigned char * Value, unsigned char * UID);
#endif /* __DS18B20_H */
ds18b20_ports.h
/*
****************************************************************************************************
* SSAC_A1
* Main Controller Board
* File name : ds18b20_ports.h
* Version : 1.0
* Use for : To detect temperature
* Summary : The include file for ports
* Author : Shensong (E_mail:webmaster@shensong.com / QQ:2939603 / Mob:13016461980)
* Date : 2005-05-25
****************************************************************************************************
*/
#ifndef __DS18B20_PORTS_H
#define __DS18B20_PORTS_H
#define MCU_XTAL 11.0592 // The unit is MHz, for main MCU
#define MCU_TYPE ATmega128
#define COMPLIER_TYPE IAR
#if (MCU_TYPE == ATmega128) && (COMPLIER_TYPE == IAR)
#include <iom128.h> /* Only for "SREG" */
#include <ina90.h> /* Only for "__disable_interrupt() */
#endif /* (MCU_TYPE == ATmega128) && (COMPLIER_TYPE == IAR) */
/* The realization: program critical area ----------------------------------------------------*/
#if (MCU_TYPE == ATmega128) && (COMPLIER_TYPE == IAR)
#define Enter_Critical() cpu_sr = SREG; __disable_interrupt();
#define Exit_Critical() if (cpu_sr & 0x80) __enable_interrupt();
#endif /* (MCU_TYPE == ATmega128) && (COMPLIER_TYPE == IAR) */
/**************************************************************************************************/
/* The realization: Software delay -------------------------------------------------------------*/
#if (MCU_TYPE == ATmega128) && (COMPLIER_TYPE == IAR)
#define Soft_Delay_us(x) __delay_cycles (x * MCU_XTAL)
#define Soft_Delay_ms(x) __delay_cycles (x * MCU_XTAL * 1000)
#define Soft_Delay_s(x) __delay_cycles (x * MCU_XTAL * 1000000)
#endif /* (MCU_TYPE == ATmega128) && (COMPLIER_TYPE == IAR) */
/**************************************************************************************************/
#define DS18B20_Tx_Release() DDRB_DDB7 = 0
#define DS18B20_Tx_Obtain() DDRB_DDB7 = 1
#define DS18B20_Rx() PINE_PINE7
#endif /* __DS18B20_PORTS_H */