打印
[AVR单片机]

玩过18B20的大虾,请帮我看看,怎么读不到温度值。返回来时

[复制链接]
3093|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
cpu51|  楼主 | 2008-3-30 21:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
//M16   11.0592MHZ  3线接法,有电源供电。只接一个18B20
void reset_18b20(void)  
{      
    PORTA|=(1<<PA0);//置1
    DDRA|=BIT(0);//置输出
    delay(150);       //210us
    PORTA&=~(1<<PA0);//置0
    delay(400);      //400*1.4us //480-960us
    PORTA|=(1<<PA0);//置1    
}  
void write_18b20(unsigned char x)  
{     
    unsigned char m;  
    for(m=0;m<8;m++)  
    {
       PORTA&=~(1<<PA0);//置0                   
       if(x&0x01==0x01) //位与//写数据,从低位开始
       PORTA|=(1<<PA0);//置1
       else
       PORTA&=~(1<<PA0);//置0
       delay(20);  //28us   
       PORTA|=(1<<PA0);//置1          
       x=x>>1;
      }  
}  
unsigned int read_18b20(void)  
{      

    unsigned char n;
    unsigned int temp;
      DDRA&=~(1<<PA0);    //转输入    
    temp=0;  
    for(n=0;n<16;n++)  
       {  
         //读数据,从低位开始  
         if(0==(PINA&0x01))
            temp=temp>>1;  
         else  
           {
            temp=temp>>1;
            temp=0x8000+temp;
             }            
        delay(60);     //84us        60~120us
        }  
   return (temp);  
}   

//**************************************************************
//数据采集
//
//**************************************************************
void sampling_analog_1(void)  //数据采集
{
  TCCR0 = 0x00;   //停  T0
  CLI();
 //测量温度
    reset_18b20();//复位18b20  
    write_18b20(0xcc); // 发出转换命令  
    write_18b20(0x44);
    reset_18b20();
    write_18b20(0xcc);//发出读命令  
    write_18b20(0xbe);
    real_no1_temp=read_18b20();//读数据,温度读来是0xFFFF.
    TCCR0 = 0x15;   //开t0
    SEI();
 
 }
 

相关帖子

沙发
lhj200304| | 2008-3-31 15:12 | 只看该作者

抄来的

你这个程序八成是抄来的,根本没有好好去看 资料,中间都没有给 传感器留下转换时间,怎么会有数据呢 

使用特权

评论回复
板凳
cpu51|  楼主 | 2008-3-31 22:34 | 只看该作者

是的,你对了,我改了。

使用特权

评论回复
地板
jxb163| | 2008-4-5 20:34 | 只看该作者

用的是IAR编译器??

使用特权

评论回复
5
maweimin| | 2008-4-11 15:24 | 只看该作者

ds18b20,读写程序,

/*ds18b20,读写程序,这里以8M晶体为例,不同的晶体速度可能需要调整
延时的时间*/

#include "..ucos_iiincludes.h"

#if ds18b20 > 0

#define DQ    PD7 //io口
#define    CLR_DS    PORTD&=~(1<<DQ)    //数据线强制拉低
#define    SET_DS    PORTD|= (1<<DQ)    //数据线强制拉高
#define    HLD_DS    DDRD |= (1<<DQ)    //Mega控制总线,DQ为输出
#define    RLS_DS    DDRD &=~(1<<DQ) //释放总线,DQ为输入
#define    STU_DS    (PIND&(1<<DQ))  //数据线的状态

#define ds_read_rom           0x33 //读命令64bit
#define ds_match_rom          0x55 //选择定位命令
#define ds_skip_rom           0xcc //跳过ROM序列号检测命令
#define ds_search_rom         0xf0 //查询命令
#define ds_alarm_search_rom   0xec //报警查询命令
#define ds_write_ram          0x4e //写入 2,3,4字节
#define ds_read_ram           0xbe //读出0-9
#define ds_copy_ram           0x48 //复制
#define ds_convert_tem        0x44 //开始转换
#define ds_eecall_eeprom      0xb8 //回调
#define ds_read_power_supply  0xb4 //读电源标志

const unsigned char ds[16]={0x00,0x06,0x13,0x19,0x25,0x31,0x38,0x44,
                    0x50,0x56,0x63,0x69,0x75,0x81,0x88,0x94};
/***********************************************************
* 函数名称:resetDS18B20()
* 功    能:ds18b20初始化
* 入口参数:无
* 出口参数:0xff存在,0x00不存在或者错误
* 全程变量: 无,for(k=4;k!=0;k--);//4*4*0.125=2us
***********************************************************/
unsigned char resetDS18B20(void)
{
  unsigned char i,k;
    i=0x00;
    asm("cli");
    HLD_DS;    //Maga控制总线,DIR:output
    CLR_DS;    //强制拉低,并且等待480~960us--600us
    for(k=240;k!=0;k--);//120us
    for(k=240;k!=0;k--);//120us
    for(k=240;k!=0;k--);//120us
    for(k=240;k!=0;k--);//120us
    SET_DS;
    RLS_DS;                 //释放总线,总线自动上拉
    //设置DIO=1,等待15~60us,如果DS18B20有应答,不会超过60us就将DIO拉低,
    //如果超过60us,DIO还是保持高电平,则表示有错误!
    for(k=120;k!=0;k--);//60us
    if(!(STU_DS))       //have a ACK
    {
     //等待DS18B20应答信号(低电平)过去,这个应答信号在60~240us
     //如果超时(大于240us),并且DIO还保持低电平,表示错误!
      asm("sei");
      for(k=250;k!=0;k--);//125us
      for(k=250;k!=0;k--);//125us
      if(STU_DS)
         i=0xff;        
      }
     asm("sei");
     return i;
}
/***********************************************************
* 函数名称:readByteDS18B20()
* 功    能:从ds18b20读一个字节
* 入口参数:无
* 出口参数:所读字节
* 全程变量: 
***********************************************************/
unsigned char readByteDS18B20(void)
{
    unsigned char i,k;
    unsigned char retVal=0;
    HLD_DS;    //Maga控制总线   DIR:output
    for(i=8;i!=0;i--)
    {
         retVal>>=1;
        //生成读时间隙
        //延迟时间必须要大于1us
        asm("cli");
      HLD_DS;    //Maga控制总线   DIR:output
        CLR_DS;    //强制拉低         DATA:0
        for(k=4;k!=0;k--);//2us 
        //释放总线,让DS18B20确定总线状态    
        //DS18B20输出数据在生成读时间隙至15us内有效                
        SET_DS;    //DATA=1,上拉电阻有效
        RLS_DS;       //释放总线,DS18B20会将总线强制拉低,DIR:input
        for(k=4;k!=0;k--);//2us  
        if(STU_DS)
             retVal|=0x80;
         //读取一位数据必须至少要求大于60us
        asm("sei");
        for(k=120;k!=0;k--);//60us
    }    
  SET_DS;    //DATA=1,上拉电阻有效
  RLS_DS;      //释放总线,DS18B20会将总线强制拉低,DIR:input
  return(retVal);
}
/***********************************************************
* 函数名称:writeByteDS18B20()
* 功    能:向ds18b20写一个字节
* 入口参数:所写字节
* 出口参数:无
* 全程变量: 
***********************************************************/
void writeByteDS18B20(unsigned char wb)
{
//从第0位到第7位,依次从总线发送出去
//如果将要发送的位是1,则先将总线拉低,持续时间大于1us,小于15us
//然后再将总线拉高,维持时间大于60us,小于120us
    unsigned char i,k;
    for(i=8;i!=0;i--)
    {   
        asm("cli");
        HLD_DS;        //DIR:output
        CLR_DS;        //强制拉低,DATA=0
        for(k=4;k!=0;k--);//2us
        if(wb & 0x01)
          SET_DS;        //DATA=1
        //输出一位之后,维持时间大于60us,小于120us
        for(k=120;k!=0;k--);//60us
        //输出下一位时候,先将总线拉高,维持时间大于1us,小于无穷大
      SET_DS;            //DATA=1
    RLS_DS;            //释放总线,DIR:input,上拉
        asm("sei");
        for(k=4;k!=0;k--);//2us        
        wb>>=1;
    }     
    SET_DS;            //DATA=1,上拉
  RLS_DS;           //释放总线,DIR:input

/***********************************************************
* 函数名称:readTempDS18B20()
* 功    能:读ds18b20的温度
* 入口参数:无
* 出口参数:温度值(两个字节),0xeeee表示无ds18b20
* 全程变量: 
***********************************************************/
unsigned int readTempDS18B20(void)
{
     unsigned int Temp;
    if(resetDS18B20())
    {
       writeByteDS18B20(ds_skip_rom);        //跳过ROM
       writeByteDS18B20(ds_convert_tem);   //启动温度转换 750ms
       //延时750ms
  }
  else
      return(0xeeee); //无DS18B20
    
    if(resetDS18B20())
    {
       writeByteDS18B20(ds_skip_rom);    //跳过ROM
       writeByteDS18B20(ds_read_ram);    //读数据
       //先低后高
       Temp=readByteDS18B20()+(unsigned int)(readByteDS18B20()<<8);
  }
  else
    return(0xeeee); //无DS18B20
    return(Temp);
}
#endif

使用特权

评论回复
6
paulful| | 2013-6-20 20:33 | 只看该作者
我也遇到了问题,读出来的是ffff,楼主,我能向你请教一下问题吗?麻烦留我一个qq

使用特权

评论回复
7
qin552011373| | 2013-6-20 22:51 | 只看该作者
我在另外一个贴子里贴上了程序  

使用特权

评论回复
8
wentao0100| | 2013-7-3 22:48 | 只看该作者
调试DS18b20最好有个示波器,能够调试延时时间,这个很重要的。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

98

主题

458

帖子

0

粉丝