📄 18b20.c
字号:
#include "18B20.h"
//*******
//延时2us
//入口:无
//出口:无
//*******
void WAIT02(void)
{
asm NOP;
asm NOP;
asm NOP;
asm NOP;
}
//**********
//1820初始化
//一次操作的开始
//入口:无
//出口:无
//*******
void init_ds18b20(void)
{
dout_ds18b20=1;
WAIT05();
WAIT05();
dout_ds18b20=0;
WAIT600();
dout_ds18b20=1;
WAIT600();
}
//********
//将设置的参数调出
//配置18B20
//转换位数:9位,转换时间:93.75ms
Byte config_ds18b20(void)
{
Byte i,flag=0;
dout_ds18b20_ddr=1;
din_ds18b20_ddr=0;
init_ds18b20();
Wr1820(SKIPROMT);
Wr1820(RECALLEE);
for(i=0;i<3;i++)
{
if(num_ds1820 < B20_Temp_num)
{
num_ds1820=search_ds18b20_rom();
}
else
{
flag=1;
break;
}
}
return flag;
}
//********
//全部启动转换
//并将温度(temper[])的初始值附值为0x9999
//故障:将该传感器的温度的值设为0x9999,以示错误
//入口:无
//出口:无
//*******
void convt_ds18b20(void)
{
Byte i;
init_ds18b20();
Wr1820(SKIPROMT); //skip ROM 跳出ROM
Wr1820(CONVERTT); //convert T 温度转换
dout_ds18b20=1;
for(i=0;i<B20_Temp_num;i++)
{
temperature[i]=0x99; //103 centigrage
}
}
//*******
//读取一个传感器的温度
//将值传递到温度数组(temper[])中
//入口:第几个18b20
//出口:该传感器的温度存于temper[温度传感器编号][低位0]
// 和temper[温度传感器编号][高位1],
//*******
Byte rd_ds18b20(Byte m1820)
{
Byte i,j,flag=0,num;
if(num_ds1820>0)
{
for(j=0;j<3;j++)
{
init_ds18b20();
if(num_ds1820==1)
{
Wr1820(SKIPROMT);
}
else
{
Wr1820(MATCHROMT); // 匹配ROM
for(i=0;i<8;i++) //将ROM号发出
Wr1820(romno[m1820][i]);
}
Wr1820(RDSCRATCHT); //read scratchpad指令
RDTXT(); //读寄存器数据9个字节
if(CRCCheck8()==scrdata[8])
{
flag=1;
if(B20_Temp_num==1) //only one temperature sensor
{
num=0;
}
else //more than one temperature sensor
{
if((scrdata[2]-1)<B20_Temp_num)//防止未写号的温度传感器的值覆盖其他参数
{
num=scrdata[2]-1;
}
else
num=0;
}
temperature[num]=(scrdata[1]<<4)+(scrdata[0]>>4);//取出整数部分
//考虑到负温度,于是取40摄氏度的偏移量,确保全部是正数
if((temperature[num]&0x80)==0x80) //负温度
temperature[num]=40-((temperature[num]^0xff)+1);
else //正温度
temperature[num]=40+temperature[num];
break;
}
}
}
return flag;
}
//*************
//写1820一个字节
//入口:写入值
//出口:无
//*******
void Wr1820(Byte wr1820)
{
Byte i;
int_disable();
for(i=0;i<8;i++)
{
WrOneBit(wr1820 & 0x01);
wr1820=wr1820>>1;
}
int_enable();
}
//**********
//读寄存器数据9个字节,放入scrdata[]中
//入口:无
//出口:无
//************
void RDTXT(void)
{
Byte i,j;
Byte WDbuff;
for(i=0;i<9;i++)
{
WDbuff=0;
for(j=0;j<8;j++)
{
int_disable();
WDbuff=WDbuff>>1;
dout_ds18b20=0; //拉低总线
WAIT05();
dout_ds18b20=1; //释放总线
WAIT05();
WAIT05(); //延时15us
WAIT02();
if(din_ds18b20==1)
{
WDbuff = WDbuff | 0x80;
}
else
WDbuff = WDbuff & 0x7F;
WAIT90(); //延时90us
int_enable();
}
scrdata[i]=WDbuff;
}
}
//**********
//CRC校验(8个字节)
//入口:无
//出口:无
//************
Byte CRCCheck8(void)
{
Byte crc=0,i,j,byta;
for(i=0;i<8;i++)
{
byta=scrdata[i]; //接收数据
for(j=0;j<8;j++)
{
if(((byta^crc)&0x01)==0x01) //异或,取.0位
{
crc=crc^0x18;
crc=crc>>1;
crc=crc|0x80;
}
else
crc=crc>>1;
byta=byta>>1;
}
}
return crc;
}
//**********
//延时5us(15个NOP)
//入口:无
//出口:无
//************
void WAIT05(void)
{
asm NOP;
asm NOP;
asm NOP;
asm NOP;
asm NOP;
asm NOP;
asm NOP;
asm NOP;
asm NOP;
asm NOP;
}
//**********
//延时90us
//入口:无
//出口:无
//************
void WAIT90(void)
{
Byte i;
for(i=40;i>0;i--)
{
asm NOP;
asm NOP;
asm NOP;
}
}
//**********
//延时600us
//入口:无
//出口:无
//************
void WAIT600(void)
{
Word i;
for(i=320;i>0;i--)
{
asm NOP;
asm NOP;
asm NOP;
}
}
//********
//读一位
//入口:无
//出口:无
//************
Byte RdOneBit(void)
{
Byte a;
dout_ds18b20=0;
WAIT05();
dout_ds18b20=1;
WAIT05();
WAIT05();
WAIT02();
if (din_ds18b20==1)
a=1;
else
a=0;
WAIT90();
WAIT05();
dout_ds18b20=1;
WAIT05();
return a;
}
//********
//写一位
//入口:无
//出口:无
//************
void WrOneBit(Byte bit)
{
dout_ds18b20=0;
WAIT05();
WAIT02();
if(bit==1)
{
dout_ds18b20=1;
}
else
{
dout_ds18b20=0;
}
WAIT90();
dout_ds18b20=1;
WAIT05();
WAIT05();
}
//********
//找寻18b20的rom号
//结果存于rom[j(第几个传感器)][k(rom的第几个字节)]中
//入口:无
//出口:无
//************
Byte search_ds18b20_rom(void)
{
Byte bit0,bit1,i=0,j=0,k=0,errflag=0,counter=0,counterbak=0,temp[10];
for(i=0;i<10;i++)
{
temp[i]=0;
}
while(errflag==0)
{
init_ds18b20();
Wr1820(SEARCHROM);
for(i=0;i<64;i++)
{
while((i<=counterbak)&&(j>0))
{
bit0=RdOneBit();
bit1=RdOneBit();
if(i<counterbak)
{
if((bit0==0)&&(bit1==0))
{
if((temp[i/8]&(0x01<<i%8))!=(0x01<<i%8))
counter=i;
}
WrOneBit((Byte)(temp[i/8]&(0x01<<(i%8)))>>(i%8));
}
else
{
WrOneBit(1);
temp[i/8]=temp[i/8]|(1<<(i%8)); //该位记录1
}
i++;
}
bit0=RdOneBit();
bit1=RdOneBit();
if((bit0==0)&&(bit1==0))
{
counter=i;
temp[i/8]=temp[i/8]&(0xff-(1<<(i%8))); //该位记录0
WrOneBit(0);
}
else if((bit0==0)&&(bit1==1))
{
temp[i/8]=temp[i/8]&(0xff-(1<<(i%8))); //该位记录0
WrOneBit(0);
}
else if((bit0==1)&&(bit1==0))
{
temp[i/8]=temp[i/8]|(1<<(i%8)); //该位记录1
WrOneBit(1);
}
else
{
errflag=1;
i=100;
}
}
for(k=0;k<8;k++)
{
scrdata[k]=temp[k];
}
if(scrdata[7]==CRCCheck7())
{
for(k=0;k<8;k++)
{
romno[j][k]=temp[k];
}
}
++j;
counterbak=counter;
counter=0;
}
return j-1;
}
//********************
//入口参数:编号
//出口参数,实际写入编号
//写入错误,返回0x99
//*******************
Byte setno(Byte Number)
{
Byte j;
int_disable();
init_ds18b20();
Wr1820(SKIPROMT);
Wr1820(WRSCRATCHT);
Wr1820(Number);
Wr1820(Number);
Wr1820(0x1f);
init_ds18b20();
Wr1820(SKIPROMT);
Wr1820(COPYSCRATCH);
init_ds18b20();
Wr1820(SKIPROMT);
Wr1820(RDSCRATCHT);
RDTXT();
if(scrdata[2]==scrdata[3])
{
j=scrdata[3];
}
else
j=0x99;
int_enable();
return j;
}
//**********
//CRC校验(8个字节)
//入口:无
//出口:无
//************
Byte CRCCheck7() //CRC校验
{
Byte crc=0,i,j,byta;
for(i=0;i<7;i++)
{
byta=scrdata[i]; //接收数据
for(j=0;j<8;j++)
{
if(((byta^crc)&0x01)==0x01)//异或,取.0位
{
crc=crc^0x18;
crc=crc>>1;
crc=crc|0x80;
}
else
crc=crc>>1;
byta=byta>>1;
}
}
return crc;
}
/************************电路板环境温度测量***********************/
void init_board_temp(void)
{
board_ds18b20_ddr=1;
board_ds18b20=1;
WAIT05();
WAIT05();
board_ds18b20=0;
WAIT600();
board_ds18b20=1;
WAIT600();
}
void convt_board_temp(void)
{
init_board_temp();
Wr1820_bd(SKIPROMT);
Wr1820_bd(CONVERTT);
}
Byte get_board_temp(void)
{
Byte i,flag=0;
for(i=0;i<3;i++)
{
init_board_temp();
Wr1820_bd(SKIPROMT);
Wr1820_bd(RDSCRATCHT); //read scratchpad指令
RDTXT_bd(); //读寄存器数据9个字节
if(CRCCheck8()==scrdata[8])
{
flag=1;
board_temp=(scrdata[1]<<4)+(scrdata[0]>>4);//取出整数部分
//考虑到负温度,于是取40摄氏度的偏移量,确保全部是正数
if((board_temp&0x80)==0x80) //负温度
board_temp=40-((board_temp^0xff)+1);
else //正温度
board_temp=40+board_temp;
break;
}
}
return flag;
}
//*************
//写1820一个字节
//入口:写入值
//出口:无
//*************
void Wr1820_bd(Byte wr1820)
{
Byte i;
int_disable();
for(i=0;i<8;i++)
{
WrOneBit_bd(wr1820 & 0x01);
wr1820=wr1820>>1;
}
int_enable();
}
//************
//读寄存器数据9个字节,放入scrdata[]中
//入口:无
//出口:无
//************
void RDTXT_bd(void)
{
Byte i,j;
Byte WDbuff;
for(i=0;i<9;i++)
{
WDbuff=0;
for(j=0;j<8;j++)
{
int_disable();
board_ds18b20_ddr=1;
WDbuff=WDbuff>>1;
board_ds18b20=0; //拉低总线
WAIT05();
board_ds18b20=1; //释放总线
WAIT05();
WAIT05(); //延时15us
WAIT02();
board_ds18b20_ddr=0;
if(board_ds18b20==1)
{
WDbuff = WDbuff | 0x80;
}
else
WDbuff = WDbuff & 0x7F;
WAIT90(); //延时90us
int_enable();
}
scrdata[i]=WDbuff;
}
}
//************
//读一位
//入口:无
//出口:无
//************
Byte RdOneBit_bd(void)
{
Byte a;
board_ds18b20_ddr=1;
board_ds18b20=0;
WAIT05();
board_ds18b20=1;
WAIT05();
WAIT05();
WAIT02();
board_ds18b20_ddr=0;
if (board_ds18b20==1)
a=1;
else
a=0;
WAIT90();
WAIT05();
board_ds18b20_ddr=1;
board_ds18b20=1;
WAIT05();
return a;
}
//************
//写一位
//入口:无
//出口:无
//************
void WrOneBit_bd(Byte bit)
{
board_ds18b20_ddr=1;
board_ds18b20=0;
WAIT05();
WAIT02();
if(bit==1)
{
board_ds18b20=1;
}
else
{
board_ds18b20=0;
}
WAIT90();
board_ds18b20=1;
WAIT05();
WAIT05();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -