#include<reg51.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit DQ=P1^3;
sbit dula=P2^2;
sbit wela=P2^3;
uchar DuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uchar WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
uint ReadTempFlag;
uchar TempData[8];
/*******************************************
uS延时函数,大致延时
长度 T=uS
*******************************************/
void Delay800us() //@11.0592MHz
{
unsigned char i, j;
_nop_();
_nop_();
_nop_();
i = 9;
j = 151;
do
{
while (--j);
} while (--i);
}
void Delay100us() //@11.0592MHz
{
unsigned char i, j;
_nop_();
_nop_();
i = 2;
j = 15;
do
{
while (--j);
} while (--i);
}
void Delay10us() //@11.0592MHz
{
unsigned char i;
_nop_();
i = 25;
while (--i);
}
void Delay10ms() //@11.0592MHz
{
unsigned char i, j;
i = 108;
j = 145;
do
{
while (--j);
} while (--i);
}
/*******************************************
函数名称:Init_18B20
功 能:对DS18B20进行复位操作
参 数:无
返回值 :初始化状态标志:1--失败,0--成功
********************************************/
bit Init_DS18B20()
{
bit Error;
DQ=1;
Delay10us();
DQ=0;
Delay800us();
DQ=1;
Delay100us();
Error=DQ;
Delay10us();
Delay10us();
Delay10us();
Delay10us();
Delay10us();
return Error;
}
/*******************************************
函数名称:Write_18B20
功 能:向DS18B20写入一个字节的数据
参 数:wdata--写入的数据
返回值 :无
********************************************/
void Write_DS18B20(uchar Wdat)
{
uint i;
for(i=0;i<8;i++)
{
DQ=0;
DQ=Wdat&0x01;
Delay10us();
Delay10us();
//Delay10us(); // ????
//Delay10us();
//Delay10us();
DQ=1;
Wdat>>=1;
}
}
/*******************************************
函数名称:Read_18B20
功 能:从DS18B20读取一个字节的数据
参 数:无
返回值 :读出的一个字节数据
********************************************/
uchar Read_DS18B20()
{
uint i;
uchar Rdat=0;
for(i=0;i<8;i++)
{
DQ=0;
Rdat>>=1;
DQ=1;
if(DQ) Rdat|=0x80;
Delay10us();
Delay10us();
Delay10us();
Delay10us();
Delay10us();
}
return Rdat;
}
/*******************************************
函数名称:Skip
功 能:发送跳过读取产品ID号命令
参 数:无
返回值 :无
********************************************/
void Skip(void)
{
Write_DS18B20(0xcc);
}
/*******************************************
函数名称:Convert
功 能:发送温度转换命令
参 数:无
返回值 :无
********************************************/
void Convert(void)
{
Write_DS18B20(0x44);
}
/*******************************************
函数名称:Read_SP
功 能:发送读ScratchPad命令
参 数:无
返回值 :无
********************************************/
void Read_SP(void)
{
Write_DS18B20(0xbe);
}
/*******************************************
功能:控制DS18B20完成一次温度转换
返回测量的温度数
********************************************/
uint DS18B20_Convert()
{
uint TempL,TempH,Temp;
Init_DS18B20();
Skip();
Convert();
Delay10ms();
Init_DS18B20();
Skip();
Read_SP();
TempL=Read_DS18B20();
TempH=Read_DS18B20();
TempH<<=8;
Temp=TempH+TempL;
return Temp;
}
void main()
{
uint Tt;
float f_Tt;
TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
TH0=(65536-2000)/256; //给定初值
TL0=(65536-2000)%256;
EA=1; //总中断打开
ET0=1; //定时器中断打开
TR0=1; //定时器开关打开
while(1)
{
if(ReadTempFlag==1)
{
ReadTempFlag=0;
Tt=DS18B20_Convert();
if(Tt&0x8000) //为负数时
{
TempData[0]=0x40;
Tt=~Tt;
Tt+=1;
}
else
TempData[0]=0;
/*TtH=Tt>>4;
TtL=Tt&0x0f;
//TtL=TtL*6/10;
if(TtH/100==0)
TempData[1]=0;
else
TempData[1]=DuanMa[TtH/100];
TempData[2]=DuanMa[(TtH%100)/10]; //十位
TempData[3]=DuanMa[(TtH%100)%10]|0x80; //个位
TempData[4]=DuanMa[TtL/10];
TempData[5]=DuanMa[TtL%10];
TempData[6]=0x3f;; */
f_Tt=Tt*0.0625;
f_Tt=f_Tt*100+0.5;
Tt=f_Tt;
TempData[1]=DuanMa[Tt/10000]; //百位
TempData[2]=DuanMa[(Tt%10000)/1000]; //十位
TempData[3]=DuanMa[(Tt%1000)/100]|0x80; //个位
TempData[4]=DuanMa[(Tt%100)/10]; //十分位
TempData[5]=DuanMa[Tt%10]; //百分位
TempData[6]=0x3f;;
TempData[7]=0x39; //显示C符号
}
}
}
void Display(uchar Num)
{
static uchar i=0; //??? 改成uchar i;也行
wela=1;
P0=WeiMa;
wela=0;
dula=1;
P0=TempData;
dula=0;
i++;
if(i==Num) i=0;
}
void Timer0_isr(void) interrupt 1
{
uint num;
TH0=(65536-2000)/256; //重新赋值 2ms
TL0=(65536-2000)%256;
Display(8); // 调用数码管扫描
num++;
if(num==300)
{
num=0;
ReadTempFlag=1; //读标志位置1
}
}
|