📄 ds18b20.c
字号:
//korfi 2007/09/22
extern int iIOPort00;
extern int *IOPort00;
extern unsigned char SNCode[8]; // DS18B20中唯一的序列号
extern short jTemperture;
extern float fTemperture;
void SetDS18B20High()
{
iIOPort00 |= 0x10;
*IOPort00 = iIOPort00;
}
void SetDS18B20Low()
{
iIOPort00 &= 0xEF;
*IOPort00 = iIOPort00;
}
//=======================================================================
void Delay3uS()
{
unsigned short j;
// op for(j=0;j<70;j++);
for(j=0;j<41;j++);
}
void Delay10uS()
{
unsigned short j;
//op for(j=0;j<260;j++);
for(j=0;j<140;j++);
}
void Delay15uS()
{
unsigned short j;
//op for(j=0;j<390;j++);
for(j=0;j<211;j++);
}
void Delay45uS()
{
unsigned short j;
//op for(j=0;j<1200;j++);
for(j=0;j<640;j++);
}
void Delay580uS()
{
unsigned int j;
//op for(j=0;j<10000;j++);
for(j=0;j<19640;j++);
}
// 耗时:508 + 508 + 10 = 1026uS
int InitDS18B20() //Reset Tx
{
unsigned int i, j;
SetDS18B20Low(); //低电平 Tx产生 "reset pulse"
Delay580uS(); //延时580us "480us(min)--960us(max)"
SetDS18B20High(); //高电平上拉
i=0;
while(1) //等待DS18B20产生 "presence pulse"
{ //60us(min)--240us(max)
j = *IOPort00;
if ((j&0x40)==0) break;
Delay10uS();
if (i++>=30) return 0; //300us内没有出现低电平,则未挂接或DS18B20故障
}
Delay580uS(); //延时580us 等待DS18B20就绪
return 1;
}
// 耗时:63*8 = 504uS
void WriteCommandToDS18B20(unsigned char Cmd ) //命令字放在Byte中
{
int i, Mask;
Mask = 1;
for(i=0;i<8;i++)
{
if(Cmd & Mask)
{
SetDS18B20Low(); //DS18B20=0;
Delay15uS();
SetDS18B20High(); //DS18B20=1;
Delay45uS();
}
else
{
SetDS18B20Low(); //DS18B20=0;
Delay15uS();
Delay45uS();
SetDS18B20High(); //DS18B20=1;
}
Mask <<= 1;
Delay3uS();
}
}
// 耗时:63*8 = 504uS
unsigned char ReadByteFromDS18B20() /*从DS18B20中读一个字节*/
{
int i, j;
unsigned char c;
c=0;
for(i=0;i<8;i++)
{
SetDS18B20Low(); //DS18B20=0;
Delay3uS();
SetDS18B20High(); //DS18B20=1;
Delay15uS();
c >>= 1;
j = *IOPort00;
if ( j&0x40 ) c |= 0x80;
Delay45uS();
}
return c;
}
unsigned int cal_crc(unsigned char *ptr, unsigned char len)
{
unsigned char i;
unsigned int crc=0;
while(len--!=0)
{
for(i=0x80; i!=0; i/=2)
{
if ((crc&0x80)!=0)
{
crc *= 2;
crc ^= 0x131; /* CRC = X^8 + X^5 + X^4 + 1*/
} /* 余式CRC乘以2再求CRC */
else
crc *= 2;
if ( (*ptr&i)!=0 ) crc ^= 0x131; /* 再加上本位的CRC */
}
ptr++;
}
return(crc);
}
/*输入InputData,输出CRC*/
unsigned char CreatCrcValue(unsigned char * p)
{
unsigned char i, j, InputData, CRC;
CRC = 0;
/*对9个字节的数据进行CRC校验,余数应为0*/
for(j=0;j<9;j++)
{
InputData = *(p+j);
for(i=0;i<8;i++)
{
if (((InputData ^ CRC) & 0x01) != 0)
{
/*若输入的BIT数据与CRC的低0位异或为1,则CRC与0x18异或
然后CRC左移。CRC的高8位置1(此位为BIT数据与CRC的低0位异或的1)*/
CRC ^= 0x18;
CRC >>= 1;
CRC |= 0x80;
}
else
CRC >>= 1;
InputData >>= 1;
}
}
return CRC;
}
void ReadSerialNumber() // 读取DS18B20中唯一的序列号
{
int i;
if (!InitDS18B20()) /* No DS18B20 present */
{
jTemperture = -32768; // 0x8000
return;
}
WriteCommandToDS18B20(0x33); /* Read Rom command */
Delay580uS();
for (i=0; i<8; i++)
{
SNCode[i] = ReadByteFromDS18B20();
Delay580uS();
}
SNCode[6] ^= 'H';
SNCode[5] ^= 'J';
SNCode[4] ^= 'Z';
// SNCode[3] ^= 0xFF;
// SNCode[2] ^= 0xFF;
// SNCode[1] ^= 0xFF;
}
void ReadTemperature() /*读温度精度为0.1℃,存放在FTemperature中*/
{
int i;
unsigned char c, CRC, uData1[10];
if (!InitDS18B20()) /* No DS18B20 present */
{
jTemperture = -32768; // 0x8000
return;
}
WriteCommandToDS18B20(0xCC); /* Skip Rom command */
WriteCommandToDS18B20(0x4E); /*write Scratchpad */
WriteCommandToDS18B20(0x4B); /*write TH */
WriteCommandToDS18B20(0x46); /*write TL */
WriteCommandToDS18B20(0x7F); /*write Configuration register */
//InitDS18B20(); /* Reset*/
if (!InitDS18B20())
{
jTemperture = -32768; // 0x8000
return;
}
WriteCommandToDS18B20(0xCC); /* Skip Rom command */
WriteCommandToDS18B20(0x44); /* Convert T command 启动温度变换 */
for (i=0; i<100; i++) Delay580uS(); /*等待温度变换完成*/
c = ReadByteFromDS18B20();
i=0;
while (c!=0xFF)
{
c = ReadByteFromDS18B20();
Delay580uS();
if(i++>=5000) //失败
{
jTemperture = -32768; // 0x8000
return;
}
}
InitDS18B20(); /* Reset */
WriteCommandToDS18B20(0xCC); /* Skip Rom command */
WriteCommandToDS18B20(0xBE); /* Read Scratchpad command 读内存命令 */
/*读取读内存值 9个字节 低位在前, 存放在XmtDat*/
for(i=0;i<9;i++)
uData1[i] = ReadByteFromDS18B20();
uData1[9] = cal_crc(uData1, 8);
/* i = uData1[1];
i <<= 8;
i += uData1[0];
t = i * 0.0625;
*/
CRC = CreatCrcValue(uData1);
if(CRC != 0) //失败
jTemperture = -32768; // 0x8000
else
{
jTemperture = (uData1[1]<<8) + uData1[0];
fTemperture = (float)jTemperture *0.0625;
if(fTemperture > 50.0)
{
//SetAdj3High();
//ReadK2();
ReadK1();
}
else
{
//SetAdj3Low();
ReadK1();
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -