• 3.8 ds18b20温度传感器实验


    DS18B20是常用的数字温度传感器,具有体积小,硬件开销低,抗干扰能力强,精度高的特点。DS18B20 单线数字温度传感器,即“一线器件”,其具有独特的优点:
    1,采用单总线的接口方式 与微处理器连接时仅需要一条口线即可实现微处理器与 DS18B20 的双向通讯。单总线具有经济性好,抗干扰能力强,适合于恶劣环境的现场温度测量,使用方便等优点,使用户可轻松地组建传感器网络,为测量系统的构建引入全新概念。
    2,测量温度范围宽,测量精度高 DS18B20 的测量范围为 -55 ℃ ~+ 125 ℃ ; 在 -10~+ 85°C范围内,精度为 ± 0.5°C 。
    3,在使用中不需要任何外围元件。
    4,持多点组网功能多个 DS18B20 可以并联在惟一的单线上,实现多点测温。
    5,供电方式灵活 DS18B20 可以通过内部寄生电路从数据线上获取电源。因此,当数据线上的时序满足一定的要求时,可以不接外部电源,从而使系统结构更趋简单,可靠性更高。
    6,测量参数可配置 DS18B20 的测量分辨率可通过程序设定 9~12 位。
    7,负压特性电源极性接反时,温度计不会因发热而烧毁。
    8,掉电保护功能 DS18B20 内部含有 EEPROM ,在系统掉电以后,它仍可保存分辨率及报警温度的设定值。
     DS18B20 具有体积更小、适用电压更宽、更经济、可选更小的封装方式,更宽的电压适用范围,适合于构建自己的经济的测温系统,因此也就被设计者们所青睐。
      DS18B20内部结构:
      主要由4部分组成:64 位ROM、温度传感器、非挥发的温度报警触发器TH和TL、配置寄存器。ROM中的64位序列号是出厂前被光刻好的,它可以看作是该DS18B20的地址序列码,每个DS18B20的64位序列号均不相同。64位ROM的排的循环冗余校验码(CRC=X8+X5+X^4+1)。 ROM的作用是使每一个DS18B20都各不相同,这样就可以实现一根总线上挂接多个DS18B20的目的。
    首先创建读取ds18b20的任务:

    define TASK_SIZE 256

    static OS_STK ds18b20_task_stk[TASK_SIZE];
    void UserMain(void)
    {

    tls_os_task_create(NULL, NULL,
    ds18b20_task,
    NULL,
    (void *)ds18b20_task_stk,
    TASK_SIZE * sizeof(u32),
    32,
    0);
    }
    在任务中初始化DS18B20,并获取DS18B20序列号后读取温度值。
    static void ds18b20_task(void *data)
    {
    uint8_t uc, ucDs18b20Id [ 8 ];
    int i;
    printf(" this is a ds18b20 test demo ");

    while( DS18B20_Init() )
    {
    	for(i=0;i<1000;i++)
    	{
    		us_delay(1000);
    	}
    
    
    printf("
     ds18b20 exit 
    ");
    }
    printf("
     ds18b20 ok  
    ");
     DS18B20_ReadId ( ucDs18b20Id  );           // 读取 DS18B20 的序列号
    
     printf("
    DS18B20: 0x");
    
     for ( uc = 0; uc < 8; uc ++ )             // 打印 DS18B20 的序列号
      printf ( "%.2x", ucDs18b20Id [ uc ] );
    
    for( ; ; )
    {
    
    	 printf ( "
    temperature: %.1f
    ", DS18B20_GetTemp_MatchRom ( ucDs18b20Id ) );		// 打印通过 DS18B20 序列号获取的温度值
    	 DS18B20_DELAY_MS(1000);
    }
    

    }
    其它函数:

    /**

    • @brief DS18B20 初始化函数

    • @param 无

    • @retval 无
      */
      uint8_t DS18B20_Init(void)
      {
      DS18B20_GPIO_Config ();

      DS18B20_DQ_1;

      DS18B20_Rst();

    return DS18B20_Presence ();

    }
    /*

    • 函数名:DS18B20_GPIO_Config

    • 描述 :配置DS18B20用到的I/O口

    • 输入 :无

    • 输出 :无
      */
      static void DS18B20_GPIO_Config(void)
      {

      tls_gpio_cfg(DS18B20_DQ_GPIO_PORT, WM_GPIO_DIR_OUTPUT, WM_GPIO_ATTR_PULLHIGH);//配置为上拉输出
      }

    /*

    • 函数名:DS18B20_Mode_IPU
    • 描述 :使DS18B20-DATA引脚变为输入模式
    • 输入 :无
    • 输出 :无
      */
      static void DS18B20_Mode_IPU(void)
      {
      tls_gpio_cfg(DS18B20_DQ_GPIO_PORT, WM_GPIO_DIR_INPUT, WM_GPIO_ATTR_FLOATING);//配置为上拉输出
      }

    /*

    • 函数名:DS18B20_Mode_Out_PP
    • 描述 :使DS18B20-DATA引脚变为输出模式
    • 输入 :无
    • 输出 :无
      */
      static void DS18B20_Mode_Out_PP(void)
      {
      tls_gpio_cfg(DS18B20_DQ_GPIO_PORT, WM_GPIO_DIR_OUTPUT, WM_GPIO_ATTR_PULLHIGH);//配置为上拉输出
      }

    /*
    *主机给从机发送复位脉冲
    /
    static void DS18B20_Rst(void)
    {
    /
    主机设置为推挽输出 */
    DS18B20_Mode_Out_PP();

    DS18B20_DQ_0;
     /* 主机至少产生480us的低电平复位信号 */
     us_delay(750);
    
     /* 主机在产生复位信号后,需将总线拉高 */
     DS18B20_DQ_1;
    
     /*从机接收到主机的复位信号后,会在15~60us后给主机发一个存在脉冲*/
     us_delay(15);
    

    }

    /*

    • 检测从机给主机返回的存在脉冲

    • 0:成功

    • 1:失败
      */
      static uint8_t DS18B20_Presence(void)
      {
      uint8_t pulse_time = 0;

      /* 主机设置为上拉输入 */
      DS18B20_Mode_IPU();

      /* 等待存在脉冲的到来,存在脉冲为一个60~240us的低电平信号

      • 如果存在脉冲没有来则做超时处理,从机接收到主机的复位信号后,会在15~60us后给主机发一个存在脉冲
        /
        while( DS18B20_DQ_IN() && pulse_time<100 )
        {
        pulse_time++;
        us_delay(1);
        }
        /
        经过100us后,存在脉冲都还没有到来*/
        if( pulse_time >=100 )
        return 1;
        else
        pulse_time = 0;

      /* 存在脉冲到来,且存在的时间不能超过240us */
      while( !DS18B20_DQ_IN() && pulse_time<240 )
      {
      pulse_time++;
      us_delay(1);
      }
      if( pulse_time >=240 )
      return 1;
      else
      return 0;
      }

    /*

    • 从DS18B20读取一个bit
      */
      static uint8_t DS18B20_ReadBit(void)
      {
      uint8_t dat;

      /* 读0和读1的时间至少要大于60us /
      DS18B20_Mode_Out_PP();
      /
      读时间的起始:必须由主机产生 >1us <15us 的低电平信号 */
      DS18B20_DQ_0;
      us_delay(10);

      /* 设置成输入,释放总线,由外部上拉电阻将总线拉高 */
      DS18B20_Mode_IPU();
      //us_delay(2);

      if( DS18B20_DQ_IN() == SET )
      dat = 1;
      else
      dat = 0;

      /* 这个延时参数请参考时序图 */
      us_delay(45);

      return dat;
      }

    /*

    • 从DS18B20读一个字节,低位先行
      */
      static uint8_t DS18B20_ReadByte(void)
      {
      uint8_t i, j, dat = 0;

      for(i=0; i<8; i++)
      {
      j = DS18B20_ReadBit();
      dat = (dat) | (j<<i);
      }

      return dat;
      }

    /*

    • 写一个字节到DS18B20,低位先行
      */
      static void DS18B20_WriteByte(uint8_t dat)
      {
      uint8_t i, testb;
      DS18B20_Mode_Out_PP();

      for( i=0; i<8; i++ )
      {
      testb = dat&0x01;
      dat = dat>>1;
      /* 写0和写1的时间至少要大于60us /
      if (testb)
      {
      DS18B20_DQ_0;
      /
      1us < 这个延时 < 15us */
      us_delay(8);

       	DS18B20_DQ_1;
       	us_delay(58);
       }
       else
       {
       	DS18B20_DQ_0;
       	/* 60us < Tx 0 < 120us */
       	us_delay(70);
      
       	DS18B20_DQ_1;
       	/* 1us < Trec(恢复时间) < 无穷大*/
       	us_delay(2);
       }
      

      }
      }

    /**

    • @brief 跳过匹配 DS18B20 ROM

    • @param 无

    • @retval 无
      */
      static void DS18B20_SkipRom ( void )
      {
      DS18B20_Rst();

      DS18B20_Presence();

      DS18B20_WriteByte(0XCC); /* 跳过 ROM */

    }

    /**

    • @brief 执行匹配 DS18B20 ROM

    • @param 无

    • @retval 无
      */
      static void DS18B20_MatchRom ( void )
      {
      DS18B20_Rst();

      DS18B20_Presence();

      DS18B20_WriteByte(0X55); /* 匹配 ROM */

    }

    /*

    • 存储的温度是16 位的带符号扩展的二进制补码形式

    • 当工作在12位分辨率时,其中5个符号位,7个整数位,4个小数位

    •     |---------整数----------|-----小数 分辨率 1/(2^4)=0.0625----|
      
    • 低字节 | 2^3 | 2^2 | 2^1 | 2^0 | 2^(-1) | 2^(-2) | 2^(-3) | 2^(-4) |

    •     |-----符号位:0->正  1->负-------|-----------整数-----------|
      
    • 高字节 | s | s | s | s | s | 2^6 | 2^5 | 2^4 |

    • 温度 = 符号位 + 整数 + 小数*0.0625
      /
      /
      *

    • @brief 在跳过匹配 ROM 情况下获取 DS18B20 温度值

    • @param 无

    • @retval 温度值
      */
      float DS18B20_GetTemp_SkipRom ( void )
      {
      uint8_t tpmsb, tplsb;
      short s_tem;
      float f_tem;

      DS18B20_SkipRom ();
      DS18B20_WriteByte(0X44); /* 开始转换 */

      DS18B20_SkipRom ();
      DS18B20_WriteByte(0XBE); /* 读温度值 */

      tplsb = DS18B20_ReadByte();
      tpmsb = DS18B20_ReadByte();

      s_tem = tpmsb<<8;
      s_tem = s_tem | tplsb;

      if( s_tem < 0 ) /* 负温度 */
      f_tem = (~s_tem+1) * 0.0625;
      else
      f_tem = s_tem * 0.0625;

      return f_tem;

    }

    /**

    • @brief 在匹配 ROM 情况下获取 DS18B20 温度值

    • @param ds18b20_id:用于存放 DS18B20 序列号的数组的首地址

    • @retval 无
      */
      void DS18B20_ReadId ( uint8_t * ds18b20_id )
      {
      uint8_t uc;

      DS18B20_WriteByte(0x33); //读取序列号

      for ( uc = 0; uc < 8; uc ++ )
      ds18b20_id [ uc ] = DS18B20_ReadByte();

    }

    /**

    • @brief 在匹配 ROM 情况下获取 DS18B20 温度值

    • @param ds18b20_id:存放 DS18B20 序列号的数组的首地址

    • @retval 温度值
      */
      float DS18B20_GetTemp_MatchRom ( uint8_t * ds18b20_id )
      {
      uint8_t tpmsb, tplsb, i;
      short s_tem;
      float f_tem;

      DS18B20_MatchRom (); //匹配ROM

    for(i=0;i<8;i++)
    DS18B20_WriteByte ( ds18b20_id [ i ] );

    DS18B20_WriteByte(0X44);				/* 开始转换 */
    
    
    DS18B20_MatchRom ();            //匹配ROM
    
    for(i=0;i<8;i++)
    	DS18B20_WriteByte ( ds18b20_id [ i ] );
    
    DS18B20_WriteByte(0XBE);				/* 读温度值 */
    
    tplsb = DS18B20_ReadByte();
    tpmsb = DS18B20_ReadByte();
    
    
    s_tem = tpmsb<<8;
    s_tem = s_tem | tplsb;
    
    if( s_tem < 0 )		/* 负温度 */
    	f_tem = (~s_tem+1) * 0.0625;
    else
    	f_tem = s_tem * 0.0625;
    
    return f_tem;
    

    }
    编译下载到开发板运行:

  • 相关阅读:
    C语言文件
    java课程设计-彩票购买抽奖程序
    面向对象设计大作业——图书馆
    有理数类设计
    图总结
    编译器、编辑器、文件、IDE等常见概念辨析
    树、二叉树、查找算法总结
    互评:数据结构、算法及线性表总结
    c语言文件
    第二次博客园作业
  • 原文地址:https://www.cnblogs.com/doiting/p/14108991.html
Copyright © 2020-2023  润新知