关于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条回答
随风xsl
1楼-- · 2019-07-16 20:39
就这点程序,也看不出来啊
zhxing001
2楼-- · 2019-07-17 00:51
 精彩回答 2  元偷偷看……
zhxing001
3楼-- · 2019-07-17 04:10
随风xsl 发表于 2016-4-14 10:55
就这点程序,也看不出来啊

谢谢回复,可是这就是完整的程序啊,拿示波器试的时候写时序当写非0x00和0xff的时候就会出现点评不确定的情况,不知道是什么原因……
zhxing001
4楼-- · 2019-07-17 07:02
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);             //右移一位等待发送
   }                          
}
好消息是问题解决了,写时序的时候时序出了点问题,上面的程序循环里的第一句方在循环的最后就正常了,具体还没看为什么原来的写法不对,宗旨谢谢大家的建议,祝好!

一周热门 更多>