2008-06-30 11:18
/********************************************************
* DS18B20溫度傳感器 *
* C51 *
* yajou 2008-06-28 無CRC *
********************************************************/
#include "reg51.h"
#include "intrins.h"
#include "DS18B20.h"
/********************************************************
* us延時程序 *
********************************************************/
void Delayus(uchar us)
{
while(us--); //12M,壹次6us,加進入退出14us(8M晶振,壹次9us)
}
/********************************************************
* DS18B20初始化 *
********************************************************/
bit Ds18b20_Init(void) //存在返0,否則返1
{
bit temp = 1;
uchar outtime = ReDetectTime; //超時時間
while(outtime-- && temp)
{
Delayus(10); //(250)1514us時間可以減小嗎
ReleaseDQ();
Delay2us();
PullDownDQ();
Delayus(100); //614us(480-960)
ReleaseDQ();
Delayus(10); //73us(>60)
temp = dq;
Delayus(70); //us
}
return temp;
}
/********************************************************
* 寫bit2DS18B20 *
********************************************************/
void Ds18b20_WriteBit(bit bitdata)
{
if(bitdata)
{
PullDownDQ();
Delay2us(); //2us(>1us)
ReleaseDQ(); //(上述1-15)
Delayus(12); //86us(45- x,總時間>60)
}else
{
PullDownDQ();
Delayus(12); //86us(60-120)
}
ReleaseDQ();
Delay2us(); //2us(>1us)
}
/********************************************************
* 寫Byte DS18B20 *
********************************************************/
void Ds18b20_WriteByte(uchar chrdata)
{
uchar ii;
for(ii = 0; ii < 8; ii++)
{
Ds18b20_WriteBit(chrdata & 0x01);
chrdata >>= 1;
}
}
/********************************************************
* 寫 DS18B20 *
********************************************************/
//void Ds18b20_Write(uchar *p_readdata, uchar bytes)
//{
// while(bytes--)
// {
// Ds18b20_WriteByte(*p_readdata);
// p_readdata++;
// }
//}
/********************************************************
* 讀bit From DS18B20 *
********************************************************/
bit Ds18b20_ReadBit(void)
{
bit bitdata;
PullDownDQ();
Delay2us(); //2us( >1us)
ReleaseDQ();
Delay8us(); //8us( <15us)
bitdata = dq;
Delayus(7); //86us(上述總時間要>60us)
return bitdata;
}
/********************************************************
* 讀Byte DS18B20 *
********************************************************/
uchar Ds18b20_ReadByte(void)
{
uchar ii,chardata;
for(ii = 0; ii < 8; ii++)
{
chardata >>= 1;
if(Ds18b20_ReadBit()) chardata |= 0x80;
}
return chardata;
}
/********************************************************
* 讀 DS18B20 ROM *
********************************************************/
bit Ds18b20_ReadRom(uchar *p_readdata) //成功返0,失敗返1
{
uchar ii = 8;
if(Ds18b20_Init()) return 1;
Ds18b20_WriteByte(ReadROM);
while(ii--)
{
*p_readdata = Ds18b20_ReadByte();
p_readdata++;
}
return 0;
}
/********************************************************
* 讀 DS18B20 EE *
********************************************************/
bit Ds18b20_ReadEE(uchar *p_readdata) //成功返0,失敗返1
{
uchar ii = 2;
if(Ds18b20_Init()) return 1;
Ds18b20_WriteByte(SkipROM);
Ds18b20_WriteByte(ReadScr);
while(ii--)
{
*p_readdata = Ds18b20_ReadByte();
p_readdata++;
}
return 0;
}
/********************************************************
* 溫度采集計算 *
********************************************************/
bit TempCal(float *p_wendu) //成功返0,失敗返1 (溫度範圍-55 --- +128)
{
uchar temp[9],ii;
uint tmp;
float tmpwendu;
TR1 = 0;
TR0 = 0;
//讀暫存器和CRC值-----------------------
if(Ds18b20_ReadEE(temp))
{
TR1 = 1;
TR0 = 1;
return 1;
}
//-------------------------------------
//CRC校驗------------------------------
//
//此處應加入CRC校驗等
//
//
//-------------------------------------
//使溫度值寫入相應的wendu[i]數組中-----
for(ii = i; ii > 0; ii--)
{
p_wendu++;
}
i++;
if(i > 4) i = 0;
//-------------------------------------
//溫度正負數處理-----------------------
//
//-------------------------------------
//溫度計算-----------------------------
tmp = temp[1]; //
tmp <<= 8; //
tmp |= temp[0]; //組成溫度的兩字節合並
tmpwendu = tmp;
*p_wendu = tmpwendu / 16;
//-------------------------------------
//開始溫度轉換-------------------------
if(Ds18b20_Init())
{
TR1 = 1;
TR0 = 1;
return 1;
}
Ds18b20_WriteByte(SkipROM);
Ds18b20_WriteByte(Convert);
ReleaseDQ(); //寄生電源時要拉高DQ
//------------------------------------
TR1 = 1;
TR0 = 1;
return 0;
}
//////////DS18B20.h/////////////////////////
/********************************************************
* I/O口定義 *
********************************************************/
sbit dq = P1^3;
sbit dv = P1^4; //DS18B20強上拉電源
/********************************************************
* 命令字定義 *
********************************************************/
#define uchar unsigned char
#define uint unsigned int
#define ReleaseDQ() dq = 1; //上拉/釋放總線
#define PullDownDQ() dq = 0; //下拉總線
#define Delay2us() _nop_();_nop_(); //延時2us,每nop 1us
#define Delay8us() _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
//設置重復檢測次次數,超出次數則超時
#define ReDetectTime 20
//ds18b20命令
#define SkipROM 0xCC
#define MatchROM 0x55
#define ReadROM 0x33
#define SearchROM 0xF0
#define AlarmSearch 0xEC
#define Convert 0x44
#define WriteScr 0x4E
#define ReadScr 0xBE
#define CopyScr 0x48
#define RecallEE 0xB8
#define ReadPower 0xB4
/********************************************************
* 函數 *
********************************************************/
void Delayus(uchar us);
//void Dog(void);
bit Ds18b20_Init(void); //DS18B20初始化,存在返0,否則返1
void Ds18b20_WriteBit(bit bitdata); //寫bit2DS18B20
void Ds18b20_WriteByte(uchar chrdata); //寫Byte DS18B20
void Ds18b20_Write(uchar *p_readdata, uchar bytes); //寫 DS18B20
bit Ds18b20_ReadBit(void); //讀bit From DS18B20
uchar Ds18b20_ReadByte(void); //讀Byte DS18B20
bit Ds18b20_ReadRom(uchar *p_readdata); //讀 DS18B20 ROM:成功返0,失敗返1
bit Ds18b20_ReadEE(uchar *p_readdata); //讀 DS18B20 EE :成功返0,失敗返1
bit TempCal(float *p_wendu); //成功返0,失敗返1 (溫度範圍-55 --- +128