8346|11

20

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

请教DS18B20初始化失败,用MSP430F149单片机 [复制链接]

刚开始学习MSP430单片机,参考网上修改的程序, DS18B20总是初始化失败,端口读入的值总是FFFF。延时用示波器测的,满足500,改为600US也不好用,请教各位达人,可能是什么原因,谢谢。

 /***************DS18B20 Reset&Init*********************/
void Reset_18B20(void)
{
   int zxc;
   P4DIR|=0x01 ;
   OUT_0;//Set output 0  主机首先发出一个480-960微秒的低电平脉冲
    DelayNus(70);  //500us
   OUT_1; //释放数据线(将数据线拉高)
   DelayNus(10);  //90us
   P4DIR&=~BIT0;   //BIT0=0X01  P4.0=input
   zxc=P4IN;
   if((P4IN&BIT0)==BIT0) 
   {   Err_Flag=1;     }  //失败,一直都是高电平说明总线上无器件应答
   else 
   {
     Err_Flag=0; // 有低电平出现说明总线上有器件已做出应答
     OUT_1;
   }
   P4DIR|=BIT0 ;  //BIT0=0X01  P4.0=output
  
}

[ 本帖最后由 黑加仑 于 2011-6-17 09:54 编辑 ]

最新回复

是的,分享一下经验。   详情 回复 发表于 2023-8-21 22:58
 
点赞 关注(1)

回复
举报

2130

帖子

0

TA的资源

五彩晶圆(中级)

沙发
 
更换上拉电阻
 
 

回复

20

帖子

0

TA的资源

一粒金砂(中级)

板凳
 

回复 沙发 leang521 的帖子

现在初始化OK,但读出来的数据仍然是FFFF.

我是外接的8M晶振,上拉电阻为4.7K,你的意思我的上拉电阻太大了吗?

下面是我的程序

#include"msp430x14x.h"

/*****************DS18B20**************************/
/***************P4.0-DS18B20**********************/
#define OUT_0 P4OUT&=~BIT0   //BIT0=0X01  P4.0=0  
#define OUT_1 P4OUT|=BIT0   //BIT0=0X01  P4.0=1  

unsigned char Err_Flag=1;
int temperature;
float Temper;

void Init_IO(void);
void Reset_18B20(void);
void Write_cmd(unsigned char cmd);
unsigned char Read_data(void);
void GetTemp(void);
void ReadTemp(void);
void DelayNus(unsigned int n);
/************************************************************/
void main()
{
  WDTCTL = WDTPW + WDTHOLD;             // Stop watchdog timer
  P3SEL|=BIT4;                         //SET P3.4  UTXD0
  P4DIR|=BIT0 ;  //BIT0=0X01  P4.0=output
  
   while(1)
   {
    GetTemp();
   }
}


/***************DS18B20 Reset&Init*********************/
void Reset_18B20(void)
{
  
   while( Err_Flag==1)
   {
   P4DIR|=0x01 ;
   OUT_0;//Set output 0  主机首先发出一个480-960微秒的低电平脉冲
   DelayNus(50);  //500us
   OUT_1; //释放数据线(将数据线拉高)
   DelayNus(6);  //60us
   P4DIR&=~BIT0;   //BIT0=0X01  P4.0=input
   

   if((P4IN&BIT0)==BIT0)  
   {   Err_Flag=1;     }  //失败,一直都是高电平说明总线上无器件应答
   else  
   {
     Err_Flag=0; // 有低电平出现说明总线上有器件已做出应答
     OUT_1;
   }
   }
   P4DIR|=BIT0 ;  //BIT0=0X01  P4.0=output
   
}
/******************Get Temperature*******************/
void GetTemp(void)
{
   Reset_18B20();
   Write_cmd(0xcc);  //跳过ROM
   Write_cmd(0x44);  //温度变换,结果存入内部9字节RAM中去
   DelayNus(60000);
   DelayNus(60000);
   DelayNus(60000);//延时1S以上
   Reset_18B20();
   Write_cmd(0xcc);   
   Write_cmd(0xBE);  //读暂存器,内部9字节RAM
   ReadTemp();
}
/*****************Read Temperature*******************/
void ReadTemp(void)
{
    char temp_low,temp_high; // 温度值
    int sign;
    temp_low=Read_data();//读低位
    temp_high=Read_data();//读高位
    if((temp_high&0xf8)==0xf8) //判断符号位   
    {
      char temp_mid=0xff;  // 前五位为1,温度为负,需取反+1
      sign=1;
      temp_mid&=~temp_high;  //高八位取反
      temperature=(temp_mid&0x0f);
      temp_mid=0xff;
      temp_mid&=~temp_low;//低八位取反
      temperature<<=8;
      temperature|=temp_mid;
      temperature+=0x0001;
    }
    else
    {
      sign=0;
    temperature=(temp_high&0x0f);
    temperature<<=8; //将高位移到高八位   (temperature16位)
    temperature|=temp_low;}
    Temper=(float)(temperature*0.0625);
}

/***************DS18B20 Write_cmd*********************/
//每个命令字节在写的时候都是低字节先写
//例如CCH的二进制为11001100,在写到总线上时00110011
void Write_cmd(unsigned char cmd)
{
    unsigned char i;
    for(i=0;i<8;i++)
    {
     OUT_0;
     DelayNus(1);//延时13us
     if((cmd&0x01)==0x01)   OUT_1; //利用与运算取出要写的某位二进制数据
     else OUT_0;
     cmd=cmd>>1; //右移   
     DelayNus(5);//延时50us
     OUT_1;
     P4DIR|=BIT0;
    }
}
/***************DS18B20 Read_data*********************/
unsigned char Read_data(void)
{
    unsigned char data,i;
    for(i=0;i<8;i++)
    {
      data=data>>1;
      OUT_0;
      _NOP(); //延时1us
    OUT_1; //读时隙是从主机把单总线拉低之后,在1微秒之后就得释放单总线为高电平
    _NOP();_NOP();_NOP();_NOP();_NOP(); //延时5us
      P4DIR&=~BIT0;  //输入
   
     if((P4IN&BIT0)==0) //利用与运算取出要写的某位二进制数据
       {data=data&0x7f;}
     else  {data=data|0x80;}
//     if(P4IN&BIT0)  data|=0x80;
       DelayNus(4);
       OUT_1;
       P4DIR|=BIT0;
       }
    return data;
}
/***************us级别延迟*********************/
//delay=n*5+6;  n=10,则延时10*5+6=56us
void DelayNus(unsigned int n)
{
  while(n--){};
}
/********************************************/
 
 
 

回复

2130

帖子

0

TA的资源

五彩晶圆(中级)

4
 
三线制还是两线制,上啦电阻多少。电压多少,
 
 
 

回复

20

帖子

0

TA的资源

一粒金砂(中级)

5
 

回复 4楼 leang521 的帖子

三线制,上拉电阻4.7K,电压都是3.3V,目前直接用仿真器供电
 
 
 

回复

20

帖子

0

TA的资源

一粒金砂(中级)

6
 

回复 4楼 leang521 的帖子

我刚才并上一个4.7K的电阻。结果读出来的数值还是FFFF
 
 
 

回复

1173

帖子

3

TA的资源

五彩晶圆(初级)

7
 
#include
typedef unsigned char uchar;
typedef unsigned int  uint;

#define DQ1 P1OUT |= BIT6
#define DQ0 P1OUT &= ~BIT6
#define DQ_in   P1DIR &= ~BIT6
#define DQ_out  P1DIR |= BIT6
#define DQ_val  (P1IN & BIT6)

/*******************************************
函数名称:DelayNus
功    能:实现N个微秒的延时
参    数:n--延时长度
返回值  :无
说明    :定时器A的计数时钟是1MHz,CPU主频8MHz
          所以通过定时器延时能够得到极为精确的
          us级延时
********************************************/
void DelayNus(uint n)
{
    CCR0 = n;
    TACTL |= MC_1;           //增计数到CCR0
    while(!(TACTL & BIT0));   //等待
    TACTL &= ~MC_1;          //停止计数
    TACTL &= ~BIT0;          //清除中断标志
}
/*******************************************
函数名称:Init_18B20
功    能:对DS18B20进行复位操作
参    数:无
返回值  :初始化状态标志:1--失败,0--成功
********************************************/
uchar Init_18B20(void)
{
    uchar Error;
   
    DQ_out;
    _DINT();
    DQ0;
    DelayNus(500);
    DQ1;
    DelayNus(55);
    DQ_in;
    _NOP();
    if(DQ_val)      
    {
        Error = 1;          //初始化失败
    }
    else
    {
        Error = 0;          //初始化成功
    }
    DQ_out;
    DQ1;
    _EINT();
   
    DelayNus(400);
   
    return Error;
}
/*******************************************
函数名称:Write_18B20
功    能:向DS18B20写入一个字节的数据
参    数:wdata--写入的数据
返回值  :无
********************************************/
void Write_18B20(uchar wdata)
{
    uchar i;
   
    _DINT();
    for(i = 0; i < 8;i++)
    {
        DQ0;
        DelayNus(6);            //延时6us
        if(wdata & 0X01)    DQ1;
        else                DQ0;
        wdata >>= 1;
        DelayNus(50);           //延时50us
        DQ1;
        DelayNus(10);           //延时10us
    }
    _EINT();
}
/*******************************************
函数名称:Read_18B20
功    能:从DS18B20读取一个字节的数据
参    数:无
返回值  :读出的一个字节数据
********************************************/
uchar Read_18B20(void)
{
    uchar i;
    uchar temp = 0;
   
    _DINT();
    for(i = 0;i < 8;i++)
    {
        temp >>= 1;
        DQ0;
        DelayNus(6);            //延时6us
        DQ1;
        DelayNus(8);            //延时9us
        DQ_in;
        _NOP();
        if(DQ_val)   temp |= 0x80;
        DelayNus(45);           //延时45us
        DQ_out;
        DQ1;
        DelayNus(10);           //延时10us
    }
    _EINT();
   
    return  temp;
}

/*******************************************
函数名称:Skip
功    能:发送跳过读取产品ID号命令
参    数:无
返回值  :无
********************************************/
void Skip(void)
{
    Write_18B20(0xcc);
}
/*******************************************
函数名称:Convert
功    能:发送温度转换命令
参    数:无
返回值  :无
********************************************/
void Convert(void)
{
    Write_18B20(0x44);
}
/*******************************************
函数名称:Read_SP
功    能:发送读ScratchPad命令
参    数:无
返回值  :无
********************************************/
void Read_SP(void)
{
    Write_18B20(0xbe);
}
/*******************************************
函数名称:ReadTemp
功    能:从DS18B20的ScratchPad读取温度转换结果
参    数:无
返回值  :读取的温度数值
********************************************/
uint ReadTemp(void)
{
    uchar temp_low;
    uint  temp;
   
    temp_low = Read_18B20();      //读低位
    temp = Read_18B20();     //读高位
    temp = (temp<<8) | temp_low;
   
    return  temp;
}
/*******************************************
函数名称:ReadTemp
功    能:控制DS18B20完成一次温度转换
参    数:无
返回值  :测量的温度数值
********************************************/
uint Do1Convert(void)
{
    uchar i;
   
    do
    {
        i = Init_18B20();
    }
    while(i);
    Skip();
    Convert();
    for(i = 20;i > 0;i--)  
        DelayNus(60000); //延时800ms以上
    do
    {
        i = Init_18B20();
    }
    while(i);
    Skip();
    Read_SP();
    return ReadTemp();
}
 
 
 

回复

20

帖子

0

TA的资源

一粒金砂(中级)

8
 

回复 7楼 ou513 的帖子

我接在P4.0口了,他不是没中断功能吗。 我用示波器侧过我的延时,当DelayNus(50);就是500US, 现在是我读的时序有问题吗?

 

在读数据时候,如果我只拉低后不释放,就一直读入的是0000,那是说明我的端口影响数据的输入吗?

[ 本帖最后由 黑加仑 于 2011-6-18 10:25 编辑 ]
 
 
 

回复

20

帖子

0

TA的资源

一粒金砂(中级)

9
 
重新修改了程序,已经OK

点评

请问楼主如何修改程序,我现在用IO模拟I2C,读取端口的时候总是高电平,但是示波器上已经是低电平了,不知道为什么状态不对啊。  详情 回复 发表于 2013-1-8 11:15
 
 
 

回复

94

帖子

0

TA的资源

一粒金砂(中级)

10
 

回复 9楼 黑加仑 的帖子

请问楼主如何修改程序,我现在用IO模拟I2C,读取端口的时候总是高电平,但是示波器上已经是低电平了,不知道为什么状态不对啊。
 
 
 

回复

7

帖子

0

TA的资源

一粒金砂(初级)

11
 
楼主,弄好了分享一下经验啊
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(中级)

12
 

是的,分享一下经验。

 
 
 

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

随便看看
查找数据手册?

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
快速回复 返回顶部 返回列表