voqc/board/Src/ds18b20.c

144 lines
3.2 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "ds18b20.h"
//复位DS18B20
void ds18b20_rst(void)
{
DS18B20_IO_OUT(); //SET PG11 OUTPUT
DS18B20_DQ_OUT(0); //拉低DQ主机至少产生480us的低电平复位信号
delay_us(750); //拉低750us
DS18B20_DQ_OUT(1); //DQ=1
delay_us(15); //15US从机接收到主机的复位信号后会在15~60us后给主机发一个存在脉冲
}
//等待DS18B20的回应
//返回1:未检测到DS18B20的存在
//返回0:存在
uint8_t ds18b20_check(void)
{
uint8_t retry=0;
DS18B20_IO_IN(); //SET PC1 INPUT
while (DS18B20_DQ_IN&&retry<200)
{
retry++;
delay_us(1);
};
if(retry>=200)return 1;
else retry=0;
while (!DS18B20_DQ_IN&&retry<240)
{
retry++;
delay_us(1);
};
if(retry>=240)return 1;
return 0;
}
//从DS18B20读取一个位
//返回值1/0
uint8_t ds18b20_read_bit(void)
{
uint8_t data;
/* 读0和读1的时间至少要大于60us */
DS18B20_IO_OUT(); //SET PC1 OUTPUT
/* 读时间的起始:必须由主机产生 >1us <15us 的低电平信号 */
DS18B20_DQ_OUT(0);
delay_us(2);
DS18B20_DQ_OUT(1);
/* 设置成输入,释放总线,由外部上拉电阻将总线拉高 */
DS18B20_IO_IN(); //SET PC1 INPUT
delay_us(12);
if(DS18B20_DQ_IN)data=1;
else data=0;
delay_us(50);
return data;
}
//从DS18B20读取一个字节
//返回值:读到的数据
uint8_t ds18b20_read_byte(void)
{
uint8_t i,j,dat;
dat=0;
for (i=1;i<=8;i++)
{
j=ds18b20_read_bit();
dat=(j<<7)|(dat>>1);
}
return dat;
}
//写一个字节到DS18B20
//dat要写入的字节
void ds18b20_write_byte(uint8_t dat)
{
uint8_t j;
uint8_t testb;
DS18B20_IO_OUT(); //SET PG11 OUTPUT;
for (j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
/* 写0和写1的时间至少要大于60us */
if (testb)
{
DS18B20_DQ_OUT(0); // Write 1
delay_us(2); //1us < 这个延时 < 15us
DS18B20_DQ_OUT(1);
delay_us(60); //60us+2us>60us
}
else
{
DS18B20_DQ_OUT(0); // Write 0
delay_us(60);
DS18B20_DQ_OUT(1);
delay_us(2);
}
}
}
//开始温度转换
void ds18b20_start(void)
{
ds18b20_rst();
ds18b20_check();
ds18b20_write_byte(0xcc); // skip rom
ds18b20_write_byte(0x44); // convert
}
//初始化DS18B20的IO口 DQ 同时检测DS的存在
//返回1:不存在
//返回0:存在
uint8_t ds18b20_init(void)
{
DS18B20_DQ_OUT(1);
ds18b20_rst();
return ds18b20_check();
}
//从ds18b20得到温度值
//精度0.1C
//返回值:温度值 -550~1250
short ds18b20_get_temp(void)
{
uint8_t temp;
uint8_t TL,TH;
short tem;
ds18b20_start(); // ds1820 start convert
ds18b20_rst();
ds18b20_check();
ds18b20_write_byte(0xcc); // skip rom
ds18b20_write_byte(0xbe); // convert
TL=ds18b20_read_byte(); // LSB
TH=ds18b20_read_byte(); // MSB
if(TH>7)
{
TH=~TH;
TL=~TL;
temp=0; //温度为负
}else temp=1; //温度为正
tem=TH; //获得高八位
tem<<=8;
tem+=TL; //获得低八位
tem=(float)tem*0.625f; //转换
if(temp)return tem; //返回温度值
else return -tem;
}