📄 1wire.c
字号:
}
if(crc8 != 0){return 0x14;} //返回crc校验失败
if((config!=0x7f)&&(tem_datal!=0x00)&&(tem_datal!=0x00))//配置错误,温度报警设置错误
{return 0x24;} //配置失败
}
//读供电方式
onewire_reset(); //复位;
if(haveic == 0){return 0x04;} //返回无设备
onewire_write(0x55); //匹配rom
onewire_writerom(num); //匹配64bit rom 注册码
onewire_write(0xb4); //读供电方式
if(onewire_rbit() == 0)
{return 0x44;} //返回寄生供电!
return 0x00;
}
/*********************************************************
所有通道循环温度转换
*********************************************************/
void syscyc(void)
{
start_tempad(8); //所有通道广播温度转换(加入短路检测)
for(bus_num=0;;)
{
if(onoff!=0x55) //不许可?
{
onoff=0xaa;
break;
}
WDR();
if(icnum[bus_num]!=0) //wire有无器件/有有无短路/无
{
setdata = set[bus_num];
clrdata = clr[bus_num];
bus1;
if(duanlu[bus_num]!=0xaa) //是短路?
{
if(busindata==0) //GND短路?
{
dianlu[bus_num]+=3;
if(dianlu[bus_num]>=(128+30))
{
duanlu[bus_num]=0X05;
}
delay2us();
}
else
{
bus0;delay15us();
if(busindata!=0) //VCC短路。
{
dianlu[bus_num]+=3;
if(dianlu[bus_num]>=(128+30))
{
duanlu[bus_num]=0X50;
}
}
else
{
duanlu[bus_num]=0xaa;
dianlu[bus_num]-=1;
if(dianlu[bus_num]<=(128-30))
{
duanlu[bus_num]=0Xaa;
}
}
buspullup;
}
}
else if(onewire_rbit/*_dl*/() == 1) //完毕(wait750ms),得到温度数据(加入短路检测)
{
return_alldata();
start_tempad(bus_num);
}
//防止溢出:
if(dianlu[bus_num]>=(128+50)){dianlu[bus_num]=(128+50);}
if(dianlu[bus_num]<=(128-50)){dianlu[bus_num]=(128-50);}
}
bus_num++;
if(bus_num==8)
{
bus_num = 0x00;
}
if(setup==0x55){break;}
if(add_change==0x55){break;}
}
}
/*********************************************************
广播启动温度转换
*********************************************************/
void start_tempad(uchar num)
{
if(num==8)
{
for(bus_num=0;bus_num<8;bus_num++)
{
if(icnum[bus_num]!=0)
{
setdata = set[bus_num];
clrdata = clr[bus_num];
onewire_reset(); //复位;
if(haveic == 0){break;/*//UDR=0x04;out485();*/} //返回无设备
onewire_write(0xcc); //广播——跳跃rom
onewire_write(0x44); //温度转换
}
}
}
else if(num<8)
{
setdata = set[bus_num];
clrdata = clr[bus_num];
onewire_reset(); //复位;
if(haveic == 0){/*//UDR=0x04;out485();*/} //返回无设备
onewire_write(0xcc); //广播——跳跃rom
onewire_write(0x44); //温度转换
}
// else{} //无效!!
}
/*********************************************************
返回通道所有ic温度数据
*********************************************************/
void return_alldata(void)
{
uchar jb_ic_num; //通道ic计数器
uint jb_temp;
for(jb_ic_num=0;jb_ic_num<icnum[bus_num];jb_ic_num++)
{
DDRB=led_ddr[bus_num]; //控制led
PORTB&=led_portb[bus_num]; //控制led
if(onewire_randc()==0X55) //复位;
{
return_data(jb_ic_num);
}
DDRB=0xf0;PORTB|=0x0f; //控制led
}
}
/*********************************************************
返回温度数据
*********************************************************/
void return_data(uchar num)
{
uchar tem_datal,tem_datah;
//if(haveic == 0){return 0x04;} //返回无设备
onewire_write(0x55); //匹配rom
onewire_writerom(num); //匹配64bit rom 注册码
onewire_write(0xbe); //读暂存器9字节
tem_datal = onewire_read();
t_data[bus_num][num*2] = tem_datal;
tem_datah = onewire_read();
t_data[bus_num][num*2+1] = tem_datah;
}
/********************************************************
匹配64bit rom 注册码
**********************************************************/
void onewire_writerom(uchar num)
{
uchar jb_byte_num; //位计数
for(jb_byte_num=0;jb_byte_num<8;jb_byte_num++)
{
onewire_write(allbus_ic_id[bus_num][(num)][jb_byte_num]);
}
}
/**************************************************
初始化:根据总线复位,得到总线有无设备(DS18B20)标志haveic;
**************************************************/
void onewire_reset(void)
{
uchar aaa;
bus1;
//bus = 0; 480us
bus0; //bus = 0;
delay500us(); //480us
buspullup; //bus=1;
//等待bus稳定 nus;
//询问bus上有无设备;从机响应75-300us;本机 480us.
delay120us();
aaa=busindata;
if(aaa == 0)
{haveic = 1;} //
else{haveic = 0;} //总线无设备
//等待总线恢复空闲并延时;
delay380us();
}
/**************************************************
初始化+短路检测:本次失败返回0xaa,否则,返回0x55.
**************************************************/
uchar onewire_randc(void)
{
uchar aaa;
bus1;
if(busindata==0) //GND短路?
{
dianlu[bus_num]+=3;
if(dianlu[bus_num]>=(128+30))
{
duanlu[bus_num]=0X05;
}
delay2us();
return 0xaa;
}
//bus = 0; 480us
bus0; //bus = 0;
delay380us(); //480us
if(busindata!=0) //VCC短路。
{
dianlu[bus_num]+=3;
if(dianlu[bus_num]>=(128+30))
{
duanlu[bus_num]=0X50;
}
return 0xaa;
}
else
{
duanlu[bus_num]=0xaa;
dianlu[bus_num]-=1;
if(dianlu[bus_num]<=(128-30))
{
duanlu[bus_num]=0Xaa;
}
}
delay120us();
buspullup; //bus=1;
//等待bus稳定 nus;
//询问bus上有无设备;从机响应75-300us;本机 480us.
delay120us();
aaa=busindata;
if(aaa == 0)
{haveic = 1;} //
else{haveic = 0;} //总线无设备
//等待总线恢复空闲并延时;
delay380us();
return ox55;
}
/*********************************************
写1字节(ROM或存贮器命令)到总线(DS18B20)
*********************************************/
void onewire_write(uchar byte)
{
uchar jb1,jb2;
bus1;
for(jb2=0;jb2<=7;jb2++)
{
jb1=byte&0x01;
if(jb1==0x01)
{
//严格时序0
CLI();
//写1时隙
bus0; //输出LOW 15us
delay13us();
buspullup; //释放总线HIGH 47us
//严格时序1
SEI();
delay47us();
}
else
{
//写0时隙
bus0; //输出LOW 60us
delay60us();
buspullup; //释放总线HIGH 1.5us
delay2us();
}
delay3us(); //释放总线HIGH 2us
byte=byte>>1;
}
}
/********************************************
写单位
*************************************************/
void onewire_wbit(uchar jbbit)
{
bus1;
if(jbbit!=0)
{
//严格时序0
CLI();
//写1时隙
bus0; //输出LOW 15us
delay15us();
buspullup; //释放总线HIGH 47us
//严格时序1
SEI();
delay47us();
}
else
{
//写0时隙
bus0; //输出LOW 60us
delay60us();
buspullup; //释放总线HIGH 1.5us
delay2us();
}
delay3us(); //释放总线HIGH 2us
}
/*********************************************
从总线(DS18B20)上读1字节数据
*********************************************/
uchar onewire_read(void)
{
uchar jb1,byte,aaa;
byte=0x00;
bus1;
for (jb1=0;jb1<=7;jb1++)
{
byte=byte>>1;
//严格时序0
CLI();
//读时隙:
bus0; //输出LOW 1-2us
delay2us(); //2us
buspullup; //释放总线HIGH 等待10us
delay7us();
aaa=busindata;
if(aaa != 0)
{byte|=0x80;}
//严格时序1
SEI();
delay15us();
buspullup;
delay37us();
delay3us();
}
return byte;
}
/********************************************
读单位
*********************************************/
uchar onewire_rbit(void)
{
uchar jbbit;
bus1;
//严格时序0
CLI();
//读时隙:
bus0; //输出LOW 1-2us
delay3us(); //2us
buspullup; //释放总线HIGH 等待10us
delay7us();
jbbit = busindata;
//严格时序1
SEI();
delay15us();
buspullup;
delay37us();
delay3us();
// bus1;
if(jbbit == 0x00)
return 0;
else return 1;
}
/********************************************************
精准延时0.5us子程序(n+1)*0.5us
(nus*8-1)+9/16=(n+1)*0.5us
8:1t 5t 2t
-1:当为最后一次判断,brne _L2 1t
9:赋值R16 1t rcall 3t nop 1t ret 4t
*********************************************************/
void delayhalfus(uchar nus)
{
asm("_L2: subi R16,1"); // 1t
asm(" nop"); asm(" nop"); asm(" nop"); asm(" nop");
asm(" nop"); // 5t
asm(" brne _L2"); // 2t/1t
WDR(); // 1t
asm(" ret"); // 4t
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -