八、Proteus817实现51单片机DS18B20多点温度采集

发布于:2025-09-01 ⋅ 阅读:(20) ⋅ 点赞:(0)

前言
本章讲解了51单片机和DS18B20实现多点温度读取,即一个单片机挂载多个DS18B20,只讲使用,不讲原理,快速上手!

一、绘制仿真

1、新建仿真和添加器件

本次要用到的器件主要为这些,当然也可以把温度读取那章的仿真复制过来直接改。
在这里插入图片描述

2、绘制仿真图

(1)引脚连接

三个DS18B20
VCC------VCC
DQ0-------P37
DQ1-------P36
DQ2-------P35
GND-------GND
在这里插入图片描述

(2)添加串口

在这里插入图片描述

(3)设置时钟频率

双击芯片设置。在这里插入图片描述

二、编写代码

为了方便测试和移植,这里只贴封装版代码

(1)新建C文件

在我们keil里面新建工程后,我们新建这几个文件。
值得注意的是,如果我们用的是温度读取章节的代码,我们只需要增加两个DS18B20的代码;串口代码的话如果没有就去第一章获取。一键跳转
在这里插入图片描述

(2)粘贴新代码

这里的话我们可以看到,代码里他们的函数都一样,除了DQ和读取函数,因为前面的关键字static,使得这个函数为静态变量,只在这个c文件里用,不会被其他C文件检测,所以可以一起同名。

DS18B20.c
#include "DS18B20.h"

//单总线延时函数
static void Delay_OneWire(unsigned int t) 
{
	//t = t * 12;	// STC15f
	while (t--)
		;
}

//通过单总线向DS18B20写一个字节
static void Write_DS18B20(unsigned char dat)
{
	unsigned char i;
	for (i = 0; i < 8; i++)
	{
		DQ0  = 0;
		DQ0  = dat & 0x01;
		Delay_OneWire(5);
		DQ0  = 1;
		dat >>= 1;
	}
	Delay_OneWire(5);
}

//从DS18B20读取一个字节
static unsigned char Read_DS18B20(void)
{
	unsigned char i;
	unsigned char dat;

	for (i = 0; i < 8; i++)
	{
		DQ0  = 0;
		dat >>= 1;
		DQ0  = 1;
		if (DQ0 )
		{
			dat |= 0x80;
		}
		Delay_OneWire(5);
	}
	return dat;
}

// DS18B20设备初始化
static bit init_ds18b20(void)
{
	bit initflag = 0;

	DQ0  = 1;
	Delay_OneWire(12);
	DQ0  = 0;
	Delay_OneWire(80);
	DQ0  = 1;
	Delay_OneWire(10);
	initflag = DQ0 ;
	Delay_OneWire(5);

	return initflag;
}
//读取温度,已经是转换后的,如值为25.6
float Get_Current_T0(void)
{
	unsigned int temp;
	float temperature;
	unsigned char low, high;

	init_ds18b20();
	Write_DS18B20(0xCC);
	Write_DS18B20(0x44);
	Delay_OneWire(200);

	init_ds18b20();
	Write_DS18B20(0xCC);
	Write_DS18B20(0xBE);

	low = Read_DS18B20();
	high = Read_DS18B20();
	temp = high;
	temp <<= 8;
	temp |= low;
	temperature = temp * 0.0625;

	return temperature;
}
DS18B20_2.c
#include "DS18B20.h"

//单总线延时函数
static void Delay_OneWire(unsigned int t) 
{
	//t = t * 12;	// STC15f
	while (t--)
		;
}

//通过单总线向DS18B20写一个字节
static void Write_DS18B20(unsigned char dat)
{
	unsigned char i;
	for (i = 0; i < 8; i++)
	{
		DQ1  = 0;
		DQ1  = dat & 0x01;
		Delay_OneWire(5);
		DQ1  = 1;
		dat >>= 1;
	}
	Delay_OneWire(5);
}

//从DS18B20读取一个字节
static unsigned char Read_DS18B20(void)
{
	unsigned char i;
	unsigned char dat;

	for (i = 0; i < 8; i++)
	{
		DQ1  = 0;
		dat >>= 1;
		DQ1  = 1;
		if (DQ1 )
		{
			dat |= 0x80;
		}
		Delay_OneWire(5);
	}
	return dat;
}

// DS18B20设备初始化
static bit init_ds18b20(void)
{
	bit initflag = 0;

	DQ1  = 1;
	Delay_OneWire(12);
	DQ1  = 0;
	Delay_OneWire(80);
	DQ1  = 1;
	Delay_OneWire(10);
	initflag = DQ1 ;
	Delay_OneWire(5);

	return initflag;
}
//读取温度,已经是转换后的,如值为25.6
float Get_Current_T1(void)
{
	unsigned int temp;
	float temperature;
	unsigned char low, high;

	init_ds18b20();
	Write_DS18B20(0xCC);
	Write_DS18B20(0x44);
	Delay_OneWire(200);

	init_ds18b20();
	Write_DS18B20(0xCC);
	Write_DS18B20(0xBE);

	low = Read_DS18B20();
	high = Read_DS18B20();
	temp = high;
	temp <<= 8;
	temp |= low;
	temperature = temp * 0.0625;

	return temperature;
}
DS18B20_3.c
#include "DS18B20.h"

//单总线延时函数
static void Delay_OneWire(unsigned int t) 
{
	//t = t * 12;	// STC15f
	while (t--)
		;
}

//通过单总线向DS18B20写一个字节
static void Write_DS18B20(unsigned char dat)
{
	unsigned char i;
	for (i = 0; i < 8; i++)
	{
		DQ2  = 0;
		DQ2  = dat & 0x01;
		Delay_OneWire(5);
		DQ2  = 1;
		dat >>= 1;
	}
	Delay_OneWire(5);
}

//从DS18B20读取一个字节
static unsigned char Read_DS18B20(void)
{
	unsigned char i;
	unsigned char dat;

	for (i = 0; i < 8; i++)
	{
		DQ2  = 0;
		dat >>= 1;
		DQ2  = 1;
		if (DQ2 )
		{
			dat |= 0x80;
		}
		Delay_OneWire(5);
	}
	return dat;
}

// DS18B20设备初始化
static bit init_ds18b20(void)
{
	bit initflag = 0;

	DQ2  = 1;
	Delay_OneWire(12);
	DQ2  = 0;
	Delay_OneWire(80);
	DQ2  = 1;
	Delay_OneWire(10);
	initflag = DQ2 ;
	Delay_OneWire(5);

	return initflag;
}
//读取温度,已经是转换后的,如值为25.6
float Get_Current_T2(void)
{
	unsigned int temp;
	float temperature;
	unsigned char low, high;

	init_ds18b20();
	Write_DS18B20(0xCC);
	Write_DS18B20(0x44);
	Delay_OneWire(200);

	init_ds18b20();
	Write_DS18B20(0xCC);
	Write_DS18B20(0xBE);

	low = Read_DS18B20();
	high = Read_DS18B20();
	temp = high;
	temp <<= 8;
	temp |= low;
	temperature = temp * 0.0625;

	return temperature;
}
DS18B20.h
#ifndef _DS18B20_H
#define _DS18B20_H
#include "reg52.h"

sbit DQ0 = P3^7;//单总线接口
sbit DQ1 = P3^6;//单总线接口
sbit DQ2 = P3^5;//单总线接口

float Get_Current_T0(void);
float Get_Current_T1(void);
float Get_Current_T2(void);

#endif

main.c
#include "reg52.h"
#include "intrins.h"
#include "stdio.h"
#include "DS18B20.h"
#include "uart.h"


void Delay1000ms(void)	//@11.0592MHz
{
	unsigned char data i, j, k;

	_nop_();
	i = 8;
	j = 1;
	k = 243;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void Delay50ms(void)	//@11.0592MHz
{
	unsigned char data i, j;

	i = 90;
	j = 163;
	do
	{
		while (--j);
	} while (--i);
}


void main()
{
	float temp0 = 25;
	float temp1 = 28;
	float temp2 = 37;
	char send[20];
	UART_Init(9600);
	UART_SendString("123");
	UART_SendString("\r\n");
	while(1)
	{
		UART_SendString("-----------------\r\n");
		Delay1000ms();
		temp0 = Get_Current_T0();//读取温度
		Delay50ms();
		sprintf(send,"temp0:%.1f\r\n",temp0);//拼接字符串
		UART_SendString(send);//串口发送温度
		temp1 = Get_Current_T1();//读取温度
		Delay50ms();
		sprintf(send,"temp1:%.1f\r\n",temp1);//拼接字符串
		UART_SendString(send);//串口发送温度
		temp2 = Get_Current_T2();//读取温度
		Delay50ms();
		sprintf(send,"temp2:%.1f\r\n",temp2);//拼接字符串
		UART_SendString(send);//串口发送温度
	}
}

(3)输出hex文件

在这里插入图片描述
0错误0警告,输出文件成功。
在这里插入图片描述

三、功能测试

1、导入文件

将编译的文件导入仿真,双击芯片进行添加。
在这里插入图片描述

2、运行仿真测试

在这里插入图片描述
可以看到,串口正常输出数据,并且数据与三个DS18B20的数据一一对应,测试成功。
在这里插入图片描述

四、总结

本章主要讲解了51单片机驱动多个DS18B20的进行多点温度读取的代码,可以批量复制新增,方便移植。


网站公告

今日签到

点亮在社区的每一天
去签到