#include<reg52.h>
#include<stdio.h>
#define uchar unsigned char
#define uint unsigned int
sbit dq=P1^3;
sbit wela=P2^7;
sbit dula=P2^6;
//定义整型的温度数据
//float f_temp;//定义浮点型型的温度数据
uchar code table[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uchar shi,ge;
uchar temp;
void delay(uint k)
{
uint x,y;
for(x=k;x>0;x--)
for(y=110;y>0;y--);
}
void init_ds()//ds18b20复位,初始化函数
{
uchar dat;
uchar k;
dq=1;
k=2;
while(k>0)k--;
dq=0;//将数据线拉低
k=80;//延时范围在480~960us之间
while(k>0)k--;
dq=1;//再次拉高
k=2; //15~60us后接收60~240us的存在脉冲
while(k>0)k--;
dat=dq;//如果dq=0则说明有期间响应即温度传感器是好的,dq=1则说明温度传感器是坏的
k=1;//稍作延时返回
while(k>0)k--;
}
uchar readonechar(void)//读一个字节
{
uchar k;
uchar j;
uchar dat;
dq=1;
k=2;
while(k>0)k--;
for(j=8;j>0;j--)//一个字节分八位读取
{
dq=0;//拉低dq总线开始读取时序
dat>>=1;//右移一位后的值
dq=1;//拉高,为单片机检测ds18b20的输出电平做准备
k=2; //使主机在15us中采样
while(k>0)k--;
if(dq)//读取一位数据 即采样
dat=dat|0x80;//如果读到的数据是1,则将1存入dat,如果是0则保持原数据不变
k=1; //两个读时序之前必须有大于1us的恢复期
while(k>0)k--;
}
return (dat);
}
void writeonechar(uchar dat)//写一个字节
{
uchar k;
uchar j;
for(j=8;j>0;j--)//一个字节分八位读取
{
dq=0;//将数据从高拉低时即启动写时序
dq=dat&0x01;//判定1或0
k=8;//写0时序时,单总线要被拉低至少60us
while(k>0)k--;
dq=1;
dat>>=1;//将dat数据中的各二进制位数据右移1位
}
k=2;
while(k>0)k--;
}
uchar read_temperature(void)//读取温度
{
uchar k;
uchar a=0;
uchar b=0;
uchar t=0;
uchar tt;
init_ds();
writeonechar(0xcc);//跳过读序号列号的操作
writeonechar(0x44);//启动温度转换
k=10;
while(k>0)k--;
init_ds();
writeonechar(0xcc);//跳过读序号列号的操作
writeonechar(0xbe);//读取温度寄存器(共可读九个寄存器)前两个分别是温度的高位和低位
k=10;
while(k>0)k--;
a=readonechar();//读取温度值低位
b=readonechar();//读取温度值高位
t=b;
t<<=4;
t|=(a&0xf0)>>4;
tt=t*0.0625;
t=tt*10+0.5;
return tt;//将数据都放b里面
}
void display_ds(void)
{
dula=1;
P0=table[temp/10];
dula=0;
P0=0xff;
wela=1;
P0=0xfe;
wela=0;
delay(5);
dula=1;
P0=table[temp%10];
dula=0;
P0=0xff;
wela=1;
P0=0xfd;
wela=0;
delay(5);
}
void init()
{
TMOD|=0x20;// 初始化定时器1为8位自动重装模式
SCON=0x50;// 配置串口工作模式,使能了串口接收中断
TH1=0xfd;// 配置波特率
TL1=0xfd;
TR1=1;// 启动定时器1
ES=1;// 打开串口中断允许
TI=1;
}
void main()
{
init();
while(1)
{
temp=read_temperature();
display_ds();
}
}
|