//-----------------------------------------------------------------
// 名称: DS18B20温度传感器程序
//-----------------------------------------------------------------
#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
#define INT8U unsigned char
#define INT16U unsigned int
//DS18B20引脚定义
#define DQ PB3
//设置数据方向
#define DQ_DDR_0() DDRB &= ~_BV(DQ)
#define DQ_DDR_1() DDRB |= _BV(DQ)
//温度管引脚操作定义
#define DQ_1() PORTB |= _BV(DQ)
#define DQ_0() PORTB &= ~_BV(DQ)
#define RD_DQ_VAL() (PINB & _BV(DQ)) //注意保留这一行的括号
//温度小数位对照表
//如果不使用此表,也可以使用本例后面代码中提供的小数位计算程序.
const INT8U df_Table[]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};
//当前读取的温度整数部分
INT8U CurrentT = 0 ;
//从DS18B20读取的温度值
INT8U Temp_Value[] = {0x00,0x00};
//待显示的各温度数位
INT8U Display_Digit[] = {0,0,0,0};
//传感器状态标志
INT8U DS18B20_ERROR = 0;
//当前温度显示缓冲
char Current_Temp_Display_Buffer[] = {" TEMP: "};
//-----------------------------------------------------------------
// 初始化DS18B20
//-----------------------------------------------------------------
INT8U Init_DS18B20()
{
INT8U status;
DQ_DDR_1();DQ_0();_delay_us(500);
DQ_DDR_0();_delay_us(50);
status=RD_DQ_VAL();_delay_us(500);
DQ_1();
return status;
}
//-----------------------------------------------------------------
// 读一字节
//-----------------------------------------------------------------
INT8U ReadOneByte()
{
INT8U i,dat=0;
for(i=0;i<8;i++)
{
DQ_DDR_1();DQ_0();
DQ_DDR_0();
if(RD_DQ_VAL())dat|=_BV(i);
_delay_us(80);
}
return dat;
}
//-----------------------------------------------------------------
// 写一字节
//-----------------------------------------------------------------
void WriteOneByte(INT8U dat)
{
INT8U i;
for(i=0x01;i!=0x00;i<<=1)
{
DQ_DDR_1();DQ_0();
if(dat&i)DQ_1();else DQ_0();
_delay_us(80);
DQ_1();
}
}
//-----------------------------------------------------------------
// 读取温度值
//-----------------------------------------------------------------
void Read_Temperature()
{
if(Init_DS18B20()!=0x00)
DS18B20_ERROR = 1;
{
WriteOneByte(0xcc);
WriteOneByte(0x44);
Init_DS18B20();
WriteOneByte(0xcc);
WriteOneByte(0xbe);
Temp_Value[0] = ReadOneByte();
Temp_Value[1] = ReadOneByte();
DS18B20_ERROR = 0;
}
}
//-----------------------------------------------------------------
// 温度值转换
//-----------------------------------------------------------------
void Temperature_Convert()
{
INT8U ng=0;
if((Temp_Value[1]&0xf0)==0xf0)
{
Temp_Value[1]=~Temp_Value[1];
Temp_Value[0]=~Temp_Value[0]+1;
if(Temp_Value[0]==0x00)Temp_Value[1]++;
ng=1;
}
Display_Digit[0]=df_Table[Temp_Value[0]&0x0f];
CurrentT = ((Temp_Value[0]>>4)|(Temp_Value[1]<<4));
Display_Digit[3] = CurrentT/100;
Display_Digit[2]= CurrentT%100/10;
Display_Digit[1]= CurrentT%10;
Current_Temp_Display_Buffer[11]=Display_Digit[0]+'0';
Current_Temp_Display_Buffer[10]='.';
Current_Temp_Display_Buffer[9]=Display_Digit[1]+'0';
Current_Temp_Display_Buffer[8]=Display_Digit[2]+'0';
Current_Temp_Display_Buffer[7]=Display_Digit[3]+'0';
if(Display_Digit[3]==0)Current_Temp_Display_Buffer[7]=' ';
if(Display_Digit[2]==0&&Display_Digit[3]==0)
Current_Temp_Display_Buffer[8]=' ';
if(ng)
{
if(Current_Temp_Display_Buffer[8]==' ')
Current_Temp_Display_Buffer[8]='-';
else
if(Current_Temp_Display_Buffer[7]==' ')
Current_Temp_Display_Buffer[7]='-';
else
Current_Temp_Display_Buffer[6]='-';
}
}