📄 ds18b20.c
字号:
/*****************************************************************************
*文件名:DS18B20.C
*日期:11:40 04-5-28
*一次读5个DS18B20
*****************************************************************************/
#include <reg932.h>
#include <intrins.h>
#include "Use.h"
#include "Ver.H"
//---------------------------------
//12MHz 下,_NOP_2uS_()执行时间0.1667us
//---------------------------------
#define NOP_1uS _nop_();_nop_();_nop_();_nop_();_nop_();_nop_()
//**************************************
#define Skip 0xcc //跳过命令
#define Convert 0x44 //转化命令
#define RdDs18b20 0xbe //读温度命令
//*******************************************************************************
#define DQ P0 //P0口用5个DS18B20
//--------------------------------------------
extern void ClrWatchDog(void); //清楚看门狗
extern void CmpTemp(void);
extern void SendTemp(unsigned char Way,float F1);
//----------------------------------
void Delay10us(unsigned char n)
{
while(n--)
{
NOP_1uS;NOP_1uS;NOP_1uS;
NOP_1uS;NOP_1uS;NOP_1uS;
NOP_1uS;
}
}
/*----------------------------------
//功能:总线初始化
//-----------------------------------
*/
bit Init_18B20(void)
{
DQ=0;
Delay10us(50);//延时500us
DQ=0xff;
Delay10us(9);//延时90us
if((DQ & 0x1f) ==0x1f) //0001 1111b=1f
{
return 0; //失败0
}else
{
Delay10us(40);//延时400us
DQ=0xff; //成功!
}
return 1;
}
//------------------------------------------
//数据合并 Buf[0].0,Buf[1].0...=>Dat[0]
//5 个DS18B20合并5个温度
//------------------------------------------
void FormatTemp(unsigned char *pSurce,unsigned char *pTag)
{
code unsigned char CodeMask[]={0x01,0x02,0x04,0x08,0x10}; //对应5个DS18B20的位
unsigned char i,j;
// unsigned char pSurce[8],pTag[Ds18b20k];
for (i=0;i<Ds18b20k;i++)
{
for (j=0;j<8;j++)
{
pTag[i] >>=1;
pTag[i] |=(( pSurce[j] & CodeMask[i])>0? 1:0)*0x80;
}
}
}
//-------------------------------------------
//功能:读取18B20 (5个DS18B20)
//入口 接收数据的地址指针
//------------------------------------
void Read_18B20(unsigned char *p)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ=0;
NOP_1uS;//延时1us
DQ=0xff;
NOP_1uS;NOP_1uS;NOP_1uS;
NOP_1uS;NOP_1uS;NOP_1uS;//延时5us
//----------------------------------
*p++=DQ; //并口读入5个位
//----------------------------------
Delay10us(5);//延时40us
DQ=0xff;
}
}
/*
//------------------------------------
//功能:读取18B20
//------------------------------------
void Read_18B20(unsigned char *p)
{
unsigned char i;
unsigned char temp;
for(i=0;i<8;i++)
{
temp=temp>>1;
DQ=0;
_NOP_2uS_();_NOP_2uS_();_NOP_2uS_();//延时1us
DQ=1;
NOP_2uS;NOP_2uS;//延时5us
if(DQ==0)
{
temp=temp&0x7F;
}else
{
temp=temp|0x80;
}
Delay10us(4);//延时40us
DQ=1;
}
*p=temp;
}
*/
//-----------------------------------
//功能:写18B20
//-----------------------------------
void Write_18B20(unsigned char n)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ=0;
Delay10us(1);//延时13us 左右
DQ= (n&0x01)*0xff;
n=n>>1;
Delay10us(5);//延时50us 以上
DQ=0xff;
}
}
//------------------------------------
//规范化成浮点数
// sssss111;11110000
//------------------------------------
float TempDo(unsigned char H,unsigned char L )
{
union
{
unsigned char Temp[2]; //单字节温度
unsigned int Tt; //2字节温度
}T;
unsigned char i;
float f=0;
char j=1;
code float Code_F[]={0.0625,0.125,0.25,0.5};
T.Temp[0]=H;T.Temp[1]=L;
//-----------------------------------
if (H >0x80) //负温度
{
T.Tt =~T.Tt+1; //取反+1=源吗 +符号S
// T.Temp[0] |=0x80;//加入-符号
j=-1;
}
T.Tt <<= 4; //左移4位
// k=(char)T.Temp[0]; //转换符号书
T.Temp[1]>>=4;
//---------------------------
for (i=0;i<4;i++) //计算小数位
{
f +=(T.Temp[1] & 0x01)*Code_F[i];
T.Temp[1]>>=1;
}
f=(float)((T.Temp[0]+f)*j);
//*********************************
if ( f> 70)
{
f=70; //>70度等于70
}
return f;
}
//----------------------------------
void Delay(unsigned int i)
{
while (i--)
{
ClrWatchDog(); //清楚看门狗
Delay10us(150); //2ms
}
}
//----------------------------------
//操作程序
//----------------------------------
void GetTemp_Read(float *pBuf)
{
unsigned char TempL[8],TempH[8]; //8个位
unsigned char Tep_H[Ds18b20Max];
unsigned char Tep_L[Ds18b20Max];
unsigned char i;
if (Init_18B20()==1) //等待总线初始化完成
{
Write_18B20(Skip);//发送SKIP ROM 指令
Write_18B20(Convert);//发送温度转换指令
Delay(MS*850);//延时1s
if (Init_18B20()==1);//等待总线初始化完成
{
Write_18B20(Skip);//发送SKIP ROM 指令
Write_18B20(RdDs18b20);//发送读取存储器指令
Read_18B20(TempL);//读取温度低字节
Read_18B20(TempH);//读取温度高字节
FormatTemp(TempL,Tep_L);//合并5个温度
FormatTemp(TempH,Tep_H);
for (i=0;i<Ds18b20k;i++)
{
*pBuf++=TempDo(Tep_H[i],Tep_L[i]); //规范浮点数
}
}
}
}
//*****************************************
//数字滤波处理
//*****************************************
void GetTemp (float *pBuf)
{
static unsigned char Number=0;
unsigned char i;
float xdata temper[Ds18b20Max];//!!!!!!!!!!!!!!!!
GetTemp_Read((float *)temper);
if (Number++ >= CiShu)
{ //计算平均值
for (i=0;i<Ds18b20k;i++)
{
pBuf[i]=Temper[i]/CiShu;
Temper[i]=0;
// SendTemp(i,pBuf[i]);
}
CmpTemp(); //比较温度
Number=0;
}
else
{
for (i=0;i<Ds18b20k;i++)
{
Temper[i] +=temper[i];
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -