|
![](static/image/common/ico_lz.png)
楼主 |
发表于 2016-12-26 16:37:48
|
显示全部楼层
//******************************************************************
// RW18b20读写函数
//------------------------------------------------------------------
//stc15w408as_IRC_11.0592Mhz测试
//****************************************************************
//延时函数 !!!延时根据不同Crystal和不同mcu要调整!!!
//----------------------------------------------------------------
void delay18(unsigned int count)
{
unsigned char i;
while(count--)
{
for(i=0;i<3;i++)
{
_nop_();
_nop_();
_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_(); //延长延时时间,现在旧探头也能用了!!!
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_(); //再增加延时时间,避免长线出现断数据问题!
_nop_();_nop_();_nop_();_nop_();_nop_();
}
}
}
//i=24=>2us
void delay_1us(unsigned int i)//us级延时
{
while(i--) ;//精确延时
}
//******************************************************************
//第二个温度探头
//------------------------------------------------------------------
Init_DS18B20_1(void)//复位(通讯)
{
unsigned char x=0;
DQ = 1; //端口I/O先拉高,准备复位
delay18(4); //80us
DQ = 0; //通讯复位低电平
delay18(28);//(28)=550us时隙
//(30)=590us
DQ=1;//加此句后,0xcc和0x44发送数据命令正确!!! //DQ==1表示释放总线???
x=DQ; //如果x=0:则初始化成功;
//if(x==) //如果x=1: 失败;
delay18(15);//补偿
}
//写字节
WriteOneChar_1(unsigned char my_dat)//写一个字节
{
unsigned char i=0;
unsigned char j=0;
//0xcc=>204=>0b_1100_1100
//==>写入的第一位数据,LSB应该是“0”值啊,示波器看到“1”值??????
EA=0;
for (i=8; i>0; i--) //先写LSB低位,最后MSB
{
DQ = 0; //写0
delay_1us(2); //就算要写“1”也得先发一个2.5us以上的L电平
//(1)=4~5us;(2)=8us;
DQ = my_dat & 0x01;//写1
//---------------------------------
delay18(3); //读写时隙78us(5T)
//--------------------------------- //5T+
DQ = 1; //强制为1 恢复Trec //恢复至少3us间隙,是由主机发出1高电平么??????
delay_1us(2); //(3)=7us间隔恢复时间
my_dat >>= 1; //写数据右移一bit,最后第8次是MSB写入
}
EA=1;
}
//读字节
ReadOneChar_1(void)//读一个字节
{
unsigned char i=0;
unsigned char my_dat = 0;
EA=0;
DQ=1; //释放总线 //有无以下两句指令,无影响
delay18(2); //延时
//---------------------------------
for(i=8;i>0;i--) //先读LSB低位,最后MSB
{
my_dat >>= 1; //数据移1位 //读到的LSB数据向右移位,这样8次以后,最后读到的MSB在最高位
DQ = 0; //主机拉低总线 //按pdf_P27页要求,至少保持>3us低电平,后,主机要"释放总线"
//---------------------------------
delay_1us(1); //保持20us //在1T位置,做采样时间点
DQ=1; //释放总线 //zxy若无此两句,温度永远显示为0值,即,主机没有释放总线!!!
delay_1us(3); //延时10us左右 //何云成:疑问???
if( DQ ) //==1 //采样!!!
my_dat |= 0x80;
delay18(3); //读写时隙78us //保持4T,读时隙宽度
//---------------------------------
DQ=1; //5T以后,强制1电平 //T_rec>3us满足此条件!!!
delay_1us(2); //(2)=8us维持,以便下一bit读取
}
EA=1;
return(my_dat);
}
ReadTemperature_1(void)//读取RW1820温度值
{
unsigned char a=0;
unsigned char b=0;
unsigned int t=0;
long int tt=0;
//Delay(85); //等待80ms???再读温度==》没有任何改善???
//while(DQ==0) ; //用此条件判读,亦无改善!!!
//---------------------------------
Init_DS18B20_1(); //复位
WriteOneChar_1(0xCC); //跳过ROM
WriteOneChar_1(0xBE); //读暂存器
a=ReadOneChar_1(); //L(温度值)
b=ReadOneChar_1(); //H //后面值不需要了
//---------------------------------
Init_DS18B20_1(); //复位
WriteOneChar_1(0xCC); //Skip ROM 跳过 //0xcc=>204=>0b_1100_1100
WriteOneChar_1(0x44); //C-T启动温度转换
//Delay(250);//延时250us //何云成:疑问??? //zxy:不必要,因为读上一次温度就可以了
//---------------------------------
t=b;
t<<=8;
t=t|a;
//tt=t*0.0625*10;
tt=t*0.625;
t=tt;
return(t);
}
![](static/image/smiley/default/shocked.gif) |
|