求stc89c52单片机c语言ds18b20温度控制

2024-12-19 00:56:36
推荐回答(2个)
回答1:

#include

#define uchar unsigned char

#define uint unsigned int

uchar i;

uchar n=0;

int nowtemp;

int highest=900;

int lowest=700;

sbit lcdrs=P2^4;     //数据/命令选择端(h/l)

sbit lcdrw=P2^3;     //读/写选择端(h/l)

sbit lcden=P2^2;

sbit p25=P2^5;

sbit p26=P2^6;

sbit p27=P2^7;

sbit p20=P2^0;

sbit p30=P3^0;

bit k=0;

bit u=0;

bit j=0;

uchar code wendu[]="0123456789";//利用一个温度表解决温度显示乱码

sbit DQ = P2^1;      //定义ds18B20总线IO

void delay(uchar z)    //延时子函数

{

uchar x,y;

for(x=50;x>1;x--)

   for(y=z;y>1;y--);

}

void write_com(uchar com) //向液晶写入命令函数

{

lcdrs=0;

lcdrw=0;

P1=com;

delay(5);

lcden=1;

delay(5);

lcden=0;

}

void write_date(uchar date)   //写入数据函数

{

lcdrs=1;

lcdrw=0;

P1=date;

delay(1);

lcden=1;

delay(1);

lcden=0;

}

void init_lcd()    //液晶初始化

{

lcden=0;     //液晶使能

lcdrw=0;     //置写状态

write_com(0x38);   //显示模式设置;

write_com(0x01);    //清除屏幕;

write_com(0x0c);    //开显示;

write_com(0x06);    //显示光标移动设置

write_com(0x80);    //设置数据地址指针

}

void write_one(char *p)

{

unsigned char i;

write_com(0x80);

for(i=0;p[i]!=0;i++)   

   {

    write_date(p[i]);

    delay(10);

   }

}

void write_two(char *p)

{

unsigned char i;

write_com(0x80+0x40); 

for(i=0;p[i]!=0;i++)  

   {

    write_date(p[i]);

    delay(10);

   }

}

write_int(int num)

{

unsigned int bai,shi,ge,xiaoshu;     //这里的num,shi,ge,xiaoshu 必须用unsigned int无符号整数来表示,用unshigned char 字符

unsigned char d;

if(num<0)d=0x2D;

else   d=0x2B;

if(num<0)num=-num;

bai=num/1000;

shi=num%1000/100;

ge=num%1000%100/10;

xiaoshu=num%10;

write_date(d);

write_date(wendu[bai]);

write_date(wendu[shi]);

write_date(wendu[ge]);

write_date(0x2e);     //写入小数点

write_date(wendu[xiaoshu]);

write_date(0xDF);

write_date(0x43);

}

void tmpDelay(int num) //延时函数

{

while(num--) ;

}

void Init_DS18B20()   //初始化ds1820

{

unsigned char x=0;

DQ = 1;          //DQ复位

tmpDelay(8);     //稍做延时

DQ = 0;          //单片机将DQ拉低

tmpDelay(80);    //精确延时 大于 480us

DQ = 1;          //拉高总线

tmpDelay(14);

x=DQ;            //稍做延时后 如果x=0则初始化成功 x=1则初始化失败

tmpDelay(20);

}

unsigned char ReadOneChar()//读一个字节

{

unsigned char i=0;

unsigned char dat = 0;

for (i=8;i>0;i--)

{

   DQ = 0;    // 给脉冲信号

   dat>>=1;

   DQ = 1;    // 给脉冲信号

   if(DQ)

   dat|=0x80;

   tmpDelay(4);

}

return(dat);

}

void WriteOneChar(unsigned char dat)//写一个字节

{

unsigned char i=0;

for (i=8; i>0; i--)

{

   DQ = 0;

   DQ = dat&0x01;

   tmpDelay(5);

   DQ = 1;

   dat>>=1;

}

}

int Readtemp()//读取温度

{

unsigned char a=0;

unsigned char b=0;

int t=0,t1=0;

float tt=0;

Init_DS18B20();

WriteOneChar(0xCC); // 跳过读序号列号的操作

WriteOneChar(0x44); // 启动温度转换

Init_DS18B20();

WriteOneChar(0xCC); //跳过读序号列号的操作

WriteOneChar(0xBE); //读取温度寄存器

a=ReadOneChar();   //连续读两个字节数据   //读低8位

b=ReadOneChar();                         //读高8位

t=b;

t1=a;

if(t>7){t=t&0x07;tt=-(128-t*16-t1*0.0625);}

else {t<<=8;

t=t|a; //两字节合成一个整型变量。

tt=t*0.0625; }//得到真实十进制温度值,因为DS18B20可以精确到0.0625度,所以读回数据的最低位代表的是0.0625度

t= tt*10+0.5; //放大十倍,这样做的目的将小数点后第一位也转换为可显示数字,同时进行一个四舍五入操作。

return(t);

}

void main()

{

p20=0;

p30=0;

init_lcd();

while(1)

{

nowtemp=Readtemp();

if(p26==1)u=0;

if(p27==1)k=0;

if(p25==1)j=0;

if(nowtemplowest)

p20=1;

else

p20=0;

if(nowtemp

p30=1;

if(nowtemp >highest)

p30=0;

if(p26==0)

{

if(u==0)

{

if(n==1)

highest=highest+50;

if(n==2)

lowest=lowest+50;

}

u=1;

}

if(p27==0)

{

if(k==0)

{

if(n==1)

highest=highest-50;

if(n==2)

lowest=lowest-50;

}

k=1;

}

if(p25==0)

{

if(j==0)

{

n++;

if(n>2)n=0;

write_com(0x01);

}

j=1;

}

if(n==0)

{

write_one("now temp is:");

write_two("  ");

write_int(nowtemp);

}

if(n==1)

{

write_one("highest temp is:");

write_two("  ");

write_int(highest);

}

if(n==2)

{

write_one("lowest temp is:");

write_two("  ");

write_int(lowest);

}

}

}

回答2:

还不行的话,我来帮你做做