lcp2103怎么成功读取ds18b20温度值

2019-07-16 10:39发布

大家好,有用lpc2103成功读取ds18b20温度值的没,有的话发一个程序分享一下.谢谢
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
6条回答
blackliu
2019-07-17 01:33
我在IAR环境下写的程序,片子是LPC2103的,验证能读出,给你参考下。

/*****************************************************************************************


名称:DS18B20测温
功能:GPIO口实现温度测量功能

**********************************************************************************************************/
#include"config.h"
#define    DQ  1 << 19

/*************************************************
初始化
**************************************************
void F_18B20_IO_Initial()
{
PINSEL1 |= 0x00;   //定义P0.16为低速GPIO

IO0DIR &= (~DQ); //默认P0.16为输入口
}
*/

/*********************************************************************************************************
** Function name:   Delaynus
** Descriptions:   延时函数,传递参数为1时大约延时1us
** Input parameters:    uiDly
** Output parameters:   无
*********************************************************************************************************/
void Delaynus1(U32 uiDly)
{
U32 i;
for(;uiDly>0;uiDly--)
   for(i=0;i<5;i++);
}
/************************************************
                DS18b20初始化
************************************************/
U8 F_DS18B20_Reset()
{
U8 uiTimeCnt,uiIOValue;
IO0DIR = IO0DIR | DQ;                   //DQ设置为输出


IO0SET = IO0SET | DQ;                   //DQ = 1;    //DQ复位
Delaynus1(10);                        //稍做延时

  
IO0CLR = IO0CLR | DQ;                   // 将DQ拉低
Delaynus1(600);                          //精确延时 大于 480us 小于960us
IO0SET = DQ;                            //主机释放单总线                  // DQ = 1;        //拉高总线
Delaynus1(50);                           //15~60us 后 接收60-240us的存在脉冲

for(uiTimeCnt=0;uiTimeCnt<5;uiTimeCnt++) //输出60-240us低电平作为应答脉冲
  {
   uiIOValue = IO0PIN;
   uiIOValue &= DQ;

   if(uiIOValue)        //读入1,复位错误,返回
   {
      return 0;
   }  
   
  }
   Delaynus1(400);         //复位需要,和上次的应答低脉冲之和至少480us,否则复位错误
   
     return 1;
  

}



/********************************************
向DS18B20写入0
********************************************/
void F_DS18B20_Write_0()
{
PINSEL1 = 0x00000000;
IO0DIR = IO0DIR | DQ ;                //DQ设为输出口
IO0CLR = DQ;                          //拉低总线
Delaynus1(60);                        //写0就一直拉低到写周期结束
IO0SET = DQ;    //主机释放单总线                          //释放总线

}
/********************************************
向DS18B20写1
*********************************************/
void F_DS18B20_Write_1()
{
PINSEL1 = 0x00000000;
IO0DIR = IO0DIR | DQ;                //DQ为输出口
IO0CLR = DQ;                         //拉低总线1微秒
Delaynus1(5);                         //写周期开始
IO0SET = DQ;    //主机释放单总线                         //拉高总线120微秒到写周期结束,写1
Delaynus1(50);
}

/*******************************************
写入一个字节
********************************************/
void WriteOneChar(U8 WriteData)
{
U8 i=0;
for(i=0;i<8;i++)
{
  if(WriteData&0x01)
    F_DS18B20_Write_1();
  else
    F_DS18B20_Write_0();
  WriteData >>= 1;
}  
}
/******************************************
主机读时序
*******************************************/
U32 F_DS18B20_ReadDQ()
{
  U32 uiTemp = 0;
  PINSEL1 = 0x00000000;
  IO0DIR = IO0DIR | DQ;    // DQ为输出口
  IO0CLR = DQ;
  Delaynus1(5);
  IO0SET = DQ;    //主机释放单总线             //拉低1毫秒后拉高,开始读
  Delaynus1(3);
  
  uiTemp=IO0PIN;
  Delaynus1(60);
  uiTemp &= DQ;          //读DQ状态
  return(uiTemp);
}


/********************************************
读取一个字节
*******************************************/
U16 ReadOneChar()
{
U16 i;
U16 dat = 0;
for(i=0;i<8;i++)
  {
   dat>>=1;
   if(F_DS18B20_ReadDQ())
   dat |= 0x80;
   }
  
return dat;
}

/***********************************************************************
**开始测温
***********************************************************************/
float F_DS18B20_Start()
{
U16 uiTemp;
U16 uiData[9];
fp32 fTemp = 0.0;
if(F_DS18B20_Reset())
{
   WriteOneChar(0xcc);          //Skip ROM,单点总线系统,不需读取分辨
   /*WriteOneChar(0x7f);*/
   WriteOneChar(0x44);          //Start one convert
   while(F_DS18B20_ReadDQ()==0);       //启动后发送读操作,若器件忙于温度转化则输出0,转化完毕输出1
   F_DS18B20_Reset();        //一次完整操作包括初始化,ROM操作,存储器和控制操作,处理数据四步,每次都要遵循该流程
   Delaynus1(1000);
   WriteOneChar(0xcc);          //Skip ROM
   /*WriteOneChar(0x1f);*/
   WriteOneChar(0xBE);          //Read Scratchpad,读缓冲寄存器
  for(uiTemp=0;uiTemp<9;uiTemp++)
  uiData[uiTemp] = ReadOneChar();
  uiTemp=((uiData[1]<<8) | uiData[0] ); //缓冲存储器中的Byte0、1数据为测得的温度信息,以16位补码形式存放
  if(uiTemp & 0x8000)
    uiTemp=(~uiTemp)+1;
    uiTemp=uiTemp/16.0;
    fTemp=(float)uiTemp;
    fTemp=fTemp/16.0;
}
return fTemp;

}



一周热门 更多>