基于AT89C51单片机和DS18B20温度传感器、LCD1602液晶显示温度的家用电热水器,江湖救急,我QQ236950540 20
3个回答
展开全部
DS18B20对时序要求很严格,我给你一个调试后的程序 晶振是11.0592MHz。
/*LCD_18B20温度采集
电路搭建: CSPIN = P2^7; CLKPIN = P2^6; DIPIN = P2^5;
DQ= P3^4; 晶振:11.0592M
实现功能:通过AT89S51(STC89C51)采集控制DS18B20,在LCD上显示
设计者:陈仲库
设计日期:2006年12月12日
*/
#include<reg51.h>
#include<intrins.h>
#define time_1 300
sbit CSPIN = P2^7; //用户自定义CS对应引脚
sbit CLKPIN = P2^6; //用户自定义CLK对应引脚
sbit DIPIN = P2^5; //用户自定义DI对应引脚
sbit DQ= P3^4; //用户自定义18B20对应引脚
unsigned char data l_data[7]; //用户自定义LCD缓冲区 其中前四个为数字
unsigned char code ch_data[]={0xEB, 0x60,0xC7,0xE5,0x6C,0xAD,0xAF,0xE0,0xEF,0xED};//定义0~9十个数字 小数点并上0x10
void LCD_WriteBit(bit n)
{ DIPIN = n;
_nop_();
_nop_();
CLKPIN = 1;
_nop_();
_nop_();
CLKPIN = 0;
_nop_();
_nop_();
CLKPIN = 1;
}
void LCD_WriteCommand(unsigned char cmdcode) //送控制字
{ unsigned char i;
CSPIN=1;
CSPIN=0;
LCD_WriteBit(1);
LCD_WriteBit(0);
LCD_WriteBit(0);
for (i=0;i<8;i++)
{ if((cmdcode&0x80)==0x80)
LCD_WriteBit(1);
else
LCD_WriteBit(0);
cmdcode<<=1;
}
LCD_WriteBit(0);
DIPIN=1;
CSPIN=1;
}
void LCD_Reset() //初始化
{ LCD_WriteCommand(0x00); //掉电
LCD_WriteCommand(0x02); //关闭
LCD_WriteCommand(0x01); //上电
LCD_WriteCommand(0x03); //显示
LCD_WriteCommand(0x29); //模式设置
}
void lcdwd(unsigned char address,unsigned char data1) //送6位地址+8位数据
{ unsigned char i;
CSPIN = 1;
CSPIN = 0;
LCD_WriteBit(1);
LCD_WriteBit(0);
LCD_WriteBit(1);
address<<=2;
for (i=0;i<6;i++)
{ if((address&0x80)==0x80)
LCD_WriteBit(1);
else
LCD_WriteBit(0);
address<<=1;
}
for (i=0;i<8;i++)
{ if((data1&0x01)==0x01)
LCD_WriteBit(1);
else
LCD_WriteBit(0);
data1>>=1;
}
DIPIN=1;
CSPIN=1;
}
void LCD_WriteWord() //送数(从第一个地址起)
{ unsigned char j;
for(j=0;j<7;j++) lcdwd(j+j,l_data[j]);
}
///////延时子程序////////
void Delay(int us) { int s; for ( s=0; s<us; s++);}
///////DS18B20初始化子程序////////
void DS18B20_rst(void)
{
DQ = 1;
Delay(2);
DQ = 0;
Delay(30); //精确延时 480~960us
DQ = 1;
Delay(8);
}
unsigned int DS18B20_Read(void)
{
int i=0;
unsigned int u=0;
for (i=0;i<16;i++)
{
DQ=0;
u>>=1;
DQ=1;
if(DQ) u|=0x8000;
Delay(4);
}
return (u);
}
void DS18B20_Write(unsigned char ku)
{
int i=0;
for (i=0;i<8;i++)
{
DQ=0;
DQ =ku&0x01;
Delay(3);
DQ=1;
ku>>=1;
}
}
//采集处理显示程序
void Display(void)
{
int t1,t2, t0;
unsigned int tp;
unsigned int lsb;
DS18B20_rst();
DS18B20_Write(0xCC);
DS18B20_Write(0x44);
DS18B20_rst();
DS18B20_Write(0xCC);
DS18B20_Write(0xBE);
tp=DS18B20_Read(); //取得DS18B20读的温度值
LCD_Reset(); //初始化
Delay(100);
if (tp&0x8000)
{
tp=~tp;
tp+=1;
lsb=(unsigned int)(tp*6.25);
l_data[0]=0x04;
t0=lsb/1000;
if(t0) //液晶显示最高位
l_data[1]=ch_data[t0];
else
l_data[1]=0x00;
t2= lsb%1000;
l_data[2]=ch_data[t2/100]|0x10;//第0位写0 小数点|0x10
t1=t2%100;
l_data[3]=ch_data[t1/10];
}
else{
lsb=(unsigned int)(tp*6.25); //18B20采集到结果
///////判断温度是100以内还是负值
if (lsb>10000) ///就是温度高于100度
{
l_data[0]=ch_data[t0=lsb/10000];
t2= lsb%10000;
l_data[1]=ch_data[t2/1000];
t1=t2%1000;
l_data[2]=ch_data[t1/100]|0x10;//第0位写0 小数点|0x10
t1=t2%100;
l_data[3]=ch_data[t1/10];// 第四位
}
else
{
t0=lsb/1000;
if(t0) //液晶显示最高位
l_data[0]=ch_data[t0];
else
l_data[0]=0x00;
t2= lsb%1000;
l_data[1]=ch_data[t2/100]|0x10;//第0位写0 小数点|0x10
t1=t2%100;
l_data[2]=ch_data[t1/10];
l_data[3]=ch_data[t1%10]; // 第四位
//l_data[3]=0xcc;//显示0的上半部 好像度一样
}
}
LCD_WriteWord();
}
void main(void)
{
l_data[4]=0x20;//显示度的符号
while(1)
{
Display();
}
}//温度18b20
希望对你能有帮助
/*LCD_18B20温度采集
电路搭建: CSPIN = P2^7; CLKPIN = P2^6; DIPIN = P2^5;
DQ= P3^4; 晶振:11.0592M
实现功能:通过AT89S51(STC89C51)采集控制DS18B20,在LCD上显示
设计者:陈仲库
设计日期:2006年12月12日
*/
#include<reg51.h>
#include<intrins.h>
#define time_1 300
sbit CSPIN = P2^7; //用户自定义CS对应引脚
sbit CLKPIN = P2^6; //用户自定义CLK对应引脚
sbit DIPIN = P2^5; //用户自定义DI对应引脚
sbit DQ= P3^4; //用户自定义18B20对应引脚
unsigned char data l_data[7]; //用户自定义LCD缓冲区 其中前四个为数字
unsigned char code ch_data[]={0xEB, 0x60,0xC7,0xE5,0x6C,0xAD,0xAF,0xE0,0xEF,0xED};//定义0~9十个数字 小数点并上0x10
void LCD_WriteBit(bit n)
{ DIPIN = n;
_nop_();
_nop_();
CLKPIN = 1;
_nop_();
_nop_();
CLKPIN = 0;
_nop_();
_nop_();
CLKPIN = 1;
}
void LCD_WriteCommand(unsigned char cmdcode) //送控制字
{ unsigned char i;
CSPIN=1;
CSPIN=0;
LCD_WriteBit(1);
LCD_WriteBit(0);
LCD_WriteBit(0);
for (i=0;i<8;i++)
{ if((cmdcode&0x80)==0x80)
LCD_WriteBit(1);
else
LCD_WriteBit(0);
cmdcode<<=1;
}
LCD_WriteBit(0);
DIPIN=1;
CSPIN=1;
}
void LCD_Reset() //初始化
{ LCD_WriteCommand(0x00); //掉电
LCD_WriteCommand(0x02); //关闭
LCD_WriteCommand(0x01); //上电
LCD_WriteCommand(0x03); //显示
LCD_WriteCommand(0x29); //模式设置
}
void lcdwd(unsigned char address,unsigned char data1) //送6位地址+8位数据
{ unsigned char i;
CSPIN = 1;
CSPIN = 0;
LCD_WriteBit(1);
LCD_WriteBit(0);
LCD_WriteBit(1);
address<<=2;
for (i=0;i<6;i++)
{ if((address&0x80)==0x80)
LCD_WriteBit(1);
else
LCD_WriteBit(0);
address<<=1;
}
for (i=0;i<8;i++)
{ if((data1&0x01)==0x01)
LCD_WriteBit(1);
else
LCD_WriteBit(0);
data1>>=1;
}
DIPIN=1;
CSPIN=1;
}
void LCD_WriteWord() //送数(从第一个地址起)
{ unsigned char j;
for(j=0;j<7;j++) lcdwd(j+j,l_data[j]);
}
///////延时子程序////////
void Delay(int us) { int s; for ( s=0; s<us; s++);}
///////DS18B20初始化子程序////////
void DS18B20_rst(void)
{
DQ = 1;
Delay(2);
DQ = 0;
Delay(30); //精确延时 480~960us
DQ = 1;
Delay(8);
}
unsigned int DS18B20_Read(void)
{
int i=0;
unsigned int u=0;
for (i=0;i<16;i++)
{
DQ=0;
u>>=1;
DQ=1;
if(DQ) u|=0x8000;
Delay(4);
}
return (u);
}
void DS18B20_Write(unsigned char ku)
{
int i=0;
for (i=0;i<8;i++)
{
DQ=0;
DQ =ku&0x01;
Delay(3);
DQ=1;
ku>>=1;
}
}
//采集处理显示程序
void Display(void)
{
int t1,t2, t0;
unsigned int tp;
unsigned int lsb;
DS18B20_rst();
DS18B20_Write(0xCC);
DS18B20_Write(0x44);
DS18B20_rst();
DS18B20_Write(0xCC);
DS18B20_Write(0xBE);
tp=DS18B20_Read(); //取得DS18B20读的温度值
LCD_Reset(); //初始化
Delay(100);
if (tp&0x8000)
{
tp=~tp;
tp+=1;
lsb=(unsigned int)(tp*6.25);
l_data[0]=0x04;
t0=lsb/1000;
if(t0) //液晶显示最高位
l_data[1]=ch_data[t0];
else
l_data[1]=0x00;
t2= lsb%1000;
l_data[2]=ch_data[t2/100]|0x10;//第0位写0 小数点|0x10
t1=t2%100;
l_data[3]=ch_data[t1/10];
}
else{
lsb=(unsigned int)(tp*6.25); //18B20采集到结果
///////判断温度是100以内还是负值
if (lsb>10000) ///就是温度高于100度
{
l_data[0]=ch_data[t0=lsb/10000];
t2= lsb%10000;
l_data[1]=ch_data[t2/1000];
t1=t2%1000;
l_data[2]=ch_data[t1/100]|0x10;//第0位写0 小数点|0x10
t1=t2%100;
l_data[3]=ch_data[t1/10];// 第四位
}
else
{
t0=lsb/1000;
if(t0) //液晶显示最高位
l_data[0]=ch_data[t0];
else
l_data[0]=0x00;
t2= lsb%1000;
l_data[1]=ch_data[t2/100]|0x10;//第0位写0 小数点|0x10
t1=t2%100;
l_data[2]=ch_data[t1/10];
l_data[3]=ch_data[t1%10]; // 第四位
//l_data[3]=0xcc;//显示0的上半部 好像度一样
}
}
LCD_WriteWord();
}
void main(void)
{
l_data[4]=0x20;//显示度的符号
while(1)
{
Display();
}
}//温度18b20
希望对你能有帮助
追问
这个不需要水位监测吗?如果加入4*4键盘的话,是不是更好呢?
追答
你需要的 网上没人会给你准确而确切的答复,只是给你一些思路或者程序段,你自己往一起调试。
没有水位检测,加上键盘也很简单,何必要4*4呢,我感觉要增加、减少确定键即可,加上水位检测需要加上一些硬件的。
展开全部
可以提供你原理图和驱动程序,具体的执行还要看你的要求了
本回答被网友采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
我没看懂你的问题,你是要做一个那样的东西么?如果是,我就给你程序
追问
是做一个家用电热水器控制系统,如果再加上4*4键盘,可以设置温度就好
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询