#include <reg51.h>
#include<intrins.h>
typedef unsigned char uchar;
typedef unsigned int uint;
uchar code table[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};
uchar code Temperature_Char[8] = {0x0c,0x12,0x12,0x0c,0x00,0x00,0x00,0x00};
uchar code df_Table[] = {0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};
uchar code wei[] = {0x01,0x02,0x04,0x08};
sbit DQ = P3^7;
sbit digt1=P2^0;
sbit digt2=P2^1;
sbit digt3=P2^2;
sbit digt4=P2^3;
sbit k1=P1^0;
sbit k2=P1^1;
sbit k3=P1^2;
sbit k4=P1^3;
uchar DS18B20_IS_OK;
uchar CurrentT = 0;
uchar Temp_Value[]={0x00,0x00};
uchar Display_Digit[]={0,0,0,0};
void delayus(uint us)
{
while(--us);
}
void delay(uint ms)
{
uchar i;
while(ms--)
{
for(i=0;i<120;i++);
}
}
uchar Init_DS18B20() //18B20初始化
{
uchar status;
DQ = 1; //总线拉高
delayus(8); // 12MHz晶振,20us左右
DQ = 0;
delayus(90); //720us左右
DQ = 1; //释放总线
delayus(8);
status=DQ;
delayus(20); //160us左右
DQ=1;
return status;
}
uchar ReadOneByte()
{
uchar i,dat=0;
DQ = 1;
_nop_();
for(i=0;i<8;i++)
{
DQ = 0;
_nop_();_nop_();
dat >>= 1;
DQ = 1;
_nop_();
_nop_();
if(DQ)
dat |= 0X80;
delayus(30);
DQ = 1;
}
return dat;
}
void WriteOneByte(uchar dat) //18B20写数据
{
uchar i;
for(i=0;i<8;i++)
{
DQ = 0;
DQ = dat& 0x01;
delayus(3);
DQ = 1;
dat >>= 1; //右移一位
}
}
void Read_Temperature() //读取温度
{
if(Init_DS18B20()==1)
DS18B20_IS_OK=0;
else
{
WriteOneByte(0xcc); //跳过序列号
WriteOneByte(0x44); //启动温度转换
Init_DS18B20();
WriteOneByte(0xcc);
WriteOneByte(0xbe); //读取温度
Temp_Value[0] = ReadOneByte(); //低八位
Temp_Value[1] = ReadOneByte(); //高八位
DS18B20_IS_OK=1;
}
}
void Display_Temperature()
{
uchar t = 150, ng =0xff, a , b;
if((Temp_Value[1]&0xf8)==0xf8) //判断高5位,如果都为1则是负数
{
Temp_Value[1] = ~Temp_Value[1]; //如果为负数。高八位需要取反,第八位需要取反后加1.
Temp_Value[0] = ~Temp_Value[0]+1;
if(Temp_Value[0]==0x00)
Temp_Value[1]++;
ng = 10;
}
a=Temp_Value[0]&0x0f; //小数点后一位算法
b=a*0.0625*10;
/*----0度以上的数值显示-----*/
Display_Digit[0]=ng;
CurrentT = ((Temp_Value[0]&0xf0)>>4) | ((Temp_Value[1]&0x07)<<4); //整数值
Display_Digit[1] = CurrentT/10; //百位 CurrentT%1000/100;
Display_Digit[2] = CurrentT%10; //十位 CurrentT%100/10;
Display_Digit[3] = b%10; //个位 CurrentT%10;
}
void display(uchar ge,uchar shi,uchar bai,uchar fu) //数码管扫描
{
P2=0X00;
delayus(30);
if(table[fu]==0x40) ////////
{
digt1=~1; //不加NPN三级管位驱动需要取反
}
else
{
digt1=~0; //加NPN三级管位驱动需要取反
}
P0=table[fu];
delay(3);
digt1=~0; //不加NPN三级管位驱动需要取反
if(table[bai]==0x3f)
{
digt2=~0; //不加NPN三级管位驱动需要取反
}
else
{
digt2=~1; //不加NPN三级管位驱动需要取反
}
P0=table[bai];
delay(3);
digt2=~0; //不加NPN三级管位驱动需要取反
digt3=~1; //不加NPN三级管位驱动需要取反
P0=table[shi]+0X80;
delay(3);
digt3=~0; //不加NPN三级管位驱动需要取反
digt4=~1; //不加NPN三级管位驱动需要取反
P0=table[ge];
delay(3);
digt4=~0; //不加NPN三级管位驱动需要取反
}
void main()
{
P0=0XFF;
P2=0X00;
// delayus(10);
Read_Temperature();
delay(500);
delay(500);
while(1)
{
display(Display_Digit[3],Display_Digit[2],Display_Digit[1],Display_Digit[0]);
Read_Temperature();
if(DS18B20_IS_OK)
Display_Temperature();
delayus(3);
}
}
|