关于ds18b20的问题,读到的数据全是1,求高手解答

2019-07-15 14:27发布

正在做毕设,单片机用的是飞思卡尔的jm60,程序写好后连接传感器就只能读出全是1来,我也不知道是发送的程序有问题还是接受的,或者是初始化的。延时函数都是用示波器看过的应该没问题。另外飞思卡尔的单片机需要设置i/o口是输入还是输出,设置为1是输出,0是输入。    有人用过dsb20的话还希望可以帮我看看,新手在这里谢过了!
                  #include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */
short i,j;

unsigned char Tem_h=0,Tem_l=0;
unsigned char x;
#define _nop_() _asm(nop);

/*函数声明----所有时钟测的是周期,所以时间应该是一半-----*/
void clkset();        //busclk=12m
void delay1s();       //上电延时函数,1s多
void delayms(int c);  //毫秒机延时 实测500ms
void delay10us();     //10us延时 实测5us
void DSset();
unsigned char Readonechar();
void Sendonechar(unsigned char date);
void delayus(int c);      //实测42(70)  1(4)   8(14)    28(46.8)  前面是c括号里是us数
void Read_tem(void);




/*子函数-----------------------------------*/
void delayus(int c)
{while(c--)
  {
  _nop_();_nop_();
  _nop_();_nop_();
  _nop_();_nop_();
  _nop_();_nop_();
  _nop_();_nop_();
   }
}


void delay10us()  //
{for(i=0;i<3;i++)
  { _nop_();
_nop_();_nop_();
_nop_();_nop_();
_nop_();_nop_();
_nop_();_nop_();
}
_nop_();
}

void delayms(int c)
{
for(i=0;i<c;i++)
for(j=0;j<490;j++)
{_nop_();
_nop_();
  }
}

void delay1s()
{for(i=0;i<1100;i++)
for(j=0;j<1200;j++)
{;
  }
}

void clkset()
{ MCGC2=0x36;      //选择外部振荡器和另外配置
while(!MCGSC_OSCINIT) ;  //振荡器稳定标志位
MCGC1=0xB8;       //选择外部参考。128分频
while(MCGSC_IREFST);      
while(MCGSC_CLKST!=2);   //外部参考时钟被选择
MCGC1=0x90;          // RDIV = 2; //0x90;  //RDIV = 4
MCGC3=0x46;          //0x46 24倍频; //0x44;//16倍频
while(!MCGSC_PLLST);
while(!MCGSC_LOCK);
MCGC1=0x08;      //切换到PLL  0x10;
while(MCGSC_CLKST!=3); //4/4*24=24m,busclk=12m
}


void DSset()
{x=1;
PTBDD_PTBDD4=1;
PTBD_PTBD4=1;      //设置成输出给高电平
delayus(1);             //延时4us
PTBD_PTBD4=0;    //拉低时钟线   
delayms(1);   
PTBD_PTBD4=1;     //保持500us左右给上升沿(实测494us)
delayus(1);                 //略作延时
PTBDD_PTBDD4=0;   //设置成输入口
delayus(42);          //延时70us用x去检测传感器返回的低电平
x=PTBD_PTBD4;     //x=0时初始化成功标志
delayus(1);
}             //看变量表示能看到想在1和0之间转换,应该初始化没有问题       



unsigned char Readonechar(void)     //读一个字节
{
  unsigned char date;
  for(i=0;i<8;i++)
  {PTBDD_PTBDD4=1;     //设置成输出
   PTBD_PTBD4=1;        //给高电平
   delayus(1);              //略延时
   PTBD_PTBD4=0;                    
   delayus(1);               //拉低保持4us
   PTBD_PTBD4=1;        //拉高总线           
   PTBDD_PTBDD4=0;    //设置成输入   
   date>>=1;               //移位
   delayus(1);                 
   if(PTBD_PTBD1)     //读:如果的是1的话这样取或就可以
   date|=0x80;

   delayus(30);        //保证每个周期至少60us以上,这里大概是50us
            }
  return date;
}


void Sendonechar(unsigned char date)
{   PTBDD_PTBDD4=1;//设置成输出

   for(i=0;i<8;i++)
   {PTBD_PTBD4=1;              
    delayus(1);                //给高电平,再略延时
    PTBD_PTBD4=0;
    delayus(8);                 //延时14us
    PTBD_PTBD4=date&(0x01);    //看给的数据是多少是0就还是0;            
    delayus(28);
                                //47us 保证60us
    date>>=1;                 
    delayus(1);             //右移一位等待发送
   }                          
}

void Read_tem(void)
{ DSset();                  //复位
  delayms(1);      
  Sendonechar(0xcc);
  Sendonechar(0x44);
                                 //温度转换命令

  delay1s();                //给温度转换的时间1s   
  DSset();
  delayms(1);                  
  Sendonechar(0xcc);
  Sendonechar(0xbe);
  Tem_h=Readonechar();
  Tem_l=Readonechar();

}




void main(void)
{
          EnableInterrupts; /* enable interrupts */
         /* include your code here */


          clkset();    //设置时钟
          SOPT1=0;         //关看门狗                 
          PTBDD_PTBDD4=1;
          PTBD_PTBD4=1;     //设置成输出并给高电平         
          PTBDD_PTBDD1=1;
          PTBD_PTBD1=1;               


   /*   for(;;)
          {
            delayus(28);
          PTBD_PTBD1=1;
            delayus(28);
          PTBD_PTBD1=0;
          }   */            //延时测试程序        

           for(;;)
          {delay1s();

           Read_tem();
           delay1s();
          }         


              //__RESET_WATCHDOG(); /* feeds the dog */
           /* loop forever */
  /* please make sure that you never leave main */
  }      








友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
10条回答
零tot
1楼-- · 2019-07-15 20:17
这个你可以先用示波器测一下你的这个时序是否正确,各个io设置是否是自己想象的那样,好久之前用这个传感器的时候出现过类似的问题最后就是一步步检测出来的,那时候好像是io输出输入模式转换的时候电平有问题导致不行的,具体的也记不清了你可以按照这个思路检查一下看看
zhxing001
2楼-- · 2019-07-15 20:43
零tot 发表于 2016-4-12 20:23
这个你可以先用示波器测一下你的这个时序是否正确,各个io设置是否是自己想象的那样,好久之前用这个传感器的时候出现过类似的问题最后就是一步步检测出来的,那时候好像是io输出输入模式转换的时候电平有问题导致不行的,具体的也记不清了你可以按照这个思路检查一下看看 ...

恩,我再看看,对这个输入输出设置转换时的电平变化确实拿不准,楼主还记的用什么方法解决的么?io转换结束马上给电平?
谢过了
V-CRAZY
3楼-- · 2019-07-16 01:07
 精彩回答 2  元偷偷看……
zhxing001
4楼-- · 2019-07-16 06:53
V-CRAZY 发表于 2016-4-13 10:04
硬件有没有问题

最新情况:程序里读的时候有个小问题已经解决了,可以读了,但是读出来的是默认的0550(85度),初始化也应该没问题,硬件我换了传感器也试过了,应该是没问题,估计还是发送rom程序的问题,有时间帮我看看发送的函数,谢过了
zhxing001
5楼-- · 2019-07-16 11:21
刚去拿示波器测了一下,发现应该是写时序的问题,写0x00和0xff的时候都还正常,但是写其他数的时候就会出现电平不确定的情况。 有人遇到过相同的情况么,如何解决啊? 谢过了
autumn_rain
6楼-- · 2019-07-16 15:03
zhxing001 发表于 2016-04-13 11:08
刚去拿示波器测了一下,发现应该是写时序的问题,写0x00和0xff的时候都还正常,但是写其他数的时候就会出现电平不确定的情况。 有人遇到过相同的情况么,如何解决啊? 谢过了

看不到你的完整程序,你可以把自己定义的变量改一下试试,改成无符号整形,把延时程序的变量也改改。unsigned int。

一周热门 更多>