本帖最后由 SUNKE9 于 2010-4-2 10:28 编辑
DS18B20多个并在一起,用的rom搜索功能搜出id然后分别读取温度,连线(30cm)短就能读出来,线长(80cm)了就读不出来怎么办?外接4.7k上拉电阻也不见效果。
线短能读出来说明我的读写函数、rom搜索都是正确的,那还差什么事呢?下面是我的读写程序,麻烦做过长距离多个并联的大侠给点指点
/*===================================================================
// 函数功能:判断总线应答
// 输入参数:void
// 返回参数:unsigned char true为应答//如果总线上有18b20则返回0
===================================================================*/
unsigned char ds1820_rst(void)
{
unsigned char ack = 1;
unsigned char i = 0;
cli();
SET_DIR_1WIRE; //Maga16控制总线
SET_OP_1WIRE; //
CLR_OP_1WIRE; //强制拉低
_delay_us(600); //480us~600us
SET_OP_1WIRE; //
CLR_DIR_1WIRE; //释放总线,总线自动上拉
_delay_us(50); //15~60us
sei();
for(i = 250;i > 1;i--)
{
ack = CHECK_IP_1WIRE;
if(ack == 0)
break;
}
SET_DIR_1WIRE;
SET_OP_1WIRE;
_delay_us(240); //240us
if(ack == 0)
{return 0;}
else
{return 1;}
}
/*===================================================================
// 函数功能: 从 1-wire 总线上读取一个字节
// 形参: void
// 返回: unsigned char 读到的值
===================================================================*/
unsigned char read_1820(void)
{
unsigned char i;
unsigned char value = 0;
cli();
for(i = 8; i > 0; i--)
{
value >>= 1; // low bit first
SET_OP_1WIRE;
CLR_OP_1WIRE; // pull DQ low to start timeslot
_delay_us(3);
SET_OP_1WIRE;
CLR_DIR_1WIRE; // release bus
_delay_us(15);
if(CHECK_IP_1WIRE)
value |= 0x80;
_delay_us(100);
SET_DIR_1WIRE;
_delay_us(5); // time interval
}
sei();
return(value);
}
/*===================================================================
// 函数功能: 向 1-WIRE 总线上写一个字节
// 形参: value 写到总线上的值
// 返回: void
===================================================================*/
void write_1820(unsigned char value)
{
unsigned char i;
cli();
SET_DIR_1WIRE;
for(i = 8; i > 0; i--)
{
if(value & 0x01)
{
CLR_OP_1WIRE; // pull DQ low to start timeslot
_delay_us(10);
SET_OP_1WIRE;
_delay_us(100);
}
else
{
CLR_OP_1WIRE; // pull DQ low to start timeslot
_delay_us(100);
SET_OP_1WIRE;
_delay_us(10);
}
value >>= 1;
}
sei();
}
/*===================================================================
函数功能:写一个位
输入参数:unsigned char *tp
返回参数:void
备 注:
程序编制:孙可
修改日期:2009.10.28
===================================================================*/
void WriteB20Bit(unsigned char *tp)
{
if((*tp)& 0x01)
{
CLR_OP_1WIRE; // pull DQ low to start timeslot
_delay_us(1);
SET_OP_1WIRE;
_delay_us(60);
}
else
{
CLR_OP_1WIRE; // pull DQ low to start timeslot
_delay_us(60);
SET_OP_1WIRE;
_delay_us(10);
}
}
/*===================================================================
函数功能:读一个位
输入参数:unsigned char *tp
返回参数:void
备 注:
程序编制:孙可
修改日期:2009.10.28
===================================================================*/
void ReadB20Bit(unsigned char *tp)
{
SET_DIR_1WIRE;
CLR_OP_1WIRE; // pull DQ low to start timeslot
_delay_us(3);
SET_OP_1WIRE;
CLR_DIR_1WIRE; // release bus
_delay_us(10);
if(CHKBIT(DS18B20_PIN,DS18B20_DQ))
{(*tp)|=0x80;}
_delay_us(60);
SET_DIR_1WIRE;
_delay_us(60); // time interval
} |