#ifndef DS18B20_H_INCLUDED
#define DS18B20_H_INCLUDED
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#define DS18B20_DDR DDRD
#define DS18B20_PORT PORTD
#define DS18B20_PIN PIND
#define DQ 7
#define DS18B20_DQ_DDR_0 (DS18B20_DDR &= ~(1 << DQ))
#define DS18B20_DQ_DDR_1 (DS18B20_DDR |= (1 << DQ))
#define DS18B20_DQ_0 (DS18B20_PORT &= ~(1 << DQ))
#define DS18B20_DQ_1 (DS18B20_PORT |= (1 << DQ))
#define DS18B20_DQ_PIN (DS18B20_PIN & (1 << DQ))==(1 << DQ)
char DS18B20_Init(void);
void DS18B20_Write_Com(unsigned char Data);
char DS18B20_Read_Data(void);
void DS18B20_Read_Temperature(void);
void DS18B20_Read_Temperature(void);
void DS18B20_Convert_Temp(char *sign,char *Temperature);
///设置全局变量用于存储从DS18B20读取的温度值
char Temp_Value[2];
#endif // DS18B20_H_INCLUDED
#include "DS18B20.h"
/// DS18B20初始化子程序
char DS18B20_Init(void)
{
DS18B20_DQ_DDR_1;
DS18B20_DQ_0; ///拉低总线,持续480us左右,初始化、复位器件
_delay_us(500);
DS18B20_DQ_DDR_0;
_delay_us(60);
return (DS18B20_DQ_PIN); ///用于判断复位是否成功,若成功则返回的值为0,否则为1
DS18B20_DQ_DDR_1;
DS18B20_DQ_1; ///释放总线,持续300us,等待器件发出存在脉冲
_delay_us(300);
}
///向DS18B20写1字节子程序
void DS18B20_Write_Com(unsigned char Data)
{
unsigned char i = 0;
DS18B20_DQ_DDR_1;
for(i = 0;i < 8;i++)
{
DS18B20_DQ_0; ///拉低总线,产生些时间片
_delay_us(45); ///I/O线有高电平变为低电平后,DS18B20在15us至60us之间对I/O口采样,为高写1,为低写0
if((Data & (1 << i)) == (1 << i))
DS18B20_DQ_1; ///写1
else
DS18B20_DQ_0; ///写0
_delay_us(20); ///所有写时间片最短持续期限为60us,各周期之间必须有最短为1us的恢复时间
}
DS18B20_DQ_1; ///释放总线
}
///从DS18B20读1字节子程序
char DS18B20_Read_Data(void)
{
unsigned char i,Data=0;
for(i = 0;i < 8;i++)
{
Data >>= 1; ///数据位右移,先读出的为低位,后读出的为高位
DS18B20_DQ_DDR_1; ///设置总线为输出
DS18B20_DQ_0; ///拉低总线,产生读时间片
_delay_us(5);
//DS18B20_DQ_1; ///因DS18B20输出数据在主机下降沿15秒之内有效,延时后需释放总线
DS18B20_DQ_DDR_0; ///设置总线为读功能,读出DS18B20内的数据
if(DS18B20_DQ_PIN)
Data |= 0x80; ///先读出的为低位,所以或0x80,然后右移
_delay_us(60); ///所有读时间片最短持续期限为60us
}
DS18B20_DQ_DDR_1; ///总线设为输出
return Data;
}
///读取温度值
void DS18B20_Read_Temperature(void)
{
DS18B20_Init();
DS18B20_Write_Com(0xCC); ///跳过序列号
DS18B20_Write_Com(0x44); ///启动温度转换
_delay_ms(10);
DS18B20_Init();
DS18B20_Write_Com(0xCC); ///跳过序列号
DS18B20_Write_Com(0xBE); ///读取温度寄存器
Temp_Value[0]=DS18B20_Read_Data();///读取当前温度低8位
Temp_Value[1]=DS18B20_Read_Data();///读取当前温度高8位
}
///转换温度数据,返回温度符号sign,整数部分Temprature
void DS18B20_Convert_Temp(char *sign,char *Temperature)
{
*sign=1; ///温度符号先设为正
if((Temp_Value[1]&0xF8)==0xF8) ///如果为负数则读取值取反加1转换为温度值,并设置负号标识
{
Temp_Value[1]=~Temp_Value[1];
Temp_Value[0]=~Temp_Value[0]+1;
if(Temp_Value[0]==0x00)
Temp_Value[1]++;
*sign=-1;
}
*Temperature=(Temp_Value[0]>>4)|(Temp_Value[1]<<4);///获取温度值
} |