• 十一、DS18B20温度传感器


    介绍

    在这里插入图片描述

    单总线时序结构

    初始化:主机将总线拉低至少480us,然后释放总线,等待15~ 60us后,存在的从机会拉低总线60~240us以相应主机,之后从机将释放总线
    发送一位:主机将总线拉低60~ 120us,然后释放总线,表示发送0;主机将总线拉低1~ 15us,然后释放总线,表示发送1。从机将在总线拉低30us后,读取电平,整个时间片应大于60us
    接收一位:主机将总线拉低1~15us,然后释放总线,并在拉低后15us内读取总线电平(尽量贴近15us的末尾),读取为低电平则为接收0,读取为高电平则为接收1 ,整个时间片应大于60us

    操作流程

    在这里插入图片描述

    温度存储格式

    在这里插入图片描述

    单总线模块代码

    #include 
    //引脚定义
    sbit OneWire_DQ=P3^7;
    unsigned char OneWire_Init(void)
    {
    	unsigned char i;
    	unsigned char AckBit;
    	OneWire_DQ=1;
    	OneWire_DQ=0;
    	i = 247;while (--i);		//Delay 500us
    	OneWire_DQ=1;
    	i = 32;while (--i);			//Delay 70us
    	AckBit=OneWire_DQ;
    	i = 247;while (--i);		//Delay 500us
    	return AckBit;
    }
    void OneWire_SendBit(unsigned char Bit)
    {
    	unsigned char i;
    	OneWire_DQ=0;
    	i = 4;while (--i);			//Delay 10us
    	OneWire_DQ=Bit;
    	i = 24;while (--i);			//Delay 50us
    	OneWire_DQ=1;
    }
    unsigned char OneWire_ReceiveBit(void)
    {
    	unsigned char i;
    	unsigned char Bit;
    	OneWire_DQ=0;
    	i = 2;while (--i);			//Delay 5us
    	OneWire_DQ=1;
    	i = 2;while (--i);			//Delay 5us
    	Bit=OneWire_DQ;
    	i = 24;while (--i);			//Delay 50us
    	return Bit;
    }
    void OneWire_SendByte(unsigned char Byte)
    {
    	unsigned char i;
    	for(i=0;i<8;i++)
    	{
    		OneWire_SendBit(Byte&(0x01<<i));
    	}
    }
    unsigned char OneWire_ReceiveByte(void)
    {
    	unsigned char i;
    	unsigned char Byte=0x00;
    	for(i=0;i<8;i++)
    	{
    		if(OneWire_ReceiveBit()){Byte|=(0x01<<i);}
    	}
    	return Byte;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    DS18B20模块代码

    #include 
    #include "OneWire.h"
    //DS18B20指令
    #define DS18B20_SKIP_ROM			0xCC
    #define DS18B20_CONVERT_T			0x44
    #define DS18B20_READ_SCRATCHPAD 	0xBE
    void DS18B20_ConvertT(void)
    {
    	OneWire_Init();
    	OneWire_SendByte(DS18B20_SKIP_ROM);
    	OneWire_SendByte(DS18B20_CONVERT_T);
    }
    float DS18B20_ReadT(void)
    {
    	unsigned char TLSB,TMSB;
    	int Temp;
    	float T;
    	OneWire_Init();
    	OneWire_SendByte(DS18B20_SKIP_ROM);
    	OneWire_SendByte(DS18B20_READ_SCRATCHPAD);
    	TLSB=OneWire_ReceiveByte();
    	TMSB=OneWire_ReceiveByte();
    	Temp=(TMSB<<8)|TLSB;
    	T=Temp/16.0;
    	return T;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    温度读取主函数

    #include 
    #include "LCD1602.h"
    #include "DS18B20.h"
    #include "Delay.h"
    
    float T;
    
    void main()
    {
    	DS18B20_ConvertT();		//上电先转换一次温度,防止第一次读数据错误
    	Delay(1000);			//等待转换完成
    	LCD_Init();
    	LCD_ShowString(1,1,"Temperature:");
    	while(1)
    	{
    		DS18B20_ConvertT();	//转换温度
    		T=DS18B20_ReadT();	//读取温度
    		if(T<0)				//如果温度小于0
    		{
    			LCD_ShowChar(2,1,'-');	//显示负号
    			T=-T;			//将温度变为正数
    		}
    		else				//如果温度大于等于0
    		{
    			LCD_ShowChar(2,1,'+');	//显示正号
    		}
    		LCD_ShowNum(2,2,T,3);		//显示温度整数部分
    		LCD_ShowChar(2,5,'.');		//显示小数点
    		LCD_ShowNum(2,6,(unsigned long)(T*10000)%10000,4);//显示温度小数部分
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    温度报警器主函数

    #include 
    #include "LCD1602.h"
    #include "DS18B20.h"
    #include "Delay.h"
    #include "AT24C02.h"
    #include "Key.h"
    #include "Timer0.h"
    
    float T,TShow;
    char TLow,THigh;
    unsigned char KeyNum;
    
    void main()
    {
    	DS18B20_ConvertT();		//上电先转换一次温度,防止第一次读数据错误
    	Delay(1000);			//等待转换完成
    	THigh=AT24C02_ReadByte(0);	//读取温度阈值数据
    	TLow=AT24C02_ReadByte(1);
    	if(THigh>125 || TLow<-55 || THigh<=TLow)
    	{
    		THigh=20;			//如果阈值非法,则设为默认值
    		TLow=15;
    	}
    	LCD_Init();
    	LCD_ShowString(1,1,"T:");
    	LCD_ShowString(2,1,"TH:");
    	LCD_ShowString(2,9,"TL:");
    	LCD_ShowSignedNum(2,4,THigh,3);
    	LCD_ShowSignedNum(2,12,TLow,3);
    	Timer0_Init();
    	
    	while(1)
    	{
    		KeyNum=Key();
    		
    		/*温度读取及显示*/
    		DS18B20_ConvertT();	//转换温度
    		T=DS18B20_ReadT();	//读取温度
    		if(T<0)				//如果温度小于0
    		{
    			LCD_ShowChar(1,3,'-');	//显示负号
    			TShow=-T;		//将温度变为正数
    		}
    		else				//如果温度大于等于0
    		{
    			LCD_ShowChar(1,3,'+');	//显示正号
    			TShow=T;
    		}
    		LCD_ShowNum(1,4,TShow,3);		//显示温度整数部分
    		LCD_ShowChar(1,7,'.');		//显示小数点
    		LCD_ShowNum(1,8,(unsigned long)(TShow*100)%100,2);//显示温度小数部分
    		
    		/*阈值判断及显示*/
    		if(KeyNum)
    		{
    			if(KeyNum==1)	//K1按键,THigh自增
    			{
    				THigh++;
    				if(THigh>125){THigh=125;}
    			}
    			if(KeyNum==2)	//K2按键,THigh自减
    			{
    				THigh--;
    				if(THigh<=TLow){THigh++;}
    			}
    			if(KeyNum==3)	//K3按键,TLow自增
    			{
    				TLow++;
    				if(TLow>=THigh){TLow--;}
    			}
    			if(KeyNum==4)	//K4按键,TLow自减
    			{
    				TLow--;
    				if(TLow<-55){TLow=-55;}
    			}
    			LCD_ShowSignedNum(2,4,THigh,3);	//显示阈值数据
    			LCD_ShowSignedNum(2,12,TLow,3);
    			AT24C02_WriteByte(0,THigh);		//写入到At24C02中保存
    			Delay(5);
    			AT24C02_WriteByte(1,TLow);
    			Delay(5);
    		}
    		if(T>THigh)			//越界判断
    		{
    			LCD_ShowString(1,13,"OV:H");
    		}
    		else if(T<TLow)
    		{
    			LCD_ShowString(1,13,"OV:L");
    		}
    		else
    		{
    			LCD_ShowString(1,13,"    ");
    		}
    	}
    }
    
    void Timer0_Routine() interrupt 1
    {
    	static unsigned int T0Count;
    	TL0 = 0x18;		//设置定时初值
    	TH0 = 0xFC;		//设置定时初值
    	T0Count++;
    	if(T0Count>=20)
    	{
    		T0Count=0;
    		Key_Loop();	//每20ms调用一次按键驱动函数
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
  • 相关阅读:
    【紫光同创国产FPGA教程】【PGC1/2KG第六章】密码锁实验例程
    在条件神经网络训练中,为什么对于条件特征采取 “don‘t compute derivative w.r.t. inputs”?
    什么是无损检测设备?
    vue3实现表格数据导出Excel
    linux学习总结
    FFplay文档解读-7-比特流过滤器
    微信小程序 语法学习
    基于一种交互式的光伏组件特性曲线算法(Matlab代码实现)
    CV计算机视觉每日开源代码Paper with code速览-2023.11.3
    HLS 的新特性
  • 原文地址:https://blog.csdn.net/m0_63667883/article/details/133096382