你的需要把结果校验一下,有时候读出来的值有问题的
//=========================DS18B20温度传感器=========================//
#define DS18B20_DQ_IN PIND & (1 << PD6)
/*******************************************************************************
* 函 数 名 : DS18B20_Reset
* 函数功能 : 复位DS18B20
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void DS18B20_Reset(void)
{
DDRD &= ~(1 << PD6); // 端口输入
PORTD &= ~(1 << PD6); // 高阻态
delay_ms(1);
DDRD |= (1 << PD6); // 端口输出,因为是输入高阻态,设置成输出时直接就会输出低电平,拉低DQ
delay_us(500);
DDRD &= ~(1 << PD6); // 拉高DQ,释放总线
delay_us(10);
}
/**
* @brief 单总线初始化
* @param 无
* @retval 从机响应位,0为响应,1为未响应
*/
uchar DS18B20_Check(void)
{
uchar i;
uchar AckBit = 1;
uchar TIMEOUT_MS = 500; // 进行超时判断
DS18B20_Reset();
while (DS18B20_DQ_IN && TIMEOUT_MS > 0)
{
TIMEOUT_MS--;
AckBit = DS18B20_DQ_IN;
}
delay_ms(1);
return AckBit;//如何DS18B20存在返回0,否则返回1
}
/*******************************************************************************
* 函 数 名 : DS18B20_Init
* 函数功能 : 初始化DS18B20的IO口 DQ 同时检测DS的存在
* 输 入 : 无
* 输 出 : 1:不存在,0:存在
*******************************************************************************/
uchar DS18B20_Init(void)
{
uchar a;
a = DS18B20_Check();
return a;
}
/*******************************************************************************
* 函 数 名 : DS18B20_Write_Byte
* 函数功能 : 写一个字节到DS18B20
* 输 入 : dat:要写入的字节
* 输 出 : 无
*******************************************************************************/
void DS18B20_Write_Byte(uchar dat)
{
uchar j;
uchar testb;
for (j = 1; j <= 8; j++)
{
testb = dat & 0x01;
dat = dat >> 1;
if (testb)
{
DDRD |= (1 << PD6); // 拉低DQ
delay_us(2);
DDRD &= ~(1 << PD6); //输入高阻态,拉高DQ
delay_us(60);
}
else // Write 0
{
DDRD |= (1 << PD6); // 拉低DQ
delay_us(60);
DDRD &= ~(1 << PD6); //输入高阻态,拉高DQ
delay_us(2);
}
}
}
/*******************************************************************************
* 函 数 名 : DS18B20_Read_Bit
* 函数功能 : 从DS18B20读取一个位
* 输 入 : 无
* 输 出 : 1/0 1001 0000
*******************************************************************************/
uchar DS18B20_Read_Bit(void) // read one bit
{
uchar data;
DDRD |= (1 << PD6); // 拉低DQ
delay_us(2);
DDRD &= ~(1 << PD6); //输入高阻态,拉高DQ
delay_us(2);
if (DS18B20_DQ_IN)
{
data = 1;
}
else
{
data = 0;
}
delay_us(50);
return data;
}
/*******************************************************************************
* 函 数 名 : DS18B20_Read_Byte
* 函数功能 : 从DS18B20读取一个字节
* 输 入 : 无
* 输 出 : 一个字节数据
*******************************************************************************/
uchar DS18B20_Read_Byte(void) // read one byte
{
uchar i,j,dat;
dat=0;
for (i=0;i<8;i++)
{
j=DS18B20_Read_Bit();
if(j==1)
{
dat|=(0x01<<i);
}
}
return dat;
}
// 0xCC进行设备寻址(只有一个从机时使用)
// 0x44温度变换(读取温度前要执行温度变换,将温度值放到暂存器里)
// 0xBE温度读取(将暂存器里的温度读出)
//DS18B20指令
#define DS18B20_SKIP_ROM 0xCC
#define DS18B20_CONVERT_T 0x44
#define DS18B20_READ_SCRATCHPAD 0xBE
/*******************************************************************************
* 函 数 名 : DS18B20_Start
* 函数功能 : 开始温度转换
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void DS18B20_Start(void)// ds1820 start convert
{
DS18B20_Check();
DS18B20_Write_Byte(DS18B20_SKIP_ROM);// skip rom
DS18B20_Write_Byte(DS18B20_CONVERT_T);// convert
}
/*******************************************************************************
* 函 数 名 : DS18B20_GetTemperture
* 函数功能 : 从ds18b20得到温度值
* 输 入 : 无
* 输 出 : 温度数据
*******************************************************************************/
uchar DS18B20_Crc(uchar *addr, uchar len)
{
uchar crc = 0, inbyte, i, mix;
while (len--)
{
// inbyte 存储当前参与计算的新字节
inbyte = *addr++;
for (i = 8; i; i--)
{
// 将新字节与CRC从低位到高位, 依次做异或运算, 每次运算完CRC右移一位
// 如果运算结果值为1, 则将CRC与 1000 1100 作异或
// 第3,4位代表异或运算, 第7位其实就是运算结果移入的1
mix = (crc ^ inbyte) & 0x01;
crc >>= 1;
if (mix)
{
crc ^= 0x8C;
}
inbyte >>= 1;
}
}
return crc;
}
float DS18B20_GetTemperture(void)
{
uint temp;
uchar a, b;
static float value;
uchar tab[9], CRC8;
DS18B20_Start(); // ds1820 start convert
DS18B20_Check();
DS18B20_Write_Byte(DS18B20_SKIP_ROM); // skip rom
DS18B20_Write_Byte(DS18B20_READ_SCRATCHPAD); // convert
tab[0] = a = DS18B20_Read_Byte(); // LSB
tab[1] = b = DS18B20_Read_Byte(); // MSB
tab[2] = DS18B20_Read_Byte(); //
tab[3] = DS18B20_Read_Byte(); //
tab[4] = DS18B20_Read_Byte(); //
tab[5] = DS18B20_Read_Byte(); //
tab[6] = DS18B20_Read_Byte(); //
tab[7] = DS18B20_Read_Byte(); //
tab[8] = DS18B20_Read_Byte(); // CRC
CRC8 = DS18B20_Crc(tab,8);
if (CRC8 != tab[8]) // CRC校验
{
return value;
}
temp = (b << 8) | a;
if ((temp & 0xf800) == 0xf800)
{
temp = (~temp) + 1;
value = temp * (-0.0625);
}
else
{
value = temp * 0.0625;
}
return value;
}
//=========================DS18B20温度传感器=========================// |