📄 18b20.c
字号:
// 程序名称:18B20温度检测子程序
// 说明:4Wire接4个18B20探头,包含CRC校验,输出温度数值为两位,精度1度.错误输出为0度
// 作者:徐征宇
// E-mail:bd7bq@126.com
unsigned char code CrcTable [256]={
0,94, 188,226,97,63,221,131,194,156,126,32,163,253,31,65,
157,195,33,127,252,162,64,30,95,1,227,189,62,96,130,220,
35,125,159,193,66,28,254,160,225,191,93,3,128,222,60,98,
190,224,2,92,223,129,99,61,124,34,192,158,29,67,161,255,
70,24,250,164,39,121,155,197,132,218,56,102,229,187,89,7,
219,133, 103,57,186,228,6,88,25,71,165,251,120,38,196,154,
101,59, 217,135,4,90,184,230,167,249,27,69,198,152,122,36,
248,166, 68,26,153,199,37,123,58,100,134,216,91,5,231,185,
140,210, 48,110,237,179,81,15,78,16,242,172,47,113,147,205,
17,79,173,243,112,46,204,146,211,141,111,49,178,236,14,80,
175,241, 19,77,206,144,114,44,109,51,209,143,12,82,176,238,
50,108,142,208,83,13,239,177,240,174,76,18,145,207,45,115,
202,148, 118,40,171,245,23,73,8,86,180,234,105,55,213, 139,
87,9,235,181,54,104,138,212,149,203,41,119,244,170,72,22,
233,183,85,11,136,214,52,106,43,117,151,201,74,20,246,168,
116,42,200,150,21,75,169,247,182,232,10,84,215,137,107,53};
void delay_us (unsigned int us) //一般延时
{
unsigned int s;
for(s=0;s<us;s++);
for(s=0;s<us;s++);
}
bit Read_bit(unsigned char p)
{
unsigned char i;
switch(p) {
case 0: B20_1=0; B20_1=1; i=B20_1; break;
case 1: B20_2=0; B20_2=1; i=B20_2; break;
case 2: B20_3=0; B20_3=1; i=B20_3; break;
case 3: B20_4=0; B20_4=1; i=B20_4; break;
}
_nop_();
_nop_();
return i;
}
unsigned char ReadOneChar(unsigned char p) //读一个字节
{
unsigned char i=0;
unsigned char dat = 0;
for (i=0;i<8;i++)
{
if(Read_bit(p)) dat|=0x01<<i;
delay_us(6);
}
return(dat);
}
void Write_bit(unsigned char bitval)
{
P2=P2&0xc3;
if(bitval==1) P2=P2|0x3c;
delay_us(5);
P2|=0x3c;
}
void WriteOneChar(unsigned char val) //写一个字节
{
unsigned char i;
unsigned char temp;
for (i=0; i<8; i++)
{
temp=val>>i;
temp&=0x01;
Write_bit(temp);
}
delay_us(5);
}
unsigned char Init_DS18B20() //初始化函数
{
unsigned char x;
P2&=0xc3;
delay_us(35);
P2|=0x3c;
delay_us(4);
x=P2;
x&=0x3c;
x>>=2;
delay_us(30);
return x;
}
void Get_temperatuer() //错误的温度返回值为0xff度
{
unsigned char i,j,temp_buff[9],crc_data=0;
unsigned int t;
i=Init_DS18B20();
if(i!=0) //出错
{
if(i&0x08!=0x08) temperatuer_val[3]=0xff;
if(i&0x04!=0x04) temperatuer_val[2]=0xff;
if(i&0x02!=0x02) temperatuer_val[1]=0xff;
if(i&0x01!=0x01) temperatuer_val[0]=0xff;
}
WriteOneChar(0xcc); //skip rom
WriteOneChar(0x44); //Temperature convert
delay_us(5); //Must delay at least 750mS
if(Init_DS18B20()!=0)
{
if(i&0x08!=0x08) temperatuer_val[3]=0xff;
if(i&0x04!=0x04) temperatuer_val[2]=0xff;
if(i&0x02!=0x02) temperatuer_val[1]=0xff;
if(i&0x01!=0x01) temperatuer_val[0]=0xff;
}
else for(i=0;i<4;i++) temperatuer_val[i]=0x00;
WriteOneChar(0xcc); //skip rom
WriteOneChar(0xbe); //read Temperature
for(j=0;j<4;j++)
{
for(i=0;i<9;i++) temp_buff[i] = ReadOneChar(j);
for(i=0;i<9;i++) crc_data = CrcTable[crc_data^temp_buff[i]]; //查表校验
if (crc_data==0) { //校验正确
t=temp_buff[1];
t<<=8;
t=t|temp_buff[0];
t /= 16;
if(t>99) t=99; //超过99度的只显示99度
if(temperatuer_val[j]!=0xff) temperatuer_val[j]=t;
else temperatuer_val[j]=0;
if(temperatuer_val[j]==85) //测试,防止未连接18B20显示默认的85度
{
switch(j)
{
case 0: B20_1=0; if(B20_1) temperatuer_val[0]=0; break;
case 1: B20_2=0; if(B20_2) temperatuer_val[1]=0; break;
case 2: B20_3=0; if(B20_3) temperatuer_val[2]=0; break;
case 3: B20_4=0; if(B20_4) temperatuer_val[3]=0; break;
}
}
}
else
{ //18B20出错
temperatuer_val[j]=0;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -