|
最近的工作需要驱动DS18B20读取温度,在看了DS18B20的文档后第一感觉就是麻烦,由于只用了一根线的原因对于时序的要求极为严格,所以做了3天了都还没采出温度来
很让人恼火!希望各位指点哈!
考虑到我使用的是VRTX平台调试的,而且不怎么熟悉C中嵌汇编弄了半天也没起色所以干脆就全用C了,重要的延时程序也用FOR循环写的,但是经过示波器测试时间上还是比较准确!
del500us() //经过示波器测试实际时间是500~510us
del20us() //经过示波器测试实际时间是20us
del6us() //经过示波器测试实际时间是6~7us
int del_time;
del_time+=2; //经过示波器测试实际时间是2us
del_time++; //经过示波器测试实际时间是1.5~2us
然后是我采集温度部分程序:(其中outp()和inp()是VRTX听过的口地址访问)
主程序:
mian()
{
......
_disable();
INIT_DS1820(); //初始化DS1820
DS1820_ROMCMD(0x33); //写ROM命令-读ROM
hj_ch[0]=DS1820_READ();
hj_ch[1]=DS1820_READ();
hj_ch[2]=DS1820_READ();
hj_ch[3]=DS1820_READ();
hj_ch[4]=DS1820_READ();
hj_ch[5]=DS1820_READ();
hj_ch[6]=DS1820_READ();
hj_ch[7]=DS1820_READ();
del20us();
del20us();
INIT_DS1820();
DS1820_ROMCMD(0x44);
delay_time(5);
INIT_DS1820();
DS1820_ROMCMD(0xCC);
DS1820_ROMCMD(0xBE);
DS1820_GETTMP();
_enable();
......
}
下面是具体的操作:
void DS1820_ROMCMD(char cmd)
{
char c,cmd_temp;
L0:
cmd_temp=cmd;
outp(P1LTCH,0x00);
for(c=0;c<8;c++)
{
if((cmd_temp&0x01)==0x01)
{
outp(P1LTCH,0x01);
}
else
{
outp(P1LTCH,0x00);
}
del20us();
del20us();
del20us();
/* if((inp(P1PIN)&0x01)!=(cmd_temp&0x01)) //本来是想自己加个校验的但是总是死监控,只有屏蔽先了
{
outp(P1LTCH,0x01);
goto L0;
} */
outp(P1LTCH,0x01);
del6us();
cmd_temp>>=1;
}
outp(P1LTCH,0x01);
}
void INIT_DS1820()
{
char c;
outp(P1LTCH,0x01);
del20us();
outp(P1LTCH,0x00);
del500us();
del20us();
del20us();
del20us();
del20us();
del20us();
outp(P1LTCH,0x01);
del20us();
del6us();
del6us();
while((inp(P1PIN)&0X01)==0x01)
{
del6us();
}
del20us();
del20us();
del20us();
del20us();
del20us();
del20us();
del6us();
outp(P1LTCH,0x01);
}
char DS1820_READ()
{
char i;
char temp=0;
char pin;
outp(P1LTCH,0x01);
del6us();
del6us();
for(i=0;i<8;i++)
{
temp>>1;
outp(P1LTCH,0x00);
del_time++;
outp(P1LTCH,0x01);
del_time=del_time+2;
del_time=del_time+2;
del_time++;
pin=inp(P1PIN);
if((pin&0X01)==0x01)
temp|=0x80;
del20us();
del20us();
del20us();
outp(P1LTCH,0x01);
}
return temp;
}
void DS1820_GETTMP()
{
int i;
double tmp=0;
char r_temp;
for(i=0;i<2;i++)
{
tmpbuf=DS1820_READ();
}
DS1820_RST();
DS1820_IDLE();
r_temp=tmpbuf[0];
if((r_temp&0x01)==0x01)
{
tmp=tmp+0.0625;
}
r_temp>>=1;
for(i=0;i<7;i++)
{
if((r_temp&0x01)==0x01)
{
tmp+=0.0625*2*(i+1);
}
r_temp>>=1;
}
r_temp=tmpbuf[1];
r_temp&=0x07;
tmp+=r_temp*16;
Rtmp=(float)tmp;
}
void DS1820_RST()
{
char i;
_Set186Register(P1LTCH,0x00);
for(i=0;i<12;i++)
{
del20us();
}
_Set186Register(P1LTCH,0x01);
for(i=0;i<12;i++)
{
del20us();
}
}
void DS1820_IDLE()
{
_Set186Register(P1LTCH,0x01);
del6us();
del6us();
}
经过这两天的调试只是把初始化成功通过了(惭愧啊),但是在写命令和读数据上总是不成功读出来的都是0x80,而且无法观察我送出去的命令到底是不是我想发的命令,读数又不成功无法验证发命令,真的很烦劳啊!请大家帮帮忙吧!谢谢了
|
|