OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 7153|回复: 3

18B20采集温度超过70度就全部返回ff

[复制链接]

8

主题

26

帖子

0

精华

初级会员

Rank: 2

积分
134
金钱
134
注册时间
2012-6-3
在线时间
21 小时
发表于 2012-7-8 08:10:19 | 显示全部楼层 |阅读模式

我采用的单片机是stc12c5410ad,当温度低于70度时是正常的,一旦超过70度全部返回ff,请高手帮忙解决啊!
以下是18b20的读写程序
#define uchar unsigned char
#define uint unsigned int
unsigned char x=0;
//sbit    DQ  = P2^3;         /* 温度传感器数据线接在P2.3上        */
sbit    DQ  = P2^6;
bit sflag;  //正负数符号,如果是正数则为0,负数则为1
char volatile xiaoshu_temp[5],zhen_temp[4];

void Delay_N1ms(unsigned int t)
{
  unsigned int i,j,k;
  for(k=0;k<12;k++)
  {
  for(j=t;j>0;j--)
     for(i=124;i>0;i--);}  //延时大约 1ms
}
void sendtest(uchar test)
{
   SBUF=test;
   while(!TI);
   TI=0;
}
void delay400ms(void)
{
  unsigned char i,j,k;
  for(i=50;i!=0;i--)
    for(j=100;j!=0;j--)   
  for(k=100;k!=0;k--); 
}
///////////////////////////////////
void delay1178us(void)
{
  unsigned char i,j;
  for(i=17;i!=0;i--)
    for(j=200;j!=0;j--);   //13333 t
}
///////////////////////////////////
void delay600us(void)
{
  unsigned char i,j;
  for(i=30;i!=0;i--)
    for(j=50;j!=0;j--);   //6000 t
}
///////////////////////////////////
void delay60us(void)
{
  unsigned char i,j;
  for(i=10;i!=0;i--)
    for(j=15;j!=0;j--);      // 330t
}
///////////////////////////////////
void delay90us(void)
{
  unsigned char i,j;
  for(i=5;i!=0;i--)
    for(j=50;j!=0;j--);  //1000t
}
///////////////////////////////////
void delay20us(void)
{
  unsigned char i,j;
  for(i=5;i!=0;i--)
    for(j=10;j!=0;j--);   //221t
}
////////////////////////////////////
void delay5us(void)
{
  unsigned char i;
  for(i=26;i!=0;i--);
    //for(j=10;j!=0;j--);
}
/////////////////////////////////
void delay2us(void)
{
  unsigned char i;
  for(i=11;i!=0;i--);
    //for(j=10;j!=0;j--);
}
////////////////////////////////////
void delay_temp(unsigned int n)
{
 while(--n);
}
//------初始化程序--------------------
bit Init_DS18B20(void)

 DQ=1;//DQ先置高
 delay20us();//稍延时
 DQ=0; //发送复位脉冲
 delay600us(); //延时(>480us)
 DQ=1;//拉高数据线
 delay60us();//等待(15~60us)
// x=DQ;//用X的值来判断初始化有没有成功,18B20存在的话X=0,否则X=1
 delay90us();
 delay60us();
 return(DQ);
}
//------读一个字节----------------------------------------------------------------
unsigned char ReadOneChar(void)//主机数据线先从高拉至低电平1ms以上,再使数据线升为高电平,从而产生读信号
{ unsigned char i=0; //每个读周期最短的持续时间为60ms,各个读周期之间必须有1ms以上的高电平恢复期
 unsigned char dat=0;
 for(i=8;i>0;i--)//一个字节有8位
 { DQ=1;
  delay20us();
  delay5us();

  DQ=0;
  dat>>=1;
  DQ=1;
  if(DQ) dat|=0x80;
  delay60us();
 
 }
 return(dat);
}
//------写一个字节----------------------------------------------------------------
void WriteOneChar(unsigned char dat)
{ unsigned char i=0; //数据线从高电平拉至低电平,产生写起始信号。15us之内将所需写的位送到数据线上,
 for(i=8;i>0;i--)//在15~60us之间对数据线进行采样,如果是高电平就写1,低写0发生。
 { DQ=0;//在开始另一个写周期前必须有1us以上的高电平恢复期。
  DQ=dat&0x01;
  delay20us();
  delay5us();
  DQ=1;
  dat>>=1;
 }
 delay60us();
}

//-------读温度值(低位放tempL;高位放tempH;温度值存在temperature.)---------------

float ReadTemperature(void)
{ unsigned int tempL=0; //设全局变量
 unsigned int tempH=0;
 float temperature; //温度值保存在temperature里
 if(!Init_DS18B20());//初始化
    {
 WriteOneChar(0xcc);//跳过读序列号的操作
 WriteOneChar(0xbe); //读温度寄存器(头两个值分别为温度的低位和高位)
 tempL=ReadOneChar(); //读出温度的低位LSB
 tempH=ReadOneChar(); //读出温度的高位MSB
    sendtest(tempH);
    sendtest(tempL);
 temperature=((tempH*256)+tempL)*0.0625; //温度转换,把高低位做相应的运算转化为实际温度
     }

 if(!Init_DS18B20());//初始化
 {WriteOneChar(0xcc);//跳过读序列号的操作
  WriteOneChar(0x44); //启动温度转换
  delay1178us(); //转换需要一点时间,延时
     delay1178us();
    }   
 return(temperature);
}
//读取18B20rom
uchar * read_rom(void)
{
 uchar rom[8],i;
 Init_DS18B20();
 WriteOneChar(0x33);
 for(i=8;i>0;i--)
 {
  rom[i-1]=ReadOneChar();
 }
 return &rom[0];
}
/*************************************************************
**功能:序列号匹配子程序          **
**参数:无返回            **
*************************************************************/
bit match_rom(uchar *rom)
{
 uchar i;
 Init_DS18B20();
 WriteOneChar(0x55);
 for(i=8;i>0;i--)
 {
  WriteOneChar(*(rom+i-1));
 }
 return 1;
}
/*************************************************************
**功能:温度处理函数           **
**参数:返回温度            **
*************************************************************/

float last_temp(uchar high,uchar low)

    uint temp1,temp3;
   
 float temperature; //温度值保存在temperature里
    if(high&0x80)//判断正负
     {
    sflag=1;
    temp3=temp3|high;
 temp3=temp3&0x00ff;
 temp3=temp3<<8;
 temp1=temp3;
 temp1=temp1|low;
 temp1=(temp1^0xffff);
 temp1=temp1+1;  //取反加1
    temperature=temp1*0.0625;
    sendtest(0xff);
      }
     else
     {
      sflag=0;
      temperature=((high*256)+low)*0.0625; //温度转换,把高低位做相应的运算转化为实际温度
      }  
    return(temperature);
}


 

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165309
金钱
165309
注册时间
2010-12-1
在线时间
2108 小时
发表于 2012-7-8 09:31:12 | 显示全部楼层
超过70°,没测试过哦.
检查是不是因为延时的问题?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

头像被屏蔽

6168

主题

7036

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
19705
金钱
19705
注册时间
2012-12-27
在线时间
25 小时
发表于 2013-4-22 17:11:34 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
22
金钱
22
注册时间
2015-2-27
在线时间
0 小时
发表于 2015-2-27 22:28:38 | 显示全部楼层
读温度值函数加延时
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-23 08:40

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表