📄 ds18b20.c
字号:
*PB >>= 1;
if (DATA & 0X80) *PA |= 0X80;
else *PA &= 0X7F;
if (DATA & 0X01) *PB |= 0X80;
else *PB &= 0X7F;
}
//****************************************************************************
//模块名:CRC_Verify
//编写者:liukang
//描述: CRC校验子程序。
//功能:
//版本: 1.0
//修改: 2006年05月12日
//****************************************************************************
const unsigned char CRC_H[16] =
{0x00,0x9d,0x23,0xbe,0x46,0xdb,0x65,0xf8,0x8c,0x11,0xaf,0x32,0xca,0x57,0xe9,0x74};
const unsigned char CRC_L[16] =
{0x00,0x5e,0xbc,0xe2,0x61,0x3f,0xdd,0x83,0xc2,0x9c,0x7e,0x20,0xa3,0xfd,0x1f,0x41};
unsigned char CRC_Verify(unsigned char * buf,unsigned char length)
{
unsigned char crc = 0x00;
do
{
crc ^= *buf;
crc = CRC_H[crc >> 4] ^ CRC_L[crc & 0x0f];
buf++;
}
while(--length);
return(crc);
}
//****************************************************************************
//模块名:Search_ROM
//编写者:liukang
//描述: 搜索ds18b20的地址子程序。
//功能:
//版本: 1.0
//修改: 2006年05月12日
//****************************************************************************
void Search_ROM (void)
{
unsigned char A[8],B[8]; //A[8]为已知ID中最大的ID值,B[8]节点表
unsigned char POINT0,POINT; //POINT0指向上次检索的最后一个节点位置;
//POINT指向当前节点位置;
unsigned char I,J,K; //I,J为循环计数器;K为检索失败次数
unsigned char DATA,CRC;
unsigned char *PA,*PB;
PA = &A[0];
PB = &B[0];
J = 0xFF;
FLAG |= FLAG_TEMP_OK; //预设传感器正常
I = 5; //
while ((I != 0) && ~(FLAG & FLAG_TEMP_RET))
{
Rst_DS18B20(); //传感器复位,复位成功或5次复位失败跳出循环
I--;
}
if (FLAG && FLAG_TEMP_RET)
{ //复位成功,开始搜索ds18b20的地址
for (I = 0 ; I <8 ; I++)
{
A[I] = 0; //已知ID中最大的ID值"0"
B[I] = 0; //所有节点都未处理
}
POINT0 = 63;
POINT = 0XFF;
K = 0;
for (J = 0 ; (J<5 && K<5 && POINT != 0) ; J++)
{
Rst_DS18B20(); //传感器复位
Write_BUS_Byte (0XF0); //写搜索ID命令
POINT = 0;
FLAG &= ~FLAG_TEMP_OVER;
for (I = 0 ; ((I < 64) && ~(FLAG & FLAG_TEMP_OVER)) ; I++)
{
Right_Move_Temp(PA,PB); //循环右移
DATA = Read_BUS_2bit(); //读ds18b20两位
switch (DATA &= 0XC0)
{
case 0: //读数为“0”,此位为一节点
{
if (B[0] & 0X80)
{ //本节点已处理
DATA = 0XFF;
A[7] |= 0X80; //地址表写"1"
}
else
{ //本节点未处理
if (I == POINT0)
{ //当前节点是最后的未处理节点
DATA = 0XFF;
A[7] |= 0X80; //地址表写"1"
B[0] |= 0X80; //节点表写"1"
}
else
{
A[7] &= ~0X80; //地址表写"0"
POINT = I; //设置节点指针
}
}
DATA = Write_BUS_bit (DATA); //选择方向
}
break;
case 0X80:
{
DATA = 0X00;
DATA = Write_BUS_bit (DATA); //写"0"
A[7] &= ~0X80;
// B[0] &= ~0X80;
}
break;
case 0X40:
{
DATA = 0X0F;
DATA = Write_BUS_bit (DATA); //写"1"
A[7] |= 0X80;
// B[0] &= ~0X80;
}
break;
case 0XC0:
{
FLAG |= FLAG_TEMP_OVER;
}
break;
default:
break;
}
} //I循环结束
if(!(FLAG & FLAG_TEMP_OVER))
{
CRC = CRC_Verify(PA,7);
if (CRC == A[7])
{
for (I=0; I<8; I++) ID[J][I] = A[I];
POINT0 = POINT;
K = 0;
}
else
{
J--;
K++;
}
}
} //J循环结束
TEMP_NUMBER = J;
}
else
{ //复位失败,置失败标志
FLAG &= FLAG_TEMP_OK;
}
}
//****************************************************************************
//模块名:Read_Temp
//编写者:liukang
//描述: 读温度子程序。
//功能:
//版本: 1.0
//修改: 2006年05月12日
//****************************************************************************
void Read_Temp (void)
{
unsigned char I,J,DATA,CRC;
unsigned char ROM[9];
unsigned char *PA;
Rst_DS18B20(); //温度传感器复位
if ((TEMP_NUMBER > 0) && (FLAG && FLAG_TEMP_RET))
{ //温度传感器数量>0并且复位正常
Write_BUS_Byte (0xcc); //写"跳过"命令
Write_BUS_Byte (0x44); //写"读温度"命令
DATA = 0;
I = 0XFF;
while ((DATA != 0XFF) && (I>0))
{ //循环等待温度转换结束
DATA = Read_BUS_Byte();
I--;
}
for (I=0; I<TEMP_NUMBER; I++)
{
PA = ROM;
Rst_DS18B20();
Write_BUS_Byte (0x55); //写"匹配温度传感器"命令
for (J=0; J<8; J++) //写温度传感器地址
{
Write_BUS_Byte (ID[I][J]);
}
Write_BUS_Byte (0xbe); //写"读存储器"命令
for (J=0; J<9; J++)
{
ROM[J] = Read_BUS_Byte();
}
CRC = CRC_Verify(PA,8);
if (CRC == ROM[8])
{
PA =(unsigned char*)&TEMP[I];
*PA = ROM[0];
*(PA+1) = ROM[1];
}
} //I循环结束
}
}
//****************************************************************************
//模块名:Temp
//编写者:liukang
//描述: 温度子程序。
//功能:
//版本: 1.0
//修改: 2006年05月12日
//****************************************************************************
void Temp (void)
{
Rst_DS18B20 ();
Search_ROM ();
Read_Temp();
_NOP();
}
//****************************************************************************
//模块名:Delay
//编写者:liukang
//描述: 延时子程序。
//功能:
//版本: 1.0
//修改: 2006年05月12日
//****************************************************************************
void Delay(unsigned int x)
{
while(x !=0)x--;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -