C51单片机——温度传感器

实现效果如图:
在这里插入图片描述

main.c

#include<string.h>
#include"typedef.h"
#include"lcd1602.h"
#include"ds18b20.h"
uchar str1[]={
    
    "Test by Ds18b20."};
uchar str2[11]={
    
    "Temp:      "};

void main()
{
    
    
	uchar i;
	lcd1602_init();
	while(1)
	{
    
    
		DS18B20_Read_Temperature();
		Temperature_Convert();
		lcd1602_write_cmd(0x80);
		for(i=0;i<strlen(str1);i++)
		{
    
    
			lcd1602_write_dat(str1[i]);
		}
		lcd1602_write_cmd(0xC0);
		for(i=0;i<11;i++)
		{
    
    
			lcd1602_write_dat(str2[i]);
		}
	}
}
		
		

lcd1602.c

#include<reg52.h>
#include"delay.h"
#include"typedef.h"
#include"lcd1602.h"
sbit RS=P2^6;
sbit RW=P2^5;
sbit EN=P2^7;
sbit P07=P0^7;
bit lcd1602_read_status()
{
    
    
	uchar temp;
	RW=1;delay(2);
	RS=0;delay(2);
	EN=1;delay(2);
	temp=P0;delay(2);
	EN=0;delay(2);
	return (bit)(temp&0x80);
}

void lcd1602_write_cmd(uchar cmd)
{
    
    
	while(lcd1602_read_status()!=0);
	RW=0;delay(2);
	RS=0;delay(2);
	EN=1;delay(2);
	P0=cmd;delay(2);
	EN=0;delay(2);
}

void lcd1602_write_dat(uchar dat)
{
    
    
	while(lcd1602_read_status()!=0);
	RW=0;delay(2);
	RS=1;delay(2);
	EN=1;delay(2);
	P0=dat;delay(2);
	EN=0;delay(2);
}

void lcd1602_init()
{
    
    
	lcd1602_write_cmd(0x38);
	lcd1602_write_cmd(0x0c);
	lcd1602_write_cmd(0x01);
	lcd1602_write_cmd(0x06);
	delay(200);
}

#include<reg52.h>
#include<INTRINS.H>
#include"typedef.h"
#include"delay.h"
#include"ds18b20.h"
sbit DQ=P3^7;
uint tvalue;
uchar tflag;
extern uchar str1[];
extern uchar str2[11];

void DS18B20_Reset()
{
    
    
	DQ=1;
	_nop_();
	DQ=0;
	delay(90);
	DQ=1;
	while(DQ);
	while(!DQ);
}

void DS18B20_Write_Byte(uchar dat)
{
    
    
	uchar i;
	for(i=0;i<8;i++)
	{
    
    
		DQ=0;
		delay(1);
		DQ=(bit)(dat&0x01);
		delay(6);
		DQ=1;
		delay(1);
		dat=dat>>1;
	}
}
unsigned char DS18B20_Read_Byte()
{
    
    
	uchar i,temp=0;
	for(i=0;i<8;i++)
	{
    
    
		temp=temp>>1;
		DQ=0;
		_nop_();
		_nop_();
		DQ=1;
		delay(2);
		if(DQ)
			temp=temp|0x80;
		delay(6);
		DQ=1;
		delay(1);
	}
	return temp;
}


int DS18B20_Read_Temperature()
{
    
    
	uchar temp_low,temp_high;
	DS18B20_Reset();
	DS18B20_Write_Byte(0xcc);
	DS18B20_Write_Byte(0x44);
	while(!DQ);
	DS18B20_Reset();
	DS18B20_Write_Byte(0xcc);
	DS18B20_Write_Byte(0xbe);
	temp_low=DS18B20_Read_Byte();
	temp_high=DS18B20_Read_Byte();
	DS18B20_Reset();
	tvalue=temp_high;
	tvalue=(tvalue<<8)|temp_low;
	if(tvalue<=0x07ff)
			tflag=0;
	else
	{
    
    
		tvalue=~tvalue+1;
		tflag=1;
	}
	tvalue=tvalue*0.625;
	return(tvalue);
}
	
void Temperature_Convert()
{
    
    
	str2[6]=(uchar)(tvalue/1000+'0');
	str2[7]=(uchar)(tvalue%1000/100+'0');
	str2[8]=(uchar)(tvalue%100/10+'0');
	str2[9]='.';
	str2[10]=(uchar)(tvalue%10+'0');
	if(tflag==0)
		str2[5]='\0';
	else
		str2[5]='-';
	if(str2[6]=='\0')
	{
    
    
		str2[6]='\0';
		if(str2[7]=='0')
		{
    
    
			str2[7]='\0';
		}
	}
}

delay.c

#include"typedef.h"
void delay(uint x)
{
    
    
	while(--x);
}

typedef.h

#ifndef _TYPEDEF_H_
#define _TYPEDEF_H_
	#define uchar unsigned char
	#define uint unsigned int
#endif

delay.h

#ifndef _DELAY_H_
#define	_DELAY_H_
	extern void delay(unsigned int x);
#endif

ds18b20.h

#ifndef _DS18B20_H_
#define _DS18B20_H_
	extern void DS18B20_Reset();
	extern void DS18B20_Write_Byte(uchar dat);
	extern unsigned char DS18B20_Read_Byte();
	extern int DS18B20_Read_Temperature();
	extern void Temperature_Convert();
#endif

lcd1602.h

#ifndef _LCD1602_H_
#define _LCD1602_H_
	extern bit lcd1602_read_status();
	extern void lcd1602_write_cmd(uchar cmd);
	extern void lcd1602_write_dat(uchar dat);
	extern void lcd1602_init();
#endif

> 单片机读DSI18B20所测得的温度流程

使用单片机读DS18B20所测得的温度的流程:
单片机先向DS18B20发出启动测量命令,DS18B20收到单片机向DS18B20此命令后启动温度测量,并将测量结果保存在RAM的第0、1字节:随后单片向DS18B20发出读命令,DS18B20收到此命令后将RAM的数据从Byte0字节开始逐字节送出,此时单片机接收到的前两个字节内容即为测量所得温度值。

启动温度测量可以细分为以下步骤

(1)复位DS18B20。

(2)单片机向DS18B20发送ROM指令0x55,匹配每个DS18B20独有的64位序列号。不过如果总线上只有一个DS18B20,则不需匹配序列号,写代码时直接写ROM命令0xcc跳过。

(3)单片机向DS18B20发送RAM指令0x44,启动DS18B20进行温度测量。
(4)等待温度测量完成。

读温度步骤可以细分为以下步骤。

(1)复位DS18B20。

匹配每个DSI8B20独有的64位序列

(2)单片机向DS8B820发送ROM指s值配序列号,写代码时直接写ROM的令号。不过如果总线上只有一个DS820则不需匹配序列号,写代码时直接写ROM命令0xcc跳过。
(3)单片机向DS18B20发送读RAM指令0xBE,收到此命令后DS18B20将RAM中的数据从字节0~8,一个一个送出,如果在此过程中要停止读操作,必须对DS1820进行复位。

猜你喜欢

转载自blog.csdn.net/weixin_53391957/article/details/117951570