4105|6

15

帖子

1

TA的资源

一粒金砂(初级)

楼主
 

基于DS18B20温度传感器的52单片机的温度采集与显示 [复制链接]

1芯积分
本想用此传感器和52单片机实现一个温度采集和1602A显示的功能,但是不知道什么原因温度一直不变,请大神帮我看一下程序哪里有问题

这是传感器的程序,我设置保存为(temp.h)
#include
#define U8 unsigned char
#define uint unsigned int
sbit DS1820_DQ= P1^4; //单总线引脚
void DS18B20_Init() ; //DS18B20 初始化
bit DS1820_Reset(); //DS1820 复位
void DS1820_WriteData(U8 wData); //写数据到 DS1820
U8 DS1820_ReadData(); //读数据
/**********************************************************
*DS18B20 初始化
*函数名称:DS1820_WriteData()
*说明:本初始化程序可以不要,因为 18B20 在出厂时就被配置为 12 位精度了
**********************************************************/
void DS18B20_Init()
{
DS1820_Reset();
DS1820_WriteData(0xCC); // 跳过 ROM
DS1820_WriteData(0x4E); // 写暂存器
DS1820_WriteData(0x20); // 往暂存器的第三字节中写上限值
DS1820_WriteData(0x00); // 往暂存器的第四字节中写下限值
DS1820_WriteData(0x7F); // 将配置寄存器配置为 12 位精度
DS1820_Reset();
}
/**********************************************************
*DS1820 复位及存在检测(通过存在脉冲可以判断 DS1820 是否损坏)
*函数名称:DS1820_Reset()
*说明:函数返回一个位标量(0 或 1)flag=0 存在,反之 flag=1 不存在
**********************************************************/
bit DS1820_Reset()
{
U8 i;
bit flag;
DS1820_DQ = 0; //拉低总线
for (i=240;i>0;i--); //延时 480 微秒,产生复位脉冲
DS1820_DQ = 1; //释放总线
for (i=40;i>0;i--); //延时 80 微秒对总线采样
flag = DS1820_DQ; //对数据脚采样
for (i=200;i>0;i--); //延时 400 微秒等待总线恢复
return (flag); //根据 flag 的值可知 DS1820 是否存在或损坏 ,可加声音告警提示 DS1820 故障
}
/**********************************************************
*写数据到 DS1820
*函数名称:DS1820_WriteData()
**********************************************************/
void DS1820_WriteData(U8 wData)
{
U8 i,j;
for (i=8;i>0;i--)
{
  DS1820_DQ = 0; //拉低总线,产生写信号
  for (j=2;j>0;j--); //延时 4us
  DS1820_DQ = wData&0x01; //发送 1 位
  for (j=30;j>0;j--); //延时 60us,写时序至少要 60us
  DS1820_DQ = 1; //释放总线,等待总线恢复
  wData>>=1; //准备下一位数据的传送
}
}
/**********************************************************
*从 DS1820 中读出数据
*函数名称:DS1820_ReadData()
**********************************************************/
U8 DS1820_ReadData()
{
U8 i,j,TmepData;
for (i=8;i>0;i--)
{
TmepData>>=1;
DS1820_DQ = 0; //拉低总线,产生读信号
for (j=2;j>0;j--); //延时 4us
DS1820_DQ = 1; //释放总线,准备读数据
for (j=4;j>0;j--); //延时 8 微秒读数据
if (DS1820_DQ == 1)
{ TmepData |= 0x80;}
for (j=30;j>0;j--); //延时 60us
DS1820_DQ = 1; //拉高总线,准备下一位数据的读取.
}
return (TmepData);//返回读到的数据
}


**********************************************************************************************
主界面
#include
#include
U8 code string[16]={"Temp Display"};
U8 code DispStr[16]={"www.sxcckj.com"};
U8 temperature[2]; //存放温度数据
sbit lcden=P3^4;
sbit lcdrs=P3^5;
sbit dula=P2^6;
sbit wela=P2^7;
void display(); //待显温度值转换
void DelayMs(uint z)
{
uint x,y;
for(x=z;x>0;x--)
  for(y=110;y>0;y--);  
}
void write_com(U8 com)//write common
{
lcdrs=0;
P0=com;
DelayMs(5);
lcden=1;
DelayMs(5);
lcden=0;
}
void write_data(U8 date) //write data
{
lcdrs=1;
P0=date;
DelayMs(5);
lcden=1;
DelayMs(5);
lcden=0;
}
void LCDInit()
{
dula=0;
wela=0;
lcden=0;
write_com(0x38);//dispaly mode
write_com(0x0f);// guanbiaoshanshuo
write_com(0x06);
write_com(0x01);//clear displayer
write_com(0x80);//*p
}
DisplayChar(U8 X, U8 Y, U8 DData)
{
Y &= 0x1;
X &= 0xF; //限制X不能大于15,Y不能大于1
if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
X |= 0x80; // 算出指令码
write_com(X); //这里不检测忙信号,发送地址码
write_data(DData);
return X;
}
DisplayStr(U8 X,U8 Y,U8 code *DData)
{
U8 ListLength;
ListLength = 0;
Y &= 0x1;
X &= 0xF; //限制X不能大于15,Y不能大于1
while (DData[ListLength]>0x20) //若到达字
{
  if (X <= 0xF) //X坐标应小于0xF
      {
     DisplayChar(X, Y, DData[ListLength]); //显示单个字符
      ListLength++;
     X++;
    }
}
return X ;
}
/**********************************************************
*主程序
**********************************************************/
void main()
{
U8 i;
DelayMs(255);//等待电源稳定,液晶复位完成
LCDInit(); //1602 液晶初始化
DS18B20_Init(); //18B20 初始化,可不用初始化,因为 18B20 出厂时默认是 12 位精度
//SetLight(1); //打开背光灯
DisplayStr(0,0,string);//显示"温度:"
DisplayStr(0,1,DispStr);//显示"系列号"
DelayMs(250);
DelayMs(250);
DelayMs(250);
DelayMs(250);
DelayMs(250);
DelayMs(250);
DelayMs(250);
DelayMs(250);
DelayMs(250);
DelayMs(250);
write_com(0x01); // 清屏
DelayMs(50);
//SetLight(0); //关闭背光灯
while (1)
{
  DS1820_Reset(); //复位
  DS1820_WriteData(0xcc); //跳过 ROM 命令
  DS1820_WriteData(0x44); //温度转换命令
  DS1820_Reset(); //复位
  DS1820_WriteData(0xcc); //跳过 ROM 命令
  DS1820_WriteData(0xbe); //读 DS1820 温度暂存器命令
  for (i=0;i<2;i++)
  {
      temperature=DS1820_ReadData(); //采集温度
  }
  DS1820_Reset(); //复位,结束读数据
  display(); //显示温度值
  DelayMs(50);
}
}
/**********************************************************
*转换显示子程序
**********************************************************/
void display()
{
U8 temp_data,temp_data_2;
U8 temp[7]; //存放分解的 7 个 ASCII 码温度数据
U8 TempDec; //用来存放 4 位小数
temp_data = temperature[1];
temp_data &= 0xf0; //取高 4 位
if (temp_data==0xf0) //判断是正温度还是负温度读数
{
  //负温度读数求补,取反加 1,判断低 8 位是否有进位
  if (temperature[0]==0)
  { //有进位,高 8 位取反加 1
   temperature[0]=~temperature[0]+1;
   temperature[1]=~temperature[1]+1;
  }
  else
  { //没进位,高 8 位不加 1
   temperature[0]=~temperature[0]+1;
   temperature[1]=~temperature[1];
  }
}
temp_data = temperature[1]<<4; //取高字节低 4 位(温度读数高 4 位),注意此时是 12 位精度
temp_data_2 = temperature[0]>>4; //取低字节高 4 位(温度读数低 4 位),注意此时是 12 位精度
temp_data = temp_data|temp_data_2; //组合成完整数据
temp[0] = temp_data/100+0x30; //取百位转换为 ASCII 码
temp[1] = (temp_data%100)/10+0x30; //取十位转换为 ASCII 码
temp[2] = (temp_data%100)%10+0x30; //取个位转换为 ASCII 码
temperature[0]&=0x0f; //取小数位转换为 ASCII 码
TempDec = temperature[0]*625; //625=0.0625*10000,表示小数部分,扩大 1 万倍 ,方便显示
temp[3] = TempDec/1000+0x30; //取小数十分位转换为 ASCII 码
temp[4] = (TempDec%1000)/100+0x30; //取小数百分位转换为 ASCII 码
temp[5] = ((TempDec%1000)%100)/10+0x30;//取小数千分位转换为 ASCII 码
temp[6] = ((TempDec%1000)%100)%10+0x30;//取小数万分位转换为 ASCII 码
if(temp[0]==0x30) DisplayChar(3,0,' ');//如果百位为 0,显示空格
else DisplayChar(3,0,temp[0]); //否则正常显示百位
DisplayChar(4,0,temp[1]);//十位
DisplayChar(5,0,temp[2]);//个位
DisplayChar(6,0,0x2e); //小数点 .
DisplayChar(7,0,temp[3]);
DisplayChar(8,0,temp[4]);
DisplayChar(9,0,temp[5]);
DisplayChar(10,0,temp[6]);
DisplayChar(11,0,'\''); //显示'
DisplayChar(12,0,'C'); //显示 C
}
此帖出自51单片机论坛

最新回复

ds18b20采集模块lct2662m,                                     ds18b20采集仪表 LCT2201C   采集数据显示   培训视频    详情 回复 发表于 2019-9-27 12:34
点赞 关注(2)
 

回复
举报

15

帖子

1

TA的资源

一粒金砂(初级)

沙发
 
C:\Users\heyang\Desktop\IMG_4111.JPG

IMG_4111.JPG (1.22 MB, 下载次数: 3)

IMG_4111.JPG
此帖出自51单片机论坛
 
 
 

回复

506

帖子

0

TA的资源

一粒金砂(高级)

板凳
 
1.用串口看一下你采集的温度是否变化了?
2.单纯给显示屏幕发数据,看是否有变化了?
然后你就知道了是采集的问题还是显示的问题了。
此帖出自51单片机论坛
 
 
 

回复

15

帖子

1

TA的资源

一粒金砂(初级)

4
 
问题已经找出 现在已经能够实时采集温度了
此帖出自51单片机论坛
 
 
 

回复

203

帖子

0

TA的资源

一粒金砂(高级)

5
 

不错,支持。

也可以选用成品模块,更适合现场

多点DS18B20采集模块LCT2662M或者仪表LCT2201C

 

此帖出自51单片机论坛
 
个人签名北京长信物联科技有限公司
专业的USB温湿度传感器、485温湿度传感器、气体传感器、64路DS18B20温度采集模块厂商。
www.lct2000.cn
QQ:1930227091
 
 

回复

13

帖子

0

TA的资源

一粒金砂(中级)

6
 

有广州和上海公司需要招聘MCU单片机应用开发和AE,欢迎联系,微信Lianjie0706, 或者发邮件到mobile_info@126.com

此帖出自51单片机论坛
 
 
 

回复

203

帖子

0

TA的资源

一粒金砂(高级)

7
 

ds18b20采集模块lct2662m,                                     ds18b20采集仪表 LCT2201C

 

采集数据显示

 

培训视频 

此帖出自51单片机论坛
 
个人签名北京长信物联科技有限公司
专业的USB温湿度传感器、485温湿度传感器、气体传感器、64路DS18B20温度采集模块厂商。
www.lct2000.cn
QQ:1930227091
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表