单片机基础模块学习——DS18B20温度传感器芯片

不知道该往哪走的时候,就往前走。 

一、DS18B20芯片原理图

该芯片共有三个引脚,分别为

  1. GND——接地引脚
  2. DQ——数据通信引脚
  3. VDD——正电源

数据通信用到的是1-Wier协议

  • 优点:占用端口少,电路设计方便
  •  同时该协议要求通过上拉电阻上拉到正电源
  • 该协议是总线协议,可以挂载一个以上的元件
  • 总线协议每一个元件都有一个地址,根据地址就可以获得对应传感器的内部信息


    DS18B20温度传感器在开发板上的位置如下图

     二、访问DS18B20步骤

    1. 初始化
    2. 发送地址(当总线上只有一个元件,就可以直接面向所有的传感器进行通信就可以了例如:局域网的广播)
    3. 功能性命令(触发温度采集,读取相关命令等)

      功能性命令表格

  • 第一行触发温度转换,地址是0x44
  • 第二行读取温度,地址是0xBE
  • 下面的功能是进行更深入的开发会用到,这里暂不解释

  • DS18B20温度存储格式

     

    共有16位数据结构,S=SIGN 代表一个符号

  • 如果温度是正的,11~15位都是0;
  • 如果温度是负的,11~15位都是1;
  • 0~3是小数位,4~10是整数位,最高到。温度传感器的精度是12bit

    读取的话由于是16位的数据,可以用unsigned int类型变量存储


    但真正的unsigned int类型和这个是有差别的

    由上图可以发现,对应的两个数之间相差倍,因此在读取之后,想要获得真正的值就要除以16

    三、模块代码

    由于占用两个字节,所以用两个变量存储高八位和低八位的数,最后并在一起返回一个数

    #include "onewire.h"
    //
    void Delay_OneWire(unsigned int t)  
    {
    	unsigned char i;
    	while(t--){
    		for(i=0;i<12;i++);
    	}
    }
    
    //
    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);
    }
    
    //
    unsigned char Read_DS18B20(void)
    {
    	unsigned char i;
    	unsigned char dat;
      
    	for(i=0;i<8;i++)
    	{
    		DQ = 0;
    		dat >>= 1;
    		DQ = 1;
    		if(DQ)
    		{
    			dat |= 0x80;
    		}	    
    		Delay_OneWire(5);
    	}
    	return dat;
    }
    
    //
    bit init_ds18b20(void)
    {
      	bit initflag = 0;
      	
      	DQ = 1;
      	Delay_OneWire(12);
      	DQ = 0;
      	Delay_OneWire(80);
      	DQ = 1;
      	Delay_OneWire(10); 
        initflag = DQ;     
      	Delay_OneWire(5);
      
      	return initflag;
    }
    
    unsigned int read_temperature(void)
    {
    	unsigned char low,high;
    	
    	init_ds18b20();//初始化
    	Write_DS18B20(0xCC);//对所有元件进行通信
    	Write_DS18B20(0x44);//触发温度转换
    	
    	init_ds18b20();//初始化
    	Write_DS18B20(0xCC);//对所有元件进行通信
    	Write_DS18B20(0xBE);//读取温度
    	
    	low=Read_DS18B20();//返回数据
    	high=Read_DS18B20();
    	
    	return (high<<8|low);
    }

    四、主函数代码

    这里别忘记要将数据除以16才是真实数据,由于传回的是整数类型,所以要除以16.0,最后的结果才可以保留两位小数


    想让数码管的后四位不显示,不要忘记敲四个空格

    #include "seg.h"
    #include "tim.h"
    #include "led.h"
    #include "init.h"
    #include "onewire.h"
    //Seg
    unsigned char pucSeg_Buf[12],pucSeg_Code[9],pucSeg_Pos=0;//字符数组以/0结尾,所以要有9位
    void Seg_Proc(void);
    
    //Timer
    unsigned long ulms =0;
    unsigned int uiSeg_Dly=0;
    //Temperature
    unsigned int uiTemp=0;
    void main(void)
    {
    	Cls_Peripheral();
    	Timer0Init();
    	EA=1;
    	
    	while(1)
    	{
    		Seg_Proc();
    	}
    
    }
    
    void Seg_Proc(void)
    {
    	if(uiSeg_Dly<200)
    		return;
    	
    	uiSeg_Dly =0;
    	uiTemp = read_temperature();
    	sprintf(pucSeg_Buf,"%.2f    ",uiTemp/16.0);//将指定的内容打印到字符数组里
    	Seg_Tran(pucSeg_Buf,pucSeg_Code);
    }
    
    void Time_0(void) interrupt 1
    {
    	ulms++;
    	uiSeg_Dly++;
    	if(ulms % 2==0)
    	{
    	pucSeg_Pos=(pucSeg_Pos+1)%8;//实现pucSeg_Pos从0-7循环的操作
    	Seg_Disp(pucSeg_Code,pucSeg_Pos);
    	}
    }
    

     

     

    作者:promising-w

    物联沃分享整理
    物联沃-IOTWORD物联网 » 单片机基础模块学习——DS18B20温度传感器芯片

    发表回复