精华内容
下载资源
问答
  • STM32 HAL库 DS18B20读取温度值

    千次阅读 2019-11-01 15:41:07
    HAL库DS18B20读取温度值程序代码 1、头文件 #ifndef __DS18B20_H #define __DS18B20_H #include "main.h" #include "stdio.h" typedef uint8_t u8; typedef uint16_t u16; typedef uint32_t u32; //IO方向设置 ...

    HAL库DS18B20读取温度值程序代码

    我是用的是STM32F103RB,时钟主频72M。18b20端口使用PA0,配置该端口为推挽输出即可。
    注意:驱动单总线器件时序上是很简单的,如果是使用HAL库,关键点在于微秒的延时的准确性。


    扫描以下二维码,关注公众号雍正不秃头获取更多STM32资源及干货!
    在这里插入图片描述


    DS18B20.H

    #ifndef __DS18B20_H
    #define __DS18B20_H 
    
    #include "main.h"
    
    #define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
    #define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr))
    #define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum))
    
    #define GPIOA_ODR_Addr    (GPIOA_BASE+12)
    #define GPIOB_ODR_Addr    (GPIOB_BASE+12)
    #define GPIOC_ODR_Addr    (GPIOC_BASE+12)
    #define GPIOD_ODR_Addr    (GPIOD_BASE+12)
    #define GPIOE_ODR_Addr    (GPIOE_BASE+12)
    #define GPIOF_ODR_Addr    (GPIOF_BASE+12)
    #define GPIOG_ODR_Addr    (GPIOG_BASE+12)
    
    #define GPIOA_IDR_Addr    (GPIOA_BASE+8)
    #define GPIOB_IDR_Addr    (GPIOB_BASE+8)
    #define GPIOC_IDR_Addr    (GPIOC_BASE+8)
    #define GPIOD_IDR_Addr    (GPIOD_BASE+8)
    #define GPIOE_IDR_Addr    (GPIOE_BASE+8)
    #define GPIOF_IDR_Addr    (GPIOF_BASE+8)
    #define GPIOG_IDR_Addr    (GPIOG_BASE+8)
    
    #define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)
    #define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)
    
    #define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)
    #define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)
    
    #define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr,n)
    #define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)
    
    #define PDout(n)   BIT_ADDR(GPIOD_ODR_Addr,n)
    #define PDin(n)    BIT_ADDR(GPIOD_IDR_Addr,n)
    
    #define PEout(n)   BIT_ADDR(GPIOE_ODR_Addr,n)
    #define PEin(n)    BIT_ADDR(GPIOE_IDR_Addr,n)
    
    #define PFout(n)   BIT_ADDR(GPIOF_ODR_Addr,n)
    #define PFin(n)    BIT_ADDR(GPIOF_IDR_Addr,n)
    
    #define PGout(n)   BIT_ADDR(GPIOG_ODR_Addr,n)
    #define PGin(n)    BIT_ADDR(GPIOG_IDR_Addr,n)
    
    
    //IO方向设置
    #define DS18B20_IO_IN()  {GPIOA->CRL&=0XFFFFFFF0;GPIOA->CRL|=8<<0;}
    #define DS18B20_IO_OUT() {GPIOA->CRL&=0XFFFFFFF0;GPIOA->CRL|=3<<0;}
    
    //IO操作函数
    #define	DS18B20_DQ_OUT PAout(0) //数据端口	PA0
    #define	DS18B20_DQ_IN  PAin(0)  //数据端口	PA0 
       	
    uint8_t DS18B20_Init(void);			//初始化DS18B20
    short DS18B20_Get_Temp(void);		//获取温度
    void DS18B20_Start(void);			//开始温度转换
    void DS18B20_Write_Byte(uint8_t dat);//写入一个字节
    uint8_t DS18B20_Read_Byte(void);	//读出一个字节
    uint8_t DS18B20_Read_Bit(void);		//读出一个位
    uint8_t DS18B20_Check(void);		//检测是否存在DS18B20
    void DS18B20_Rst(void);				//复位DS18B20
    #endif
    
    

    DS18B20.C

    #include "ds18b20.h"
    
    static inline void delay_ms(uint32_t delay)
    {
    	HAL_Delay(delay);
    }
    
    #define CPU_FREQUENCY_MHZ 72				// CPU主频,根据实际进行修改
    static void delay_us(uint32_t delay)
    {
    	int last, curr, val;
    	int temp;
    
    	while (delay != 0)
    	{
    		temp = delay > 900 ? 900 : delay;
    		last = SysTick->VAL;
    		curr = last - CPU_FREQUENCY_MHZ * temp;
    		if (curr >= 0)
    		{
    			do
    			{
    				val = SysTick->VAL;
    			}
    			while ((val < last) && (val >= curr));
    		}
    		else
    		{
    			curr += CPU_FREQUENCY_MHZ * 1000;
    			do
    			{
    				val = SysTick->VAL;
    			}
    			while ((val <= last) || (val > curr));
    		}
    		delay -= temp;
    	}
    }
    
    //复位DS18B20
    void DS18B20_Rst(void)	   
    {                 
    	DS18B20_IO_OUT(); //SET PA0 OUTPUT
        DS18B20_DQ_OUT=0; //拉低DQ
        delay_us(750);    //拉低750us
        DS18B20_DQ_OUT=1; //DQ=1 
    	delay_us(15);     //15US
    }
    //等待DS18B20的回应
    //返回1:未检测到DS18B20的存在
    //返回0:存在
    uint8_t DS18B20_Check(void)
    {   
    	uint8_t retry=0;
    	DS18B20_IO_IN();//SET PA0 INPUT	 
        while (DS18B20_DQ_IN&&retry<200)
    	{
    		retry++;
    		delay_us(1);
    	};	 
    	if(retry>=200)return 1;
    	else retry=0;
        while (!DS18B20_DQ_IN&&retry<240)
    	{
    		retry++;
    		delay_us(1);
    	};
    	if(retry>=240)return 1;	    
    	return 0;
    }
    //从DS18B20读取一个位
    //返回值:1/0
    uint8_t DS18B20_Read_Bit(void) 			 // read one bit
    {
        uint8_t data;
    	DS18B20_IO_OUT();//SET PA0 OUTPUT
        DS18B20_DQ_OUT=0; 
    	delay_us(2);
        DS18B20_DQ_OUT=1; 
    	DS18B20_IO_IN();//SET PA0 INPUT
    	delay_us(12);
    	if(DS18B20_DQ_IN)data=1;
        else data=0;	 
        delay_us(50);           
        return data;
    }
    //从DS18B20读取一个字节
    //返回值:读到的数据
    uint8_t DS18B20_Read_Byte(void)    // read one byte
    {        
        uint8_t i,j,dat;
        dat=0;
    	for (i=1;i<=8;i++) 
    	{
            j=DS18B20_Read_Bit();
            dat=(j<<7)|(dat>>1);
        }						    
        return dat;
    }
    //写一个字节到DS18B20
    //dat:要写入的字节
    void DS18B20_Write_Byte(uint8_t dat)
     {             
        uint8_t j;
        uint8_t testb;
    	DS18B20_IO_OUT();//SET PA0 OUTPUT;
        for (j=1;j<=8;j++) 
    	{
            testb=dat&0x01;
            dat=dat>>1;
            if (testb) 
            {
                DS18B20_DQ_OUT=0;// Write 1
                delay_us(2);                            
                DS18B20_DQ_OUT=1;
                delay_us(60);             
            }
            else 
            {
                DS18B20_DQ_OUT=0;// Write 0
                delay_us(60);             
                DS18B20_DQ_OUT=1;
                delay_us(2);                          
            }
        }
    }
    //开始温度转换
    void DS18B20_Start(void)// ds1820 start convert
    {   						               
        DS18B20_Rst();	   
    	DS18B20_Check();	 
        DS18B20_Write_Byte(0xcc);// skip rom
        DS18B20_Write_Byte(0x44);// convert
    } 
    //初始化DS18B20的IO口 DQ 同时检测DS的存在
    //返回1:不存在
    //返回0:存在    	 
    uint8_t DS18B20_Init(void)
    {
    	DS18B20_Rst();
    	return DS18B20_Check();
    }  
    //从ds18b20得到温度值
    //精度:0.1C
    //返回值:温度值 (-550~1250) 
    short DS18B20_Get_Temp(void)
    {
        uint8_t temp;
        uint8_t TL,TH;
    	short tem;
        DS18B20_Start ();                    // ds1820 start convert
        DS18B20_Rst();
        DS18B20_Check();	 
        DS18B20_Write_Byte(0xcc);// skip rom
        DS18B20_Write_Byte(0xbe);// convert	    
        TL=DS18B20_Read_Byte(); // LSB   
        TH=DS18B20_Read_Byte(); // MSB  
    	    	  
        if(TH>7)
        {
            TH=~TH;
            TL=~TL; 
            temp=0;//温度为负  
        }else temp=1;//温度为正	  	  
        tem=TH; //获得高八位
        tem<<=8;    
        tem+=TL;//获得底八位
        tem=(float)tem*0.625;//转换     
    	if(temp)return tem; //返回温度值
    	else return -tem;    
    } 
     
    
    

    ends…

    展开全文
  • MSP430系列单片机具有超低功耗,且外围的整合高,DS18B20只需一个端口即可实现数据通信,连接方便。通过多次实验证明,该系统的测试结果与实际环境温度一致,除了具有接口电路简单、测量精度高、误差小、可靠...
  • 为了克服空调检测系统存在的布线复杂、温度采集稳定差的缺点,利用数字温度传感器DS18B20具有一线总线、可组网的特点,结合AT89S52单片机,给出一种用于空调检测系统的高效稳定的温度采集方案,讨论了16片DS18B20...
  • 针对传统的温度检测系统对于通信基站测温点少、检测实时性和准确性较低的问题。设计了一种基于DS18B20温度传感器关联性模型的温度检测系统,通过建立不同位置测温值的关联模型,实现对温度异变信号的声光报警和自动...
  • DS18B20 数字温度传感器实验

    千次阅读 2019-06-20 10:52:00
    DS18B20 数字温度传感器实验 STM32 虽然内部自带了温度传感器,但是因为芯片温升较大等问题,与实际温度差别较大,所以,本章我们将向大家介绍如何通过 STM32 来读取外部数字温度传感器的温度,来得到较为准确的环境...

    DS18B20 数字温度传感器实验

    STM32 虽然内部自带了温度传感器,但是因为芯片温升较大等问题,与实际温度差别较大,所以,本章我们将向大家介绍如何通过 STM32 来读取外部数字温度传感器的温度,来得到较为准确的环境温度。在本章中,我们将学习使用单总线技术,通过它来实现 STM32 和外部温度传感器( DS18B20)的通信,并把从温度传感器得到的温度显示在 TFTLCD 模块上。

    1 DS18B20 简介
    DS18B20 是由 DALLAS 半导体公司推出的一种的“一线总线”接口的温度传感器。与传统的热敏电阻等测温元件相比,它是一种新型的体积小、适用电压宽、与微处理器接口简单的数字化温度传感器。一线总线结构具有简洁且经济的特点,可使用户轻松地组建传感器网络,从而为测量系统的构建引入全新概念,测量温度范围为-55~+125℃ ,精度为±0.5℃。现场温度直接以“一线总线”的数字方式传输,大大提高了系统的抗干扰性。它能直接读出被测温度,并且可根据实际要求通过简单的编程实现 9~l2 位的数字值读数方式。它工作在 3~5.5V 的电压范围,采用多种封装形式,从而使系统设计灵活、方便,设定分辨率及用户设定的报警温度存储在 EEPROM 中,掉电后依然保存。

    ROM 中的 64 位序列号是出厂前被光记好的,它可以看作是该 DS18B20 的地址序列码,每DS18B20 的 64 位序列号均不相同。 64 位 ROM 的排列是:前 8 位是产品家族码,接着 48 位是DS18B20 的序列号,最后 8 位是前面 56 位的循环冗余校验码(CRC=X8+X5+X4+1)。 ROM 作用是使每一个 DS18B20 都各不相同,这样就可实现一根总线上挂接多个 DS18B20。
    所有的单总线器件要求采用严格的信号时序,以保证数据的完整性。 DS18B20 共有 6 种信号类型:复位脉冲、应答脉冲、写 0、写 1、读 0 和读 1。所有这些信号,除了应答脉冲以外,都由主机发出同步信号。并且发送所有的命令和数据都是字节的低位在前。 这里我们简单介绍这几个信号的时序:

    ①、 独特的单总线接口方式,DS18B20在与微处理器连接时仅需要一条口线即可实 现微处理器与DS18B20的双向通讯。大大提高了系统的抗干扰性。

    ② 、测温范围 -55℃~+125℃,精度为±0.5℃。

    ③、支持多点组网功能,多个DS18B20可以并联在唯一的三线上,最多只能并联8个,实现多点测温,如果数量过多,会使供电电源电压过低,从而造成信号传输的不稳定。

    ④、 工作电源: 3.0~5.5V/DC (可以数据线寄生电源)。

    ⑤ 、在使用中不需要任何外围元件。

    ⑥、 测量结果以9~12位数字量方式串行传送。

    1)复位脉冲和应答脉冲
    单总线上的所有通信都是以初始化序列开始。主机输出低电平,保持低电平时间至少 480us,,以产生复位脉冲。接着主机释放总线, 4.7K 的上拉电阻将单总线拉高,延时 15~60 us,并进入接收模式(Rx)。接着 DS18B20 拉低总线 60~240 us,以产生低电平应答脉冲,若为低电平,再延时 480 us。
    2)写时序
    写时序包括写 0 时序和写 1 时序。所有写时序至少需要 60us,且在 2 次独立的写时序之间至少需要 1us 的恢复时间,两种写时序均起始于主机拉低总线。写 1 时序:主机输出低电平,延时 2us,然后释放总线,延时 60us。写 0 时序:主机输出低电平,延时 60us,然后释放总线,延时 2us。
    3)读时序
    单总线器件仅在主机发出读时序时,才向主机传输数据,所以,在主机发出读数据命令后,必须马上产生读时序,以便从机能够传输数据。所有读时序至少需要 60us,且在 2 次独立的读时序之间至少需要 1us 的恢复时间。每个读时序都由主机发起,至少拉低总线 1us。主机在读时序期间必须释放总线,并且在时序起始后的 15us 之内采样总线状态。典型的读时序过程为:
    主机输出低电平延时 2us,然后主机转入输入模式延时 12us,然后读取单总线当前的电平,然后延时 50us。
    在了解了单总线时序之后,我们来看看 DS18B20 的典型温度读取过程, DS18B20 的典型温度读取过程为:复位发 SKIP ROM 命令( 0XCC) 发开始转换命令( 0X44) 延时复位发送 SKIP ROM 命令( 0XCC) 发读存储器命令( 0XBE) 连续读出两个字节数据(即温度)结束。
    DS18B20封装

    2.连接方式

    连接在STM32上 的引脚接口(可以选择其他)连接的引脚为后面的编程用得到

    单总线是一种半双工通信方式

    DS18B20共有6种信号类型:复位脉冲、应答脉冲、写0、写1、读0和读1。所有这些信号,除了应答脉冲以外,都由主机发出同步信号。并且发送所有的命令和数据都是字节的低位在前。

    边讲信号类型,边讲代码配置的方式,让大家了解STM32驱动18B20过程。

     信号线:PG9

    //IO方向设置

    #define DS18B20_IO_IN()  {GPIOG->MODER&=~(3<<(9*2));GPIOG->MODER|=0<<9*2;}    //PG9输入模

    #define DS18B20_IO_OUT() {GPIOG->MODER&=~(3<<(9*2));GPIOG->MODER|=1<<9*2;}     //PG9输出模

    IO操作                          

    #define    DS18B20_DQ_OUT PGout(9) //数据端口PG9

    #define    DS18B20_DQ_IN  PGin(9)  //数据端口    PG9 

    ( 1). 复位脉冲

    单总线上的所有通信都是以初始化序列开始。主机输出低电平,保持低电平时间至少480 us,,以产生复位脉冲。接着主机释放总线,4.7K的上拉电阻将单总线拉高,延时15~60 us,并进入接收模式(Rx)。接着DS18B20拉低总线60~240 us,以产生低电平应答脉冲。

    //复位DS18B20 void DS18B20_Rst(void)      

    {                    

    DS18B20_IO_OUT(); //设置为输出模式    

    DS18B20_DQ_OUT=0; //拉低DQ    

    delay_us(750);    //拉低750us(至少480us)    

    DS18B20_DQ_OUT=1; //DQ=1拉高释放总线    

    delay_us(15);     //15US    

    //进入接受模式,等待应答信号。

    }

    ② 应答信号

    //等待DS18B20的回应

    //返回1:未检测到DS18B20的存在    返回0:存在

    u8 DS18B20_Check(void)       

    {      

    u8 retry=0;    

    DS18B20_IO_IN();//SET PA0 INPUT        

    while (DS18B20_DQ_IN&&retry<200)    

    {            

    retry++;          

     delay_us(1);    

     };        

    if(retry>=200)return 1;    

    else retry=0;    

    while (!DS18B20_DQ_IN&&retry<240)    

    {            

    retry++;            

    delay_us(1);    

    };    

    if(retry>=240)return 1;            

    return 0;

    }

    ③ 写时序

    写时序包括写0时序和写1时序。所有写时序至少需要60us,且在2次独立的写时序之间至少需要1us的恢复时间,两种写时序均起始于主机拉低总线。 写1时序:主机输出低电平,延时2us,然后释放总线,延时60us。 写0时序:主机输出低电平,延时60us,然后释放总线,延时2us。

    /写一个字节到DS18B20 //dat:要写入的字节

    void DS18B20_Write_Byte(u8 dat)    

     {                

    u8 j;

     u8 testb;    

    DS18B20_IO_OUT();//设置PA0为输出    

    for (j=1;j<=8;j++)    

    {        

    testb=dat&0x01;        

    dat=dat>>1;        

    if (testb) //输出高      

      {          

      DS18B20_DQ_OUT=0;// 主机输出低电平            

    delay_us(2);                  //延时2us            

    DS18B20_DQ_OUT=1;//释放总线            

    delay_us(60); //延时60us                    

    }        

    else //输出低        

    {            

    DS18B20_DQ_OUT=0;//主机输出低电平            

    delay_us(60);               //延时60us            

    DS18B20_DQ_OUT=1;//释放总线            

    delay_us(2);                  //延时2us              

      }    

    }

    }

    ④ 读时序

    单总线器件仅在主机发出读时序时,才向主机传输数据,所以,在主机发出读数据命令后,必须马上产生读时序,以便从机能够传输数据。 所有读时序至少需要60us,且在2次独立的读时序之间至少需要1us的恢复时间。每个读时序都由主机发起,至少拉低总线1us。主机在读时序期间必须释放总线,并且在时序起始后的15us之内采样总线状态。

    典型的读时序过程为:主机输出低电平延时2us,然后主机转入输入模式延时12us,然后读取单总线当前的电平,然后延时50us。

    典型的读时序过程为:主机输出低电平延时2us,然后主机转入输入模式延时12us,然后读取单总线当前的电平,然后延时50us。

    //从DS18B20读取一个位 //返回值:1/0

    u8 DS18B20_Read_Bit(void)              // read one bit

    {

        u8 data;    

    DS18B20_IO_OUT();//设置为输出    

    DS18B20_DQ_OUT=0; //输出低电平2us    

    delay_us(2);    

    DS18B20_DQ_OUT=1; //拉高释放总线    

    DS18B20_IO_IN();//设置为输入    

    delay_us(12);//延时12us  

     if(DS18B20_DQ_IN)data=1;//读取总线数据    

    else data=0;        

    delay_us(50);  //延时50us            

    return data;

    }

    读取一个字节数据

    //从DS18B20读取一个字节 //返回值:读到的数据

    u8 DS18B20_Read_Byte(void)    // read one byte

    {            

    u8 i,j,dat;    

    dat=0;  

     for (i=1;i<=8;i++)  

     {        

    j=DS18B20_Read_Bit();        

    dat=(j<<7)|(dat>>1);    

    }                                

    return dat;

    }

    我们来看看DS18B20的典型温度读取过程,DS18B20的典型温度读取过程为:复位发SKIP ROM命令(0XCC)发开始转换命令(0X44)延时复位发送SKIP ROM命令(0XCC)发读存储器命令(0XBE)连续读出两个字节数据(即温度)结束。

    3最后最终源程序(需要把程序放在STM32F4库函数编写)

    打开我们的 DS18B20 数字温度传感器实验工程可以看到我们添加了 ds18b20.c 文件以及其
    头文件 ds18b20.h 文件,所有 ds18b20 驱动代码和相关定义都分布在这两个文件中。
    //ds18b20.c代码

    //复位 DS18B20

    #include "DS18B20"
    void DS18B20_Rst(void)
    {
    DS18B20_IO_OUT(); //SET PG11 OUTPUT
    DS18B20_DQ_OUT=0; //拉低 DQ
    delay_us(750); //拉低 750us
    DS18B20_DQ_OUT=1; //DQ=1
    delay_us(15); //15US
    }
    //等待 DS18B20 的回应
    //返回 1:未检测到 DS18B20 的存在
    //返回 0:存在
    u8 DS18B20_Check(void)
    {
    u8 retry=0;
    DS18B20_IO_IN();//SET PG11 INPUT
    while (DS18B20_DQ_IN&&retry<200) { retry++; delay_us(1); };
    if(retry>=200)return 1;
    else retry=0;
    while (!DS18B20_DQ_IN&&retry<240) {retry++; delay_us(1); };
    if(retry>=240)return 1;
    return 0;
    }
    //从 DS18B20 读取一个位
    //返回值: 1/0
    u8 DS18B20_Read_Bit(void)
    {
    u8 data;
    DS18B20_IO_OUT();//SET PG11 OUTPUT
    DS18B20_DQ_OUT=0;
    delay_us(2);
    DS18B20_DQ_OUT=1;
    DS18B20_IO_IN();//SET PG11 INPUT
    delay_us(12);
    if(DS18B20_DQ_IN)data=1;
    else data=0;
    delay_us(50);
    return data;
    }
    //从 DS18B20 读取一个字节
    //返回值:读到的数据
    u8 DS18B20_Read_Byte(void)
    {
    u8 i,j,dat;
    dat=0;
    for (i=1;i<=8;i++)
    {
    j=DS18B20_Read_Bit();
    dat=(j<<7)|(dat>>1);
    }
    return dat;
    }
    //写一个字节到 DS18B20
    //dat:要写入的字节
    void DS18B20_Write_Byte(u8 dat)
    {
    u8 j;
    u8 testb;
    DS18B20_IO_OUT();//SET PG11 OUTPUT;
    for (j=1;j<=8;j++)
    {
    testb=dat&0x01;
    dat=dat>>1;
    if (testb)
    {
    DS18B20_DQ_OUT=0;// Write 1
    delay_us(2);
    DS18B20_DQ_OUT=1;
    delay_us(60);
    }
    else
    {
    DS18B20_DQ_OUT=0;// Write 0
    delay_us(60);
    DS18B20_DQ_OUT=1;
    delay_us(2);
    }
    }
    }
    //开始温度转换
    void DS18B20_Start(void)
    {
    DS18B20_Rst();
    DS18B20_Check();
    DS18B20_Write_Byte(0xcc);// skip rom
    DS18B20_Write_Byte(0x44);// convert
    }
    //初始化 DS18B20 的 IO 口 DQ 同时检测 DS 的存在
    //返回 1:不存在
    //返回 0:存在
    u8 DS18B20_Init(void)
    {
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);//使能 GPIOG 时钟
    //GPIOG9

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//50MHz
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
    GPIO_Init(GPIOG, &GPIO_InitStructure);//初始化
    DS18B20_Rst();
    return DS18B20_Check();
    }

    //从 ds18b20 得到温度值
    //精度: 0.1C
    //返回值:温度值 ( -550~1250)
    short DS18B20_Get_Temp(void)
    {
    u8 temp;
    u8 TL,TH;
    short tem;
    DS18B20_Start();// ds1820 start convert
    DS18B20_Rst();
    DS18B20_Check();
    DS18B20_Write_Byte(0xcc);// skip rom
    DS18B20_Write_Byte(0xbe);// convert
    TL=DS18B20_Read_Byte(); // LSB
    TH=DS18B20_Read_Byte(); // MSB
    if(TH>7)
    {
    TH=~TH;
    TL=~TL;
    temp=0; //温度为负
    }else temp=1; //温度为正
    tem=TH; //获得高八位
    tem<<=8;
    tem+=TL; //获得底八位
    tem=(double)tem*0.625;//转换
    if(temp)return tem; //返回温度值
    else return -tem;
    }
    该部分代码就是根据我们前面介绍的单总线操作时序来读取 DS18B20 的温度值的,DS18B20
    的温度通过 DS18B20_Get_Temp 函数读取,该函数的返回值为带符号的短整型数据,返回值的
    范围为-550~1250,其实就是温度值扩大了 10 倍。
    主函数ds18b20.h

    #include "sys.h"
    #include "delay.h"
    #include "usart.h"
    #include "led.h"
    #include "lcd.h"
    #include "ds18b20.h"

    int main(void)
    {
    u8 t=0;
    short temperature;
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组 2
    delay_init(168); //初始化延时函数
    uart_init(115200); //初始化串口波特率为 115200
    LED_Init(); //初始化 LED
    LCD_Init();
    POINT_COLOR=RED;//设置字体为红色
    LCD_ShowString(30,50,200,16,16,"ALIX");
    LCD_ShowString(30,70,200,16,16,"DS18B20 TEST");
    LCD_ShowString(30,90,200,16,16,"ALIX");
    LCD_ShowString(30,110,200,16,16,"2018/7/22");
    while(DS18B20_Init()) //DS18B20 初始化
    {
    LCD_ShowString(30,130,200,16,16,"DS18B20 Error");
    delay_ms(200);
    LCD_Fill(30,130,239,130+16,WHITE);
    delay_ms(200);
    }
    LCD_ShowString(30,130,200,16,16,"DS18B20 OK");
    POINT_COLOR=BLUE;//设置字体为蓝色
    LCD_ShowString(30,150,200,16,16,"Temp:    . C");
    while(1)
    {
    if(t%10==0)//每 100ms 读取一次
    {
    temperature=DS18B20_Get_Temp();
    if(temperature<0)
    {
    LCD_ShowChar(30+40,150,'-',16,0); //显示负号
    temperature=-temperature; //转为正数
    }else LCD_ShowChar(30+40,150,' ',16,0); //去掉负号
    LCD_ShowNum(30+40+8,150,temperature/10,2,16); //显示正数部分
    LCD_ShowNum(30+40+32,150,temperature%10,1,16); //显示小数部分
    }
    delay_ms(10); t++;
    if(t==20)
    {
    t=0; LED0=!LED0;
    }
    }


     

     

     

     

     

     

     

    展开全文
  • ds18b20温度采集

    多人点赞 2021-04-20 13:37:52
    DS18B20的温度值显示程序设计 一.DS1820 单线数字温度计特性 • 独特的单线接口仅需一个端口引脚进行通讯 • 简单的多点分布应用 • 无需外部器件 • 可通过数据线供电 • 零待机功耗 • 测温范围-55~+125℃,以 0.5...

    DS18B20的温度值显示程序设计

    一.DS1820 单线数字温度计特性

    • 独特的单线接口仅需一个端口引脚进行通讯
    • 简单的多点分布应用
    • 无需外部器件
    • 可通过数据线供电
    • 零待机功耗
    • 测温范围-55~+125℃,以 0.5℃递增。华氏器件-67~+2570F,以 0.90F 递增
    • 温度以 9 位数字量读出
    • 温度数字量转换时间 200ms(典型值)
    • 用户可定义的非易失性温度报警设置
    • 报警搜索命令识别并标志超过程序限定温度(温度报警条件)的器件
    • 应用包括温度控制、工业系统、消费品、温度计或任何热感测系统

    二. ROM 操作指令

    Read ROM(读 ROM) [33H]
    Match ROM(匹配 ROM) [55H]
    Skip ROM(跳过 ROM] [CCH]
    Search ROM(搜索 ROM) [F0H]
    Alarm search(告警搜索) [ECH]

    三. 存储器操作命令

    Write Scratchpad(写暂存存储器) [4EH]
    Read Scratchpad(读暂存存储器) [BEH]
    Copy Scratchpad(复制暂存存储器) [48H]
    Convert Temperature(温度变换) [44H]
    Recall EPROM(重新调出) [B8H]
    Read Power supply(读电源) [B4H]
    话不多说,直接上代码。

    1.初始化子函数

    主机将数据线DQ拉低480us后释放总线,延时15 ~ 60 us 后的60 ~ 240 us时间内检测DQ是否为低电平,再延时240us 保证起始时序的完整。
    初始化

    bit init_ds18b20(void)
    {
      	bit initflag = 0;
      	
      	DQ = 1;             //主机拉低总线
      	Delay_OneWire(12);
      	DQ = 0;             //主机释放总线
    
      	Delay_OneWire(80); // 延时大于480us
      	DQ = 1;
      	Delay_OneWire(10);  // 14
      	initflag = DQ;     // initflag等于1初始化失败
      	Delay_OneWire(5);   //适当延时保证时序完整
      
      	return initflag;
    }
    

    2.通过单总线向DS18B20写一个字节

    注意 :传输数据低位在前面
    在这里插入图片描述
    写周期开始的时候,主机先把总线拉低大于1us表示写周期的开始。
    若主机写0,则继续拉低电平最少60us直到写周期结束,然后释放总线为高电平
    若主机写1,在拉低总线电平1us后,释放总线为高电平,直到写周期结束。

    void Write_DS18B20(unsigned char dat)
    {
    	unsigned char i;
    	for(i=0;i<8;i++)
    	{
    		DQ = 0;				    //主机拉低总线开始写
    		DQ = dat&0x01;		    //数据传输 低位在前 去最低置兼延时
    		Delay_OneWire(5);	    //使从机有时间去取到该位置
    		DQ = 1;				    //送完当前位后释放总线
    		dat >>= 1;			    // 为送入下一位做准备
    		                        //注意:左移还是右移,先移还是后移
    	}
    	Delay_OneWire(5);
    
    }
    

    3.从DS18B20读取一个字节

    读周期开始的时候,主机先把总线拉低大于1us,然后释放总线。主机释放总线后:
    若主机发送0,则继续拉低总线并保持至少从读周期开始15us,然后释放总线为高电平。
    若主机发送1,则在主机释放总线后不拉低总线,为高电平。
    主机必须在读周期开始的15us内检测总线电平的高低
    在这里插入图片描述

    unsigned char Read_DS18B20(void)	//调用返回读取的字节
    {
    	unsigned char i;			    //能用局部变量就不用全局变量
    	unsigned char dat;
    //	unsigned char index = 0;
      	   	
    	for(i=0;i<8;i++)		    //每次读一位
    	{
    		DQ = 0;				   //主机拉低总线至少一微秒开始读当前位
    		dat >>= 1;			   //位移兼延时,第一次右移位 无作用
    		DQ = 1; 			   //主机释放总线
    	   	Delay_us();			   //延时 使得从机得到响应
    
    		if(DQ)  			   //如果检测到了1  或写成(DQ==1)
    		{
    			dat |= 0x80;	   //将 dat 置于最高位  1000 1000
    		}	    
    		Delay_OneWire(5);		//适当延时,度周期至少60US
    	}
    	return dat;					//将接收好的字节反送给调用处
    }
    

    4.DS18B20温度采集程序

    unsigned char rd_temperature(void)
    {
       char temp,flag,xiaoshu1,xiaoshu2;
       int low,high;
       init_ds18b20();
       Write_DS18B20(0xcc);			//跳过写rom指令
       Write_DS18B20(0x44);			//启动温度转换
       Delay_OneWire(50);  			
    
       init_ds18b20();
       Write_DS18B20(0xcc);			//跳过写rom指令
       Write_DS18B20(0xbe);			//启动温度转换	转换期间必须10us(最多) 给单总线强上拉
       Delay_OneWire(50);  
    
       low=Read_DS18B20();  	 //传输过程中 先是低八位传输  后是 高八位传输
       high=Read_DS18B20();
    
       temp=low/16+high*16 ;  //温度组装成为字节
                              //相当于 temp=(low>>4)|(high<<4)	;低字节右移四位  高字节左移
       if(temp>=127)		  //符号位是1,则结果是负   此处判断标志位
       {
     		flag = 1; 		 //若符号位是1,则 温度为负数
    		temp = ~temp+1;  //补码转换为原码
       
       }
       xiaoshu1 = (low&0x0f)*10/16;       //取出温度第一位小数
       xiaoshu2 = (low&0x0f)*100/16%10;   //取出温度第二位小数
       //另外一种写法
       /*
       xiaoshu1 = (low&0x0f)*625/1000;
       xiaoshu2 = (low&0x0f)*625/100%10;
       */
       return temp;
    }
    /CCH 跳过rom指令 则 1100 1100 则写入的时候 0011 0011
    //BEH  写的时候低位前,高位后  1011 1110 则送进寄存器的段码是0111 1101
    // 8421 a 10 1010  b 11 1011   c 12 1100   d 13 1101   e 14 1110   f 15 1111
    

    5.延时子函数

    void Delay_OneWire(unsigned int t)  
    {
    	unsigned char i;
    	while(t--){
    		for(i=0;i<12;i++);
    	}
    }
    
    void Delay_us(void)
    {
    	unsigned char i;
    	i = 30;
    	while (--i);
    }
    

    希望可以对你有所帮助。

    展开全文
  • 一种快速查询多点DS18B20温度的方法

    万次阅读 2015-04-21 14:44:38
    一种快速查询多点DS18B20温度的方法 为了满足实时要求较高系统的设计需求,针对串联多个器件在一线制总线上的结构导致的在查询多点温度时速度缓慢的问题,北京铭正同创科技有限公司提出了一种快速查询多点温度...

    一种快速查询多点DS18B20温度的方法

    为了满足实时性要求较高系统的设计需求,针对串联多个器件在一线制总线上的结构导致的在查询多点温度时速度缓慢的问题,北京铭正同创科技有限公司提出了一种快速查询多点温度的解决方案。本方案以Dallas公司开发的一线制数字温度传感器DS18B20为核心,通过采用每个并行端口上连接一个DS18B20器件,实现同时对多个DS18B20进行同步操作的方法。本方案可广泛应用于各种工业控制、仪器仪表产品中。
    关键字快速多点温度查询 工业控制 仪器仪表

    1 技术概述
    Dallas公司开发的一线制数字温度传感器DS18B20是一款性能优异的数字式传感器,广泛应用于各种工业控制、仪器仪表产品当中。DS18B20与传统的热敏电阻温度传感器相比,能够直接读出被测温度,并且根据实际要求通过简单的编程可设置9~12位的分辨率,可以在750ms内将温度转化为12位的数字量,具有多种可选的封装方式。因而使用DS18B20可使系统结构更加简单,可靠性更高。DS18B20器件具体的封装形式如下图所示:


    GND 接地
    DQ 一线制总线(输入/输出)
    VD 供电电源

    而DS18B20的一线制总线独特而经济的特点,使用户可轻松地组建传感器网络,为测量系统的构建引入全新概念。一般应用一线制总线对DS18B20进行多点温度监控时,多采用如下的电路形式,即在一DQ线上串接多个DS18B20器件。如下图:

    在一线制总线上串接多个DS18B20器件时,实现对其中一个DS18B20器件进行一次温度转换和读取操作主要包括以下13个步骤(所有的操作都是通过DQ线进行信号传输的):
    1 主机MCU发复位脉冲
    2 DS18B20发应答脉冲(即MCU接收该应答信号,以确认器件在总线上)

    ************************确定器件存在**********************************************************************

    3 主机发匹配ROM命令
    4 主机发64位器件序列号(器件序列号与总线上的某个DS18B20器件一一对应)

    ***********************选择某个器件**************************************************************************


    5 主机发温度转换指令
    6 总线保持高电平50ms

    *********************所选器件开始转换温度**********************************************************************


    7 主机发复位命令
    8 DS18B20发应答脉冲
    9 主机发匹配ROM命令
    10 主机发64位器件代码
    11 主机发读数据寄存器指令
    12 主机接收数据

    *************************读取温度数据******************************************************************************


    13 主机发复位脉冲
    参考DS18B20的数据手册可知,当DS18B20的精度设置为12位精度表示时,依据上面的步骤完成对一个器件的测温、读取温度值的过程,大概会消耗掉1秒钟的时间。而如果总线上存在8个DS18B20器件的话,完成一次8个器件的查询需要8秒的时间,这不还没计算在系统初始化时,对总线上的器件序列号进行初始化过程所消耗的时间。
    针对所述利用多个DS18B20器件串接在一线制总线上进行多点温度查询时速度慢的原因,做进一步分析如下。
    DS18B20器件在进行一线制总线操作时,仅有一根DQ线用于双向的数据传输,每一个操作最小的细分至每一个的读写过程,即一个位的读写操作为一线制总线操作的最小单位,可以参考DS18B20的手册,了解到每一次最小单位的总线操作利用了规定时间内MCU驱动DQ线的高低电平来决定读/写的操作,然后在其后的规定时间内完成读/写一个位数据的操作。这样,就决定了每一次操作的过程中,要传输的数据位数越多,每一次的操作耗时越长。而DS18B20的一线制总线的操作对时序的要求很严格,一般在设计MCU对其总线操作的程序时,都是利用延时去保证每个读写周期的时间准确性,即说明这些时间内CPU必然是闲置的。如下图示意了一个写0和1操作的时序:

    另外,在多个器件串接在一线制总线上时,为了区分每次操作是针对总线上哪一个器件,DS18B20器件在内部提供了每个器件独有的64位ROM序列号,也就是说每一次操作都要首先在对DS18B20器件的ROM序列号进行匹配后,方可对其中的某一个器件进行测温/读取温度值的操作。可以估算出,每一次序列号的匹配操作,差不多需要4ms的时间,完成一次完整的测温/读取温度值操作,就需要进行两次序列号匹配,即消耗掉大概8个ms的时间。
    多个器件串接在总线上时,对所有的器件的查询操作,需要一个一个来,完成一次全部器件的查询需要成倍的操作时间,整个系统把大量时间消耗在时序所要求的延时上。
    此外,当采用多个器件串接在一线制总线的系统时,还需要在系统的初始化其间花销较长的时间来进行烦琐的总线上器件的序列号查询,并以此获知总线上的每个器件的序列号。
    如前所述,可以总结出,影响查询多点DS18B20温度速度的最主要因素有如下几个:
    1.每次操作都需要附加两次对64位序列号的匹配过程;
    2.多个器件串接,完成全部的查询就需要与器件个数成倍增长的耗时。
    这样的应用在一些对实时性要求相对较高的系统当中,是非常占用资源的(虽然省掉了端口资源,但CPU不得不等待N长时间后方可获取多点的温度值),所以使用起来总会有些遗憾。下面,介绍一种快速查询多点DS18B20温度的方法,包括硬件的连线构成以及软件的编程思路。
    2 解决方案
    由于一般都会将对DS18B20器件的温度查询放置在中断当中实现或者是在程序的主循环当中采用定时查询的方法实现,所以这就要求每次对DS18B20的操作都能快速的完成,尽快退出来进行其它的处理。所以为了解决串联多个器件在一线制总线上的结构导致的在查询多点温度时速度缓慢的问题,本设计提出一种解决方案,具体说是通过修改硬件连接来实现方便快捷的查询多点DS18B20器件温度的方法。
    2.1 快速查询多点DS18B20温度的方法简述
    当一线制总线上仅有一个DS18B20器件时,可以用skip ROM操作(即跳过ROM匹配)命令来代替64位序列号的匹配过程,这点也是使用单个DS18B20器件的系统常用的方法。所以,要想节省掉64位序列号匹配的时间开销,就必需设计成一个一线制总线上仅有一个DS18B20器件的系统。
    DS18B20的一线制总线在时序上的严格要求,也从另一方面意味着在一定的弹性范围内,不同DS18B20器件的时序细节上的一致性应该是非常好,所以可以将系统设计成利用MCU的并行端口同时对多个DS18B20进行统一的操作,不过这时候并行端口上的每一个端口连接着一个DS18B20器件而已。
    本文所述的解决方案正是以端口的消耗为代价,换取对多点DS18B20温度查询的速度,并在程序结构的设计上采用一些巧妙的处理方法,使得系统对DS18B20的操作上花更少的时间。此外,采用本设计实现的快速多点温度查询系统,可以省掉烦琐的总线上器件序列号的查询操作,并可节省大量的存储空间(原用于存储总线上器件的序列号所用的空间)。
    从理论上分析,本设计方案的采用,查询多个DS18B20器件操作所消耗的时间与查询一个DS18B20器件操作所消耗的时间是等量的。
    下面以查询8个DS18B20器件为例详细分析此方法的设计思想。
    2.2 系统硬件连接
    本系统方案8个DS18B20器件连接在MCU的一组端口的8个I/O口上,连线示意图如下所示:

    当然,上图中的示意图并没有考虑诸如端口驱动能力、抗干扰处理等,仅表明一个逻辑的连接示意,具体在产品级的设计时会根据产品的应用做必要的处理,比如增加一些必要的电路等,此处不作为讨论的重点。
    从上图可见,每个端口连接有一个DS18B20器件,也即一条一线制总线上仅有一个DS18B20器件,符合了前面所述的解决方法。实际在对DS18B20器件进行操作时,只需统一地对这一组并行端口进行操作(每个端口在同一时间输出相同的电平状态)即可。
    一个端口对应一个DS18B20器件,也就表示每组端口的某一个位的读回数据状态也就是该端口所对应的器件的输出状态,所以,这样的系统里面是不需要进行每个器件的序列号搜索、匹配的操作的。可知,在对DS18B20器件进行操作时,可以使用skip ROM命令来跳过ROM序列号匹配的操作,也即在所有的DS18B20器件的ROM操作时可以使用相同的端口输出时序。
    2.3 软件设计思路
    总结前面所介绍的电路示意图,下面详细介绍程序设计思想。
    在接下来的软件介绍中,会以C语言的例子介绍具体的编程思路,但这些代码并非就是实际中所使用的代码,仅作为逻辑性的参考,以便大家理解。这些代码是从一个产品的应用当中摘出的,而程序设计的结构也是从具体的设计当中分解出来的,供大家参考。
    软件设计从最底层的与DS18B20时序相关的驱动,到与一线制总线器件处理过程控制/协议的接口函数,再上升到应用API接口函数的关系如下图所示:

    在对连在一组8位端口上的8个DS18B20操作时,是同时对该组端口进行操作,也即同时对8个DS18B20器件进行同步的操作。
    范例程序是根据笔者的项目当中的功能需求而设计的,不一定会适合所有人的使用方法,但程序设计思想是可以参考的,这点请使用者在参考本文时对这里的范例进行一定的取舍。下面详细介绍一个以MCS51系列单片机的应用为例的范例程序,其中约定与8个DS18B20器件进行连接的是P1端口。
    2.3.1 底层时序驱动
    底层时序驱动程序与DS18B20的一线制总线的协议保持一致,根据一线制总线时序的特点,设计了四个基本的函数:
    总线写1时序控制函数:
    void DS18B20_Write_1(void)
    {
    P1 = 0x00; //8个DQ 线全部设置为低电平
    Delay_1us(10); //延时10us左右
    P1 = 0xff; //8个DQ线全部输出高电平
    Delay_1us(30); //延时30us左右
    }
    总线写0时序控制函数:
    void DS18B20_Write_0(void)
    {
    P1 = 0x00; //8个DQ 线全部设置为低电平
    Delay_1us(40); //延时
    P1 = 0xff; //端口恢复高电平
    Delay_1us(1);
    }
    总线读取一个数据位时序控制函数:
    unsigned char DS18B20_ReadDQ(void)
    {
    unsigned char DQ_S=0;
    P1 = 0x00; //8个DQ 线全部设置为低电平
    Delay_1us(10);
    P1 = 0xff; //端口置1,准备读取
    Delay_1us(1); //延时待总线准备好数据
    DQ_S = P1; //一次性读取8条DQ线的数据状态
    P1 = 0xff; //恢复端口电平
    Delay_1us(30); //延时
    return DQ_S; //返回读取的值
    }
    在读取一个总线状态数据位的函数中,将会返回一个byte的数据,该数据的8个位正好与连接在P2端口上的8个I/O口对应,如下图所示:

    总线复位时序控制函数:
    void DS18B20_Reset(void)
    {
    unsigned char Error_Counter=0;
    P1 = 0x00; //8个DQ 线全部设置为低电平
    Delay_1us(500); //保持总线低电平500us
    P1 = 0xff;
    Delay_1us(100);
    if(P1!=0x00) B20_Error = P1;//如检测到DS18B20总线响应了回复信号,则读取当前8条
    //总线的状态
    Delay_1us(50);
    P1 = 0xff;
    for(Error_Counter=0;Error_Counter<200;Error_Counter++)
    {
    if((P1&(~B20_Error))==(~B20_Error)) break; //如检测到总线的回复信号结
    //束,则退出循环
    Delay_1us(1);
    }
    P1 = 0xff; //恢复端口电平
    Delay_1us(200); //延时 200us~~~
    }
    在复位时序控制的函数中,使用了B20_Error全局变量,它将会传递给上一层的数据处理函数作为判断当前8个I/O口所接的DS18B20是否正常工作,或者是否在各自的总线上。
    2.3.2 操作协议相关的函数
    分析DS18B20的一线制总线控制命令,可以提炼出两个最基本的操作函数,一个是写一个byte数据至DS18B20器件,另一为读取DS18B20器件的数据。而在本文的范例程序当中,仅仅为了提取DS18B20器件的转换完后的温度值,所以在读取DS18B20的数据时,仅读取存放在数据地址前两个字节的温度数据,而不读取其它字节的数据,包括CRC校验值也没有进行读取,供参考。
    写字节操作函数:
    void DS18B20_WriteByte(unsigned char Com)
    {
    unsigned char i;
    for(i=0;i<8;i++)
    {
    if(Com&0x01)
    DS18B20_Write_1();
    else
    DS18B20_Write_0();
    Com = Com>>1;
    }
    }
    调用DS18B20_WriteByte函数,连在8个I/O口上的一线制总线上的8个DS18B20器件,将都会接收到同样的一个字节的数据:Com。
    读数据操作函数:
    unsigned char Read_buf_8ch[16]; //buffer of Read DS18B20
    void DS18B20_Read2Byte(void)
    {
    unsigned int i;
    for(i=0;i<16;i++)
    {
    Read_buf_8ch = DS18B20_ReadDQ();
    }
    }
    前面已经介绍过了,在本范例中,只读取位到DS18B20内部数据区域的前两节字的温度值数据,所以数据读取函数设计成读取两个字节的函数,即需要连续读取16个位(对应于每一个DS18B20器件来说是连续的16个位)。而将读回的数据保存于一个Read_buf_8ch(简写:Rb)的数组中,可以根据系统的接线图对读回的16个字节的数据进行分析,如下图所示:

    读取DS18B20的数据时,先读高位再读低位;所以可以从上图看到,以TM2的DS18B20的数据为例,TM2的两个字节的数据由Read_buf_8ch数组的16个字节数据中的每个字节的bit2位组成。可知,完成一次数据读取的操作后,可以同时读回8个DS18B20器件的数据,在数据处理时,只需针对上图的数据结构对Read_buf_8ch数组的数据进行处理即可得到每个DS18B20器件的测温值。
    2.3.3 API功能函数:
    供上层应用程序直接调用的函数相对来说,是与系统的具体硬件接法没有太多的关系,只需要依照DS18B20器件的操作流程进行操作即可。在此,提供两个API的范例,分别是启动温度转换控制函数和读取温度值函数。
    启动温度转换控制函数:
    void DS18B20_Conver(void)
    {
    DS18B20_Reset();
    DS18B20_WriteByte(0xcc); //Skip ROM
    DS18B20_WriteByte(0x44); //启动测温
    }
    读取温度值函数:
    void DS18B20_ReadTemp(void)
    {
    DS18B20_Reset();
    DS18B20_WriteByte(0xcc); //Skip ROM
    DS18B20_WriteByte(0xbe); //送入读取数据命令
    DS18B20_Read2Byte();
    }
    调用读取温度值函数后,8个DS18B20器件的测温数据将保存在数组Read_buf_8ch的16个字节单元当中,还有待进行下一步的处理,方可得到对应每个DS18B20器件的测温值。下面介绍简单的处理代码片断:
    char i,j;
    unsigned int uiData[8];
    unsigned char Mask;
    //OS the resoult of Temperature
    for(i=15;i>=0;i--)
    {
    Mask = 0x01;
    for(j=0;j<8;j++)
    {
    uiData[j] = uiData[j]<<1;
    if(Read_buf_8ch&Mask) uiData[j]++;
    Mask = Mask<<1;
    }
    }
    经过上述简单的处理,8个DS18B20器件的测温数据将保存在数组uiData当中的8个单元里,就可以根据自身程序设计的需求来对这些数据进行具体的处理了。
    3 结语
    本文介绍的快速查询多点DS18B20温度的设计方案,解决了串联多个器件在一线制总线上的结构导致的在查询多点温度时速度缓慢的问题,基本的设计思想是:将系统设计为在每个并行端口上连接一个DS18B20器件,利用MCU的并行端口同时对多个DS18B20进行统一的操作,实现操作多个DS18B20器件的时间等同于操作单个DS18B20器件的时间。本设计思想,可以大大减少在查询多个DS18B20测温值的时间开销,满足了实时性要求较高的系统的设计需求;同时,也省掉了烦琐的总线上多个器件序列号搜索的代码的步骤,并且节省了用于存储这些器件的序列号的存储单元,使得利用DS18B20进行多点测温的操作变得更方便、容易。
    虽然本文介绍的方法是以牺牲端口资源为代价,但具体在进行系统设计时,也可以通过一些扩展端口、串转并端口、多路模拟开关等硬件电路设计来弥补这些端口资源的消耗,也可通过这些硬件电路来扩展更多的DS18B20器件(如果有必要的话)。
    本文所介绍的方法已经在笔者参与设计的大型恒温系统当中应用,目前系统运行稳定、可靠
    展开全文
  • 该温度控制系统以STC89C52单片机为核心,采用DS18B20数字温度传感器采集温度,并以PWM形式输出,确保温度输出的稳定,再结合PID闭环控制,使系统能够更稳定地运行。先利用Proteus软件结合Keil软件仿真,再用STC89C52...
  • DS18B20测温程序

    2010-05-01 10:37:32
    测温程序,传统的温度检测大多以热敏电阻为传感器,采用热敏电阻,可满足 40 摄氏度 至 90 摄氏度 测量范围,但热敏电阻可靠差,测量温度准确率低,对于 1 摄氏度 的信号是不适用的,还得经过专门的接口电路转换成...
  •    九层妖塔 起于垒土 【蓝桥杯】—{模块}—{DS18B20温度传感器}
  • STM32中DS18B20的实现(垃圾版)

    万次阅读 多人点赞 2018-07-22 10:33:19
    DS18B20 数字温度传感器实验 STM32 虽然内部自带了温度传感器,但是因为芯片温升较大等问题,与实际温度差别较大,所以,本章我们将向大家介绍如何通过 STM32 来读取外部数字温度传感器的温度,来得到较为准确的...
  • DS18B20(1-wires)驱动移植

    2017-06-15 13:57:09
    Dallas 1-wires是Dallas公司的单总线设备,最具代表的就是DS18B20温度传感器,只需要一根线操作。...然后在XC2440板上小试了一下,把DS18B20驱起来,准确获取温度,一个好的驱动让工作变得如此简单。 L
  • DS18B20 是 DALLAS 最新单线数字温度传感器,新的"一线器件"体积更小、适用电压更宽、更经济。Dallas 半导体公司的数字化温度传感器 DS1820 是世界上第一片支持 "一线总线"接口的温度传感器。 DS18B20采用的单总线...
  • DS18B20温度传感器

    2009-07-03 13:01:35
    随着时代的进步和发展,...传统的温度检测大多以热敏电阻为传感器,这类传感器可靠差,测量温度准确率低且电路复杂。因此,本温度计摆脱了传统的温度测量方法,利用单片机对传感器进行控制。这样易于智能化控制。
  • linux 下 DS18B20(1-wires)驱动移植

    千次阅读 2013-02-05 11:38:58
    Dallas 1-wires是Dallas公司的单总线设备,最具代表的就是DS18B20温度传感器,只需要一根线操作...然后在XC2440板上小试了一下,把DS18B20驱起来,准确获取温度,一个好的驱动让工作变得如此简单。   Linux内核自
  • 单片机课程设计,C51+DS18B20温度传感器+LM016L显示屏 重点在于两个外设的时序控制 模块化的设计结构清晰明了 一、题目 温度测量系统的设计 二、要求 1.温度测量范围:-55℃ ~ 125℃,测量精度 ±0.1℃ 2.DS18B20作...
  • 一种快速查询多点DS18B20温度的方法 引言 为了满足实时要求较高系统的设计需求,针对串联多个器件在一线制总线上的结构导致的在查询多点温度时速度缓慢的问题,北京铭正同创科技有限公司提出了一种快速查询多点...
  • 基于DS18B20的数字温度计的毕业设计

    万次阅读 热门讨论 2009-07-28 11:21:00
    毕业设计论文 题目 基于单片机的DS18B20数字温度计 电话13812281034 系 电子信息工程系 专业 应用电子 
  • 本文章所研究的无线多功能防火报警系统采用STC12C5A60S2为核心控制器,利用火焰传感器YL-38、蓝牙模块HC-05、DS18B20温度传感器等实现基本功能。通过这些传感器和芯片,当环境中有火焰或温度等发生变化时系统会发出...
  • DS18B20 数字温度计提供9至12位的摄氏温度测量, 并具有易失的用户可编程触发点的上限和下限报警功能。DS18B20 单总线通信按定义只需要一条数据线(和地线)与中央微处理器进行通信。它具有工作温度范围55°C + ...
  • DS18B20 温度传感器的内部存储器包括一个高速暂存RAM 和一个非易失的可电擦除的EEPRAM,后者存放高温度和低温度触发器TH、TL 和结构寄存器。   4、配置寄存器 该字节各位的意义如下: TM ...
  • 通过采用DS18B20温度传感器与STC12 、ATMEG8A8相结合的水泥养护温度监控单元,并运用MCGS组态技术,进行MCGS与MATLAB的数据通信,实现了水泥养护室现场的多个检测点动态参数监控,系统具有控制精度高、实时监控、...
  • 设计基于MSP430g2553的多路温度巡检系统,系统采用LM35、DS18B20、PT100和MSP430g2553内部ADC10温度传感器,通过MSP430g2553单片机控制外围电路对4 路温度自动巡检,将测量结果通过LCD12864实时显示。给出了系统的...
  • 因而使用DS18B20可使系统结构更趋简单,可靠更高。他在测温精度、转换时间、传输距离、分辨率等方面较DS1820有了很大的改进,给用户带来了更方便的使用和更令人满意的效果。 主控制器 单片机AT89S52具有低电压供电...
  • 常见测温传感器及电路原理图

    千次阅读 2020-08-17 21:09:56
    常见的数字式测温芯片DS18B20,这个便宜,接口简单,所以在实验室用的还比较多。DS18B20数字温度传感器接线方便,封装后可应用于多种场合,如管道式,螺纹式,磁铁吸附式,不锈钢封装式。主要根据应用场合的不同而...
  • 基于单片机的温度计设计

    千次阅读 2020-09-27 21:13:42
    关键词:单片机,数字控制,温度计, DS18B20,AT89S51 1 引言   随着人们生活水平的不断提高,单片机控制无疑是人们追求的目标之一,它所给人带来的方便也是不可否定的,其中数字温度计就是一个典型的例子,但人们...

空空如也

空空如也

1 2 3 4 5 ... 14
收藏数 277
精华内容 110
关键字:

ds18b20准确性