当前日期:2021年09月25日 星期六
Hi 你好,欢迎访问!登录
搜索 导航

凯特网-Think and Do it , as Soon as!

当前位置:首页 - 实用案例 - 正文
阅读模式

基于STC15单片机及DS18B20的测温实操

2015-10-22 | 实用案例 | caterwang | 3161°c

    对于DS18B20,之前在AT89C51上有一次调试经历,后面没再接触过了。这次由于实际需要,又用到了DS18B20。当把旧程序移过去之后,傻眼了,不成功!于是开始了漫长的调试过程!之前有一篇文章也分享过DS18B20的驱动程序了,关于DS18B20的时,大家可以自己查阅手册,只需要记住,这个片子,对时序要求还是高的。这是旨在分享自己真实可用的程序,对于时序部分的控制,为便于大家移植,已经做成固定函数,到时大家把对应的函数改一下就行了。

  1. 电路图


    blob.png

2.驱动程序--以个人经验,初始化程序很重要

blob.png

#include <intrins.h>
#include "STC15F2K60S2.H"
#include "DS18B20.H"
#include "max7219.h"
#include "mainapp.h"
void Delay5us()		//@22.1184MHz
{
	unsigned char i;

	_nop_();
	i = 24;
	while (--i);
}
void Delay5us_xn(int x)
{
	while(x--)
	{
	Delay5us();
	}
}
/**************复位***********************/
unsigned char DS1B20Init(void)
{
	unsigned char i;
	DQ=1;
	_nop_();
	DQ=0;
	Delay5us_xn(96);			//延时480us
	DQ=1;
	Delay5us_xn(12);			//延时60us
	i=0;
	while(DQ)				//在480us内检测DQ是否变为低,如果为低则复位成功,否则复位不成功
	{
		Delay5us();
		i++;
		if(i>96)
			{
			i=255;
			break;
			}
	}
	if(i==255)
		return 0;                      //初始化失败
	while(!DQ);				//等待DS18B20释放总线
	return 1;				//初始化成功
}

/**********写一个字节数据到DS18B20***********/
void WriteDat(unsigned char dat)
{
	unsigned char i;
	for (i=8; i>0; i--) //
	{
		DQ=1;
		_nop_();_nop_(); 
		DQ=0;
		Delay5us();
		DQ=dat&0x01;      //最低位移出
		Delay5us_xn(13);
		dat=dat/2;          //右移一位
	}
	DQ=1;
	Delay5us_xn(2);
}
/**********读一个字节数据从DS18B20***********/
unsigned char ReadDat(void)
{
	unsigned char dat,i;
	for (i=8;i>0;i--)
	{
		DQ=1;_nop_();_nop_();
		dat>>=1;
		DQ=0;             //
		Delay5us_xn(1);
		DQ=1;
		Delay5us_xn(1);
		if(DQ)
			dat|=0x80;
		Delay5us_xn(13);
	}
	DQ=1;
	return(dat);
}
void GetTep(unsigned char *TempDat)
{
	unsigned char TPH=0;
	unsigned char TPL=0;
	EA = 0;
	if(DS1B20Init())
	{
		WriteDat(0xCC);	 //跳过器件匹配
		WriteDat(0x44);	 //发出温度转换命令
		if(DS1B20Init())
		{
			WriteDat(0xCC);	 //跳过器件匹配
			WriteDat(0xBE);	 //发出读数据命
			TPL=ReadDat();	 //低八位
			TPH=ReadDat();	 //高八位

			if(TPH>0xf8)	//负温度(TPH高五位是1)求补码
			{
				TPH=(256-TPH);
				TPL=(256-TPL);
				TempDat[2]=1; //表示0度以下
			}
			TempDat[1]=(TPL&0x0f)*0.625;
			if(TempDat[1]>9) 
				TempDat[1]=9;
			TempDat[0]=((TPL&0xf0)>>4)|((TPH&0x0f)<<4);//

			Dot[0]=0;
			Dot[1]=0;
			Dot[2]=1;
			Dot[3]=0;
		}	
		else
		{
		DisDat[0]=7;
		DisDat[1]=7;
		DisDat[2]=7;
		DisDat[3]=7;

		Dot[0]=1;
		Dot[1]=1;
		Dot[2]=1;
		Dot[3]=1;
		}
	}
	else
	{
		DisDat[0]=8;
		DisDat[1]=8;
		DisDat[2]=8;
		DisDat[3]=8;

		Dot[0]=1;
		Dot[1]=1;
		Dot[2]=1;
		Dot[3]=1;	
	}
	EA = 1;
}

3.演示程序

#include <intrins.h>
#include "STC15F2K60S2.H"
#include "DS18B20.H"
#include "max7219.h"
#include "mainapp.h"
/********************************************************
系统初始化程序,用于配置硬件和变量初始化设置
*********************************************************/
void SysInsatll(void)
{
	AUXR &= 0x7F;		//定时器时钟12T模式//50毫秒@12.000MHz
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x01;		//设置定时器模式
	TL0 = 0xB0;		//设置定时初值
	TH0 = 0x3C;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	ET0 = 1;		//允许定时器中断0
	TR0 = 1;		//定时器0开始计时
	EA=1;	  					//开总中断
}
unsigned int uiTestNum  = 1000;
unsigned char tc=0;		//读温度值的时间间隔控制【tc*50ms】
unsigned char tck=0;	//前10次读出的数据不要,当tck的值为255时温度值才是有效值
unsigned char tepd[3]={0};
void main(void)
{
	DisDat[0]=1;DisDat[1]=2;DisDat[2]=3;DisDat[3]=4;
	Dot[0]=0;Dot[1]=0;Dot[2]=1;Dot[3]=0;	
	InitialMax7219(); 						//MAX7219初始化
	P1=0xff;
	DisPlay();		//显示子程序
	SysInsatll();							//系统(中断及IO口)初始化
        DelayNx10ms(1);						//等待主机启动
	//DisDat[0]=0;DisDat[1]=0;DisDat[2]=0;DisDat[3]=0;
	while(1)
		{
		DisPlay();		//显示子程序
		}
}
/**********************定时中断0服务子程序[用于显示控制及10ms计时]*******************************/
//1.可以通过设置Time门限控制LED数码管闪烁位的频率; 
void DisPlayTimeInt0(void) interrupt 1   using 2//计时,精确到10ms
 	{
		//float temp;
		TR0 = 0;
		TF0 = 0;

		tc++;
		if(tc==10)
			{
			//tepd=GetTep();	 //读温度值
			GetTep(tepd);
			tc=0;
			tck++;
			if(tck>10) 
				{
				tck=255; //前10次读出的数据不要,当tck的值为255时温度值才是有效值
				}
			}
			/*
		if(tepd[2]) //温度是0度下则当0度
			{
			tepd[0]=0;
			tepd[1]=0;
			}
			*/
		if(tck==255)
			{
			DisDat[0]=(tepd[0]/100);
			DisDat[1]=((tepd[0]%100)/10);
			DisDat[2]=((tepd[0]%100)%10);
			DisDat[3]=(tepd[1]);
			}
		TL0 = 0xB0;		//设置定时初值
		TH0 = 0x3C;		//设置定时初值	
		TR0 = 1;					
	}

以上为主要部分和程序,需要完整工程代码,请到这里下载:http://pan.baidu.com/s/1pJqwLsR

blob.png

请使用支付宝赞助我

支付宝打赏

请使用微信赞助我

微信打赏

版权声明

欢迎转载,但注明出处,谢谢!

分享:
0
QR:  基于STC15单片机及DS18B20的测温实操

扫一扫,用手机打开吧

共0条评论

暂时没有评论,你可以来抢个沙发!

发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

展开