标题:
stc89c52单片机+ds18b20+lcd1601温度计程序
[打印本页]
作者:
chunzz
时间:
2019-6-9 01:32
标题:
stc89c52单片机+ds18b20+lcd1601温度计程序
做了个温度计,和大家分享下。
制作出来的实物图如下:
ds18b20_1.jpg
(128.44 KB, 下载次数: 37)
下载附件
2019-6-9 01:30 上传
ds18b20_2.jpg
(109.52 KB, 下载次数: 27)
下载附件
2019-6-9 01:30 上传
单片机源程序如下:
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar code table[]="TEMP : ";
uchar data disdata[5];//百、十、个、小数位
sbit lcden=P1^1; //液晶使能端
sbit lcdrs=P1^0; //液晶数据命令选择端
sbit DQ=P1^3;
uint tvalue; //温度值
uchar tflag; //温度正负标志
// sbit lcdrw=P1^2;
uchar num;
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void write_com(uchar com)
{
lcdrs=0;
// lcdrw=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_data(uchar date)
{
lcdrs=1;
// lcdrw=0;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void init()
{
lcden=0;
write_com(0x38);//设置16X2显示,5X7点阵,8位数据接口
write_com(0x0c);//设置开显示,不显示光标
write_com(0x06);//写一个字符后地址指针加1
write_com(0x01);//显示清零,数据指针清零
delay(5);
}
/******************************ds18b20程序******************************************************************/
void delay_18b20(uint i)//延时1微秒
{
while(i--);
}
void ds18b20rst() //ds18b20初始化子函数
//要求"数据线拉高-延时-数据线拉低-延时大于480微妙-数据线拉高-延时等待"
{
uchar x=0;
DQ = 1; //信号线DQ复位
delay_18b20(4); //延时
DQ = 0; //DQ拉低
delay_18b20(100); //精确延时大于480us
DQ = 1; //拉高
delay_18b20(40);
}
void ds18b20wr(uchar wdata)/*写数据子函数,无返回值,含参数*/
{
uchar i=0;
for (i=8; i>0; i--)//要写完一个字节,故需要重复8次以下操作
{
DQ = 0; //数据线拉低
DQ = wdata&0x01;//wdata是一个形参,将其与0000 0001进行按位与
//按从低到高的顺序发送数据(一次发送一位)
delay_18b20(10);
DQ = 1; //最后将数据线拉高
wdata>>=1; //将wdata右移1位
}
}
uchar ds18b20rd() //读数据子函数,是有返回值dat
{
uchar i=0;
uchar dat = 0;
for (i=8;i>0;i--)//要读完一个字节,故需要重复8次以下操作
{
DQ = 0; //给脉冲信号
dat>>=1;
DQ = 1; //给脉冲信号
if(DQ)
dat|=0x80;
delay_18b20(10);
}
return(dat); //返回dat
}
read_temp() //读取温度值并转换的子函数,有返回值温度值tvalue
{
uchar a,b;
ds18b20rst(); //调用ds18b20初始化子函数
ds18b20wr(0xcc);//调用写数据子函数,向ds18b20写命令0xcc
//ccH表示跳过ROM读序列号,适用于单机工作,直接向18b20发送温度变换命令
ds18b20wr(0x44);//调用写数据子函数,向ds18b20写命令0x44
//44H表示启动ds18b20温度转换,结果自行存入9字节的RAM中
ds18b20rst(); //调用ds18b20初始化子函数
ds18b20wr(0xcc);//同上
ds18b20wr(0xbe);//调用写数据子函数,向ds18b20写命令0xbe
//beH表示读取RAM中9字节的温度数据
a=ds18b20rd(); //调用读数据子函数,并将所得数据给a
b=ds18b20rd(); //
tvalue=b; //把b的值给tvalue
tvalue<<=8; //tvalue左移8位
tvalue=tvalue|a;//tvalue与a进行按位或
if(tvalue<0x0fff)//
tflag=0; //前五位为0时,读取的温度为正,标志位为0,此时只要
//将测得数值乘以0.0625即可得到实际温度
else //前五位为1时,读取的温度为负,标志位为1,此时需要
{ //将测得数值取反后再加1,再乘以0.0625即可得到实际温度
tvalue=~tvalue+1;
tflag=1; //此时表示负温度
}
tvalue=tvalue*(0.625);//温度值扩大10倍,精确到1位小数
return(tvalue); //返回温度值
}
/*************************************************************************************************************/
/************************温度值显示**************************************************************************/
void ds18b20disp()//温度值显示
{
uchar flagdat;
disdata[0]=tvalue/1000+0x30; //百位数
disdata[1]=tvalue%1000/100+0x30;//十位数
disdata[2]=tvalue%100/10+0x30; //个位数
disdata[3]=tvalue%10+0x30; //小数位
if(tflag==0)
flagdat=0x2b; //正温度显示符号:+
else
flagdat=0x2d; //负温度显示负号:-
if(disdata[0]==0x30)
{
disdata[0]=0x20; //如果百位为0,不显示
if(disdata[1]==0x30)
{
disdata[1]=0x20; //如果百位为0,十位为0也不显示
}
}
write_com(0x80+0x40); //定位数据指针的位置:第二行第六个字符处
write_data(flagdat); //显示符号位
write_com(0x80+0x41); //定位数据指针的位置:第二行第七个字符处
write_data(disdata[0]); //显示百位
write_com(0x80+0x42); //定位数据指针的位置:第二行第八个字符处
write_data(disdata[1]); //显示十位
write_com(0x80+0x43); //定位数据指针的位置:第二行第九个字符处
write_data(disdata[2]); //显示个位
write_com(0x80+0x44); //定位数据指针的位置:第二行第十个字符处
write_data(0x2e); //显示小数点
write_com(0x80+0x45); //定位数据指针的位置:第二行第十一个字符处
write_data(disdata[3]); //显示小数位
}
void main()
{
init();
write_com(0x80);
for(num=0;num<8;num++)
{
write_data(table[num]);
delay(5);
}
while(1)
{
read_temp(); //调用ds18b20读取温度
ds18b20disp(); //调用温度显示子函数
}
}
复制代码
以上所有资料51hei提供打包下载:
ds18b20.rar
(1.99 KB, 下载次数: 88)
2019-6-9 01:32 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
tt98
时间:
2019-6-9 08:36
谢谢楼主!!!
作者:
花式帅
时间:
2020-6-6 08:23
可以做多路
作者:
w1179benp
时间:
2022-3-16 06:55
楼主的标题、图片是LCD1601,可程序却是LCD1602D的,???
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1