#include "ds18b20.h"
#include "stcdelay.h"//这里包含延迟函数,需要根据需要自己更改
#define COMMAND_SKIP_ROM 0xcc
#define COMMAND_CONVERT_TEMPERATURE 0x44
#define COMMAND_READ_SCRATCHPAD 0xbe
#define COMMAND_READ_ROM 0x33
static void Init18B20()
{
BYTE i = 0;
DQ_PIN = 1;
NOP(); //产生一个高电平
NOP();
DQ_PIN = 0;
//480us ~ 960us
for(i = 0; i < 15; i++)
{
DelayUS(40);
}
DQ_PIN = 1; // releases the bus and goes into receive mode
//等待15~60us后再检测
DelayUS(40);
DelayUS(30);
//初始化低电平会持续60~240us,然后会自动拉高,需持续至少480us,这里省略了检测
for(i = 0; i < 12; i++)
{
DelayUS(40);
}
}
static void SetSingleByte(BYTE byte)
{
BYTE i = 0;
/********************************************************************************************************
To generate a Write 1 time slot, after pulling the 1-Wire bus low, the bus master must release the 1-Wire
bus within 15μs. When the bus is released, the 5k pullup resistor will pull the bus high. To generate a
Write 0 time slot, after pulling the 1-Wire bus low, the bus master must continue to hold the bus low for
the duration of the time slot (at least 60μs).
*********************************************************************************************************/
for(i = 0; i < 8; i++)
{
DQ_PIN = 0;
if(TEST_BIT(byte, i)) //若是写入1,在1~15us内释放总线,且持续至少60us等待ds18b20读取
{
DelayUS(2);
//必须大于1us后再释放总线
DQ_PIN = 1; //释放总线
DelayUS(30);
DelayUS(30);
}
else //若是写入0,则保持低电平60us~120us,然后释放
{
DelayUS(30);
DelayUS(30);
DQ_PIN = 1; //释放总线
DelayUS(2); //下一个时隙的间隔必须大于1us
}
}
}
static BYTE GetSingleByte()
{
BYTE Ret = 0;
BYTE i = 0;
/*******************************************************************************************************************
All read time slots must be a minimum of 60μs in duration with a minimum of a 1μs recovery time
between slots. A read time slot is initiated by the master device pulling the 1-Wire bus low for a
minimum of 1μs and then releasing the bus (see Figure 14). After the master initiates the read time slot,
the DS18B20 will begin transmitting a 1 or 0 on bus. The DS18B20 transmits a 1 by leaving the bus high
and transmits a 0 by pulling the bus low. When transmitting a 0, the DS18B20 will release the bus by the
end of the time slot, and the bus will be pulled back to its high idle state by the pullup resister. Output DS18B20
data from the DS18B20 is valid for 15μs after the falling edge that initiated the read time slot. Therefore,
the master must release the bus and then sample the bus state within 15μs from the start of the slot.
*********************************************************************************************************************/
for(i = 0; i < 8; i++)
{
DQ_PIN = 0;
//保持至少1us
DelayUS(2);
DQ_PIN = 1; //释放总线
DelayUS(5); //在15us之内采集即可
//15u之内采集
if(DQ_PIN)
{
SET_BIT(Ret, i);
}
//读写时隙必须大于60us
DelayUS(30);
DelayUS(30);
}
return Ret;
}
void ConvertTemperature()
{
Init18B20();
SetSingleByte(COMMAND_SKIP_ROM);
SetSingleByte(COMMAND_CONVERT_TEMPERATURE);
}
WORD GetTemperature()
{
BYTE loTemp = 0;
BYTE hiTemp = 0;
Init18B20();
SetSingleByte(COMMAND_SKIP_ROM);
SetSingleByte(COMMAND_READ_SCRATCHPAD);
loTemp = GetSingleByte();
hiTemp = GetSingleByte();
return MAKEWORD(loTemp, hiTemp);
}
复制代码
注意:其中的延迟函数需要根据自己的需要实现,我用的是stc的片子,指令周期和c51不一样。
详情回复
发表于 2010-4-6 22:52
uchar data temp_data[2]={0x00,0x00}; //读出温度暂放
uchar data temp_dat[2]={0x00,0x00};
uchar data display[5]={0x00,0x00,0x00,0x00,0x00}; //显示单元数据,共4个数据和一个运算暂用
uchar data display2[5]={0x00,0x00,0x00,0x00,0x00};