16/32路温度测量

如何基于单片机51,实现16路或者32路的温度监测?
温度传感器用DS18B20

该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
要基于单片机实现16路或32路的温度监测,可以使用DS18B20数字温度传感器。DS18B20是一种数字式温度传感器,具有易于使用、高精度、数字输出等特点。

以下是一个实现16路温度测量的示例代码:

#include <reg51.h>
#include "ds18b20.h" // DS18B20驱动库头文件

#define DQ P2_0 // DS18B20数据引脚

void main()
{
    unsigned char i;
    float temp[16]; // 存储16路温度值的数组

    while (1)
    {
        for (i = 0; i < 16; i++)
        {
            temp[i] = ds18b20_read_temp(DQ); // 读取温度值
        }
    }
}

在上面的代码中,我们使用了 ds18b20.h 头文件中的 ds18b20_read_temp 函数来读取温度值。该函数接收一个参数,即DS18B20数据引脚的引脚号,返回一个浮点数表示当前DS18B20的温度值。

如果要实现32路温度测量,可以类似地定义一个32个元素的数组,然后在主循环中读取每个DS18B20的温度值,将其存储在相应的数组元素中即可。

需要注意的是,在使用DS18B20时,需要先进行初始化,然后再读取温度值。具体的初始化过程可以参考DS18B20的数据手册。另外,由于DS18B20是一种数字式温度传感器,读取温度值时需要进行一定的计算,将读取到的原始数据转换为温度值。具体的温度值计算公式也可以在DS18B20的数据手册中找到。


如果以上回答对您有所帮助,点击一下采纳该答案~谢谢

  • 你看下这篇博客吧, 应该有用👉 :夯实基础:51单片机及DS18B20温度传感器的数字温度计设计 原件清单,仿真,原理图,源代码
  • 除此之外, 这篇博客: C语言:51单片机看这一篇就够了中的 二十九、单片机实操二十七:DS18B20温度传感器与温度读取 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 1、DS18B20介绍

    2、 引脚及应用电路

     3、内部结构图

     4、存储器结构

     5、单总线介绍

     6、单总线电路规范

     7、单总线时序结构

     

     

     

     8、DS18B20操作流程

    9、DS18B20数据帧 

     10、温度存储格式

     11、编写程序

    main.c

    #include <STC89C5xRC.H>
    #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调用一次按键驱动函数
    	}
    }
    

    OneWrite.c

    #include <STC89C5xRC.H>
    //引脚定义
    sbit OneWire_DQ=P3^7;
    
    /**
      * @brief  单总线初始化
      * @param  无
      * @retval 从机响应位,0为响应,1为未响应
      */
    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;
    }
    
    /**
      * @brief  单总线发送一位
      * @param  Bit 要发送的位
      * @retval 无
      */
    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;
    }
    
    /**
      * @brief  单总线接收一位
      * @param  无
      * @retval 读取的位
      */
    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;
    }
    
    /**
      * @brief  单总线发送一个字节
      * @param  Byte 要发送的字节
      * @retval 无
      */
    void OneWire_SendByte(unsigned char Byte)
    {
    	unsigned char i;
    	for(i=0;i<8;i++)
    	{
    		OneWire_SendBit(Byte&(0x01<<i));
    	}
    }
    
    /**
      * @brief  单总线接收一个字节
      * @param  无
      * @retval 接收的一个字节
      */
    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;
    }
    

    OneWrite.h

    #ifndef __ONEWIRE_H__
    #define __ONEWIRE_H__
    
    unsigned char OneWire_Init(void);
    void OneWire_SendBit(unsigned char Bit);
    unsigned char OneWire_ReceiveBit(void);
    void OneWire_SendByte(unsigned char Byte);
    unsigned char OneWire_ReceiveByte(void);
    
    #endif
    
  • 以下回答由chatgpt基于相关博客总结生成:

    可以采用循环遍历的方式,不断读取温度传感器DS18B20的输出值,并将其转化为实际温度值。具体实现方法如下:

    1. 定义控制DS18B20的引脚DQ和一个标志位FLAG,用于判断温度传感器是否正常。同时定义几个用于存储温度数据的寄存器。
          FLAG BIT F0                  ;  声明传感器复位返回的标志位 
          DQ BIT P1.7                  ;  定义DQ作为数据传输端口名 
          ABIT EQU 35H 
          BBIT EQU 36H 
          CBIT EQU 37H                 ;  固定个,十,百位的存储位置,名称
    
    1. 写一个复位程序INIT_1,用于初始化DS18B20传感器和单片机。程序如下:
          INIT_1:SETB DQ               ;  总线释放 
          NOP                          ;  保持高电平延时
          CLR DQ                       ;  总线置 0请求响应
          MOV R0,#0FBH 
    TSR1: DJNZ R0,TSR1                 ;  延时
          SETB DQ                      ;  再释放
          MOV R0,#25H 
    TSR2: JNB DQ,TSR3                  ;  改变为0则代表得到对应
          DJNZ R0,TSR2                 ;  未得到则继续等待判断
    TSR3: SETB FLAG                    ;  得到相应则标志位置1代表传感器正常存在 
          MOV R0,#06BH 
    TSR4: DJNZ R0,TSR4                 ;  延时
          SETB DQ                      ;  释放总线完成复位 
    RET 
    
    1. 写一个改变温度精度的函数FBLCHANGE,用于在DS18B20传感器中改变温度的采集精度为9位,并调用INIT_1程序进行初始化操作。具体代码如下:
    FBLCHANGE:
          LCALL INIT_1                 ;  复位
          MOV A,#0CCH                  ;  跳过ROM
          LCALL WRITE                  ;  A写入传感器
          MOV A,#1FH                   ;  改变温度分辨率为9
          LCALL WRITE                  ;  A写入传感器
    RET
    
    1. 读取温度的程序GET_TEMP,可以参考以下代码,其中用到了循环语句,对温度传感器进行多次采样获取更加准确的温度值。
    GET_TEMP:
          SETB DQ                      ;  释放总线
          LACALL INIT_1                ;  复位
          JB FLAG,TSS1                 ;  若传感器不存在,则直接返回主程序
    RET
    TSS2: MOV A,#0CCH
          LCALL WRITE                  ;  执行跳过ROM指令
          MOV A,#44H
          LCALL WRITE                  ;  执行测温指令
          LCALL DISPLAY                ;  不仅延时,还让程序完全生效前数码管置零
          LCALL INIT_1                 ;  复位
          MOV A,#0CCH 
          LCALL WRITE                  ;  执行跳过ROM置零
          MOV A,#0BEH 
          LCALL WRITE                  ;  执行读取温度数据指令
          LCALL READ                   ;  跳转至通信子程序
    RET 
    
    1. 数据处理函数CHANGE,用于将读出来的温度数据处理为可读显示的格式,并调用显示函数进行实时展示。

    ``` CHANGE: MOV A,29H MOV 26H,29H MOV 25H,28H MOV 24H,28H ; 在24H存储原始数据防止丢失 MOV C,25H.7 ; 存