📄 18b20.txt
字号:
//总线上只有一个ds18b20器件的温度读取和显示程序。 //
//测温范围:-55.00~99.94摄氏度。 //
//使用四位共阳极数码管作为显示器。 //
//不显示符号位, 只显示十位、个位和小数点后两位。 //
//如果温度为负直接显示数值,使用11.0592Mhz晶振。 //
//该程序于2005.5.29在伟福仿真器上调试成功 //
#include <reg51.h>
#define uchar unsigned char
#define sel P0
#define display P1
sbit TMDAT = P3^4; //根据实实际情况设定
sbit temh = P2^5; //高温报警位
sbit teml = P2^2; //低温报警位
uchar x;
/////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////延时部分////////////////////////////////////
void dmsec (unsigned char count)
{
unsigned char i;
while (count)
{
i = 250;
while (i>0) i--;
count--;
}
}
////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////发送复位//////////////////////////////
void tmreset (void)
{
unsigned int i;
EA=0; //关中断//
TMDAT = 0;
i = 103;
while (i>0) i--; // 延时 900 uS(11.0592Mhz时) //
TMDAT = 1;
i = 4;
while (i>0) i--;
EA=1; //开中断//
}
//////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////读一位//////////////////////////////////
bit tmrbit (void)
{
unsigned int i;
bit dat;
EA=0;
TMDAT = 0; i++;
TMDAT = 1; i++; i++; //微量延时 //
dat = TMDAT;
i = 8; while (i>0) i--; // 延时 //
EA=1;
return (dat);
}
////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////// 读一个字节///////////////////////
unsigned char tmrbyte (void)
{
unsigned char i,j,dat;
dat = 0;
for (i=1;i<=8;i++)
{
j = tmrbit ();
dat = (j << 7) | (dat >> 1);
}
return (dat);
}
/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////// 写一个字节//////////////////////////
void tmwbyte (unsigned char dat)
{
unsigned int i;
unsigned char j;
bit testb;
EA=0;
for (j=1;j<=8;j++)
{
testb = dat & 0x01;
dat = dat >> 1;
if (testb)
{
TMDAT = 0; // 写1 //
i++; i++;
TMDAT = 1;
i = 8; while (i>0) i--;
}
else
{
TMDAT = 0; // 写0 //
i = 8; while (i>0) i--;
TMDAT = 1;
i++; i++;
}
}
EA=1;
}
//////////////////////////////////////////////////////////////////////////////////
////////////////////////////////开始转换////////////////////////////////////
void tmstart (void)
{
tmreset (); //复位 //
dmsec (1); //延时 //
tmwbyte (0xcc); //跳过序列号命令,选中ds18b20 //
tmwbyte (0x44); //发转换命令 44H //
}
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////读取温度////////////////////////////////////
uchar tmrtemp (void)
{
unsigned char a,b,y1,y2,y3;
tmreset (); //复位 //
dmsec (1); //延时 //
tmwbyte (0xcc); //跳过序列号命令 //
tmwbyte (0xbe); //发送读取命令 //
a = tmrbyte (); //读取低位温度 //
b = tmrbyte (); //读取高位温度 //
if(b>0x0f) //如果温度值为负,对其取补 //
{
a=~a+1;
if(a==0)
{
b=~b+1;
}
else
{
b=~b;
}
}
x=a&0x0f; //取温度值小数部分 //
y1=a>>4;
y2=b<<4;
y3=y1|y2;
return(y3); //返回温度值的整数部分//
}
///////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////小数值转换//////////////////////////////////
uchar xiaoshu(uchar a)
{
uchar p;
switch(a)
{ //相当于将小数值x*0.0625,再四舍五入保留两位值//
case 0x00:
p=0x00;break;
case 0x01:
p=0x06;break;
case 0x02:
p=0x0d;break;
case 0x03:
p=0x13;break;
case 0x04:
p=0x19;break;
case 0x05:
p=0x1f;break;
case 0x06:
p=0x26;break;
case 0x07:
p=0x2c;break;
case 0x08:
p=0x32;break;
case 0x09:
p=0x38;break;
case 0x0a:
p=0x3f;break;
case 0x0b:
p=0x45;break;
case 0x0c:
p=0x4b;break;
case 0x0d:
p=0x51;break;
case 0x0e:
p=0x58;break;
case 0x0f:
p=0x5e;break;
default:
break;
}
return(p);
}
////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////重新设定ds18b20内部报警温度///////////////////////
void alarm(void)
{
tmreset (); //复位 //
dmsec (1); //延时 //
tmwbyte (0xcc); //跳过序列号命令,选中ds18b20 //
tmwbyte (0x4e); //发写暂存存储器命令//
tmwbyte (0x3c); //写TH(温度上限) 60度 //
tmwbyte (0x0a); //写TL(温度下限) 10度 //
}
/////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////主函数////////////////////////////////////////
void main(void)
{
unsigned char code dispcode_1[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,
0x82,0xf8,0x80,0x90,0xff,0xbf};//十进制数值显示代码,没有小数点 //
unsigned char code dispcode_2[]={0x40,0x79,0x24,0x30,0x19,0x12,
0x02,0x78,0x00,0x10}; //十进制数值显示代码,有小数点 //
unsigned char i,j,last,c1,c2,c3,c4,c;
//alarm(); //设ds18b20内部报警温度//
while(1)
{
temh=0;
teml=0;
dmsec(200); //延时//
tmstart(); //开始转换温度//
dmsec(250); // 延时//
dmsec(250); //延时//
dmsec(250); //延时//
dmsec(200); //延时//
last=tmrtemp(); // 取整数部分温度值//
if(last>0x32) //大于50度就报警,亮红灯//
{
temh=1;
}
if(last<0x0a) //低于10度报警,亮绿灯//
{
teml=1;
}
c=xiaoshu(x); //取小数部分温度值//
c2=last/0x0a; //整数十位值//
c1=last%0x0a; //整数个位值//
c3=c/0x0a; //小数第一位//
c4=c%0x0a; //小数第二位//
for(i=0;i<255;i++)
{
for(j=255;j>0;j--)
{
display=0xff; // 清P1口//
sel=0x08; // 位选//
display=dispcode_1[c2]; // 显十位//
display=0xff; // 清P1口//
sel=0x04; // 位选//
display=dispcode_2[c1]; // 显个位//
display=0xff; // 清P1口//
sel=0x02; // 位选//
display=dispcode_1[c3]; // 显小数第一位//
display=0xff; //清P1口//
sel=0x01; //位选//
display=dispcode_1[c4]; //显小数第二位//
}
}
display=0xff; //清P1口//
}
} //完//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -