📄 ds18b20.c
字号:
/*
* -= N U A A =-
* 030210634 H Y X QQ:32242111
* DS18b20.C
* 温度采集系统DS18b20驱动程序
* 版本:1.3
* 2005.7.29-8.4
*/
//ATTENTION:端口必须匹配,51单片机端口别忘接上拉电阻(4.7k)至VCC!否则只能读出数据1;
//一线一器件程序:
#include<reg52.h>
#include<intrins.h>
#include <string.h>
#define DATAS P0
sbit PORT_DATA= P2^3;
unsigned char c[2]; //接收码;
float temperature=0; //实际温度绝对值,用于其他控制判断;
unsigned char f; //温符:“0”为正温,“1”为负温;
unsigned char s[16]; //用于显示的字符串,可直接输出;
void delayms(unsigned int count); //延时1ms;
void restoration(void); //复位命令;
void judge(void); //器件判断; ATTENTION:(器件不存在将会陷入死循环)
bit read_bit(void); //读取一位 1bit;
unsigned char read_byte(void); //读取一个字节 8bit;
void write_byte(unsigned char dat); //写一个字节 8bit;
void convention(void); //启动温度转换;
void read_temperature(void); //温度读取;
void FloatToStr(unsigned char *s,int nMaxLen);//数据存入*s字符串中!供显示使用! this function made by XLQ! thank him!
/////////////////////////////////////////////////////////////////////////////////////////////
/*
main()
{
while(1)
{
convention();
delayms(100);
read_temperature();
FloatToStr(s,10);
//此时温度以存入temperature,以供控制;
//显示数据存入s字符串中,可直接显示;
}
}
*/
/////////////////////////////////////////////////////////////////////////////////////////////
void delayms(unsigned int count) //delay 1ms;
{
unsigned int i;
while (count)
{
i = 115;
while (i>0) i--;
count--;
}
}
void restoration(void) //restoration the DS18b20;
{
unsigned int i;
PORT_DATA= 0;
i = 100;
while (i>0) i--;// 900 uS(11.0592Mhz)
PORT_DATA= 1;
i = 4;
while (i>0) i--;
}
void judge(void) //judge the DS18B20 is entity ?
{
unsigned char i;
while (PORT_DATA); //wait the pulse;
while (~PORT_DATA);
i = 4; while (i>0) i--;
}
bit read_bit(void) //read a bit of the data;
{
unsigned int i;
bit dat;
PORT_DATA= 0;
_nop_();
PORT_DATA= 1;
_nop_();
_nop_();
dat = PORT_DATA;
for(i=8;i>0;i--);
return (dat);
}
unsigned char read_byte(void) //read a byte of the data;
{
unsigned char i,j,dat;
dat = 0;
for (i=1;i<=8;i++)
{
dat>>=1;
j = read_bit();
if (j) dat=( dat | 0x80 );
}
return (dat);
}
void write_byte(unsigned char dat) //write a byte to the DS18b20;
{
unsigned int i;
unsigned char j;
bit testb;
for (j=1;j<=8;j++)
{
testb = dat & 0x01;
dat = dat >> 1;
if (testb)
{
PORT_DATA= 0;
_nop_();
_nop_();
PORT_DATA= 1;
for(i=8;i<0;i--);
}
else
{
PORT_DATA= 0;
for(i=8;i<0;i--);
PORT_DATA= 1;
_nop_();
_nop_();
}
}
}
void convention(void) //startup temperature-convention;
{
restoration();
judge();
delayms(1);
write_byte(0xcc); //the code of jump sequence CCH;
write_byte(0x44); //the code of convention 44H;
}
void read_temperature(void) //read the temperature;
{
restoration();
//judge();
delayms(1);
write_byte(0xcc);
write_byte(0xbe);
c[0] = read_byte(); //read the low temperature-data;
c[1] = read_byte(); //read the high temperature-data;
f=0;
if( c[1] & 0x80 )
{
f=1;
c[1]=!c[1];
c[0]=!c[0];
if( c[0]==0xff )
{
c[0]=0x00;
c[1]+=1;
}
else c[0]+=1;
}
}
void FloatToStr(unsigned char *s,int nMaxLen) //计算器式数字显示;数据存入s字符串中!
{
float n;
int i;
int nCount=0;
unsigned char sTmp[9];
int nLeft;
float nRight;
n=c[0]+c[1]*256;
n=n*0.0625;
temperature=n; // 存入实际温度;
nLeft = (int) n; //整数部分
nRight = n-nLeft; //小数部分
while (nLeft > 0) //将整数部分转化为字符串
{
sTmp[nCount] = nLeft%10 + '0';
nLeft = (int)nLeft/10;
nCount++;
if (nCount >= nMaxLen)
{
break;
}
}
for (i=0; i < nCount; i++) //必须倒序才是从高位到低位的
{
s[i] = sTmp[nCount-i-1];
}
if (nCount >= nMaxLen || nRight < 1E-6) //如果整数部分已经超过最大长度,或小数部分为零则退出
{
s[nCount] = '\0';
return;
}
if (nCount == 0) //如果整数部分为零,则应赋值0
{
s[nCount] = '0';
nCount++;
}
s[nCount] = '.';
nCount++;
if (nCount >= nMaxLen)
{
s[nCount] = '\0';
return;
}
while (nRight < 1 && nRight > 1E-6)
{
s[nCount] = (int)(nRight * 10) + '0';
nCount ++;
nRight = (nRight*10)- (int)(nRight * 10);
if (nCount >= nMaxLen)
{
break;
}
}
s[nCount] = '\0';
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -