温度检测系统

温度检测系统【数码管显示】(实训周,附代码)


期末到了,刚刚好是实训周,做了个温度检测系统。大家交流交流!

如果有什么错误欢迎指出,本人感激不尽!

///////////////////////////////////////////分///割///线//////////////////////////////////////////////////////

用的是学校的单片机开发仪。

在开始写程序前,要把思路整理清楚:

先从DS18B20数字温度传感器获得当前的温度数据,然后再把温度数据显示在数码管上。

那么怎么从DS18B20数字温度传感器里获得数据呢?

引用百科的数据:

DS18B20的读写时序和测温原理与DS1820相同,只是得到的温度值的位数因分辨率不同而不同,且温度转换时的延时时间由2s减为750ms。 DS18B20测温原理如图3所示。图中低温度系数晶振的振荡频率受温度影响很小,用于产生固定频率的脉冲信号发送给计数器1。高温度系数晶振随温度变化其振荡频率明显改变,所产生的信号作为计数器2的脉冲输入。计数器1和温度寄存器被预置在-55℃所对应的一个基数值。计数器1对低温度系数晶振产生的脉冲信号进行减法计数,当计数器1的预置值减到0时,温度寄存器的值将加1,计数器1的预置将重新被装入,计数器1重新开始对低温度系数晶振产生的脉冲信号进行计数,如此循环直到计数器2计数到0时,停止温度寄存器值的累加,此时温度寄存器中的数值即为所测温度。斜率累加器用于补偿和修正测温过程中的非线性,其输出用于修正计数器1的预置值。

通俗点来讲,DS18B20数字温度传感器只有一个用于传数据的引脚线,所以它用了单总线协议。通过控制高低电平的时间来传输数据。(硬件上的简单带来的是软件上的复杂)

那么,我们既然要使用DS18B20,那么初始化就是必要的了。为了检测单片机有没有DS18B20和“告诉”DS18B20你要准备工作了。

初始化

温度检测系统_第1张图片

首先,总线置0,然后至少延时480us,然后在拉高总线;接着延时60us后检测总线(因为DS18B20的响应时间为5~60us),看看是否为低电平,如果是低电平就是说明总线那头有DS18B20,如果不是就说明没有。不过在这里要注意,检测的时间最小要480us,所以还要延时哦。

读数据

这个是要读取从DS18B20发送回单片机的数据。时序图如下:


温度检测系统_第2张图片

(1).先把总线拉低(置0)。 

(2).延时15us。 

(3).将数据线拉高“1”,释放总线准备读数据。 

(4).读取总线的数据(就是看看是0或1)【变量=总线】。 

(5).读数据线的状态得到1个状态位,并进行数据处理。 

(6).延时45微妙。 

(7).重复1~7步骤,直到读完一个字节(8bite)。

写数据

这是为了写RAM指令和ROM指令。

温度检测系统_第3张图片

(1).总线先置低电平“0” 

(2).延时1us。 

(3).按从低位到高位的顺序发送数据(一次只发送一位)。 

(4).延时60微妙。 

(5).将数据线拉到高电平。 

(6).重复1~5步骤,直到发送完整的字节。 

指令表:

温度检测系统_第4张图片

温度检测系统_第5张图片

写完了以上的基本函数,DS18B20的准备工作就差不多了!

接下来就是启动温度转化;“叫DS18B20”发送数据;数据转化等函数了……

我们获取到了温度数据后,把温度数据的每一位提取出来,存放进数组里,按位显示在数码管上。

数码管显示就不多说了。


开发条件(DS18B20数字温度传感器,89C52单片机,数码管)

温度检测系统_第6张图片


Keil 4软件

温度检测系统_第7张图片

代码如下:(变量和函数的命名有点浪,看起来可能有点吃力)
//main.c
#include 
#include "001.h"

typedef unsigned int u16;	 
typedef unsigned char u8;
u8 code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//共阴极数码管字码

sbit pca=P2^2;
sbit pcb=P2^3;
sbit pcc=P2^4;

unsigned char wendu[8];

void daley(u16 i){
	while(i--);
}

//数据处理(获取数据,进行处理,得到想要的数字)
void tp(int date){
	 float wd;
	 if(date<0)
	 {
	 	wendu[0]=0x40;
	 	date=date-1;
	 	date=~date;
		wd=date;
		date=wd*0.0625*100+0.5;

	 }
	 else
	 {
	 	 wendu[0]=0x00;
		 wd=date;
		 date=wd*0.0625*100+0.5;
	 }
	 wendu[1] = smgduan[date / 10000];			//第五位
	 wendu[2] = smgduan[date % 10000 / 1000];		//第四位
	 wendu[3] = smgduan[date % 1000 / 100] | 0x80;		//第三位
	 wendu[4] = smgduan[date % 100 / 10];			//第二位
	 wendu[5] = smgduan[date % 10];				//第一位
	 
}
//显示数据
void sdp(){

	
	u8 i;
	for(i=0;i<6;i++)
	{
		switch(i)
		{
			case(0): pca=0;pcb=0;pcc=0;break;
			case(1): pca=1;pcb=0;pcc=0;break;
			case(2): pca=0;pcb=1;pcc=0;break;
			case(3): pca=1;pcb=1;pcc=0;break;
			case(4): pca=0;pcb=0;pcc=1;break;
			case(5): pca=1;pcb=0;pcc=1;break;

		}
		P0=wendu[5-i];
		daley(100);
		P0=0x00;
	}
}
void main(){

	int date;

	while(1)
	{
		date=drt();
		tp(date);//处理
		sdp();//显示
	}
}

001.c

#include "001.h"
#include "intrins.h"
//#include "time .h"
////////各种延时函数////////////////
void Delay1ms(unsigned int y) //1ms
{
	unsigned int x;
	for( ; y>0; y--)
	{
		for(x=110; x>0; x--);
	}
}
void delay600us(void)   //600us
{
    unsigned char a,b;
    for(b=119;b>0;b--)
        for(a=1;a>0;a--);
}
//void delay10us(void)   //10us
//{
//    unsigned char a,b;
//    for(b=1;b>0;b--)
//        for(a=1;a>0;a--);
//}
void delay45us(void)   //45us
{
    unsigned char a;
    for(a=20;a>0;a--);
}
void delay60us(void)   //60us
{
    unsigned char a,b;
    for(b=11;b>0;b--)
        for(a=1;a>0;a--);
}
void delay15us(void)   //15us
{
    unsigned char a;
    for(a=5;a>0;a--);
}

////////////////////////////////////////////

// DS18B20初始化
uchar key()
{
	uchar x,i=0;
	s=0;

	delay600us();

	s=1;
	delay60us();
	i=s;
	delay600us();
	return x;

//	while(s)
//	{
//		delay600us();
//		i++;
//		if(i>5){
//			return 0;
//		}
//	}
//	return 1;	
}
//读时序
uchar drb()
{	
	uint i;
	uchar shuju,bi;
	
	for(i=8;i>0;i--)
	{
		s=0;
		delay15us();
		s=1;
		//delay10us();
				
		bi=s;
		shuju = (shuju >> 1) | (bi << 7);
		
		delay45us();
	}
	return shuju;
}
//写时序
void dwb(uchar i)
{
	uint m, j;
	for(m=8;m>0;m--){
		s=0;
		j++;

		s=i&0x01;
		delay60us();
		s=1;
		i>>=1;	 
	}
}
//“叫DS18B20”发送数据
void drtc()
{
	 key();
	 Delay1ms(1);
	 dwb(0xcc);//
	 dwb(0xbe);//
	   
}
//启动温度转化
void dct()
{
	 key();
	 Delay1ms(1);
	 dwb(0xcc);
	 dwb(0x44);
	   
}
//温度转化
int drt(){
	
	uint L,H,time=0;//l为低,h为高
	
	dct();
	drtc();

	L=drb();
	H=drb();

	time=H;
	time<<=8;
	time|=L;
	return time; 
}

001.h

#ifndef _001_h_
#define _001_h_

#include "regx52.h"

#ifndef uchar
#define uchar unsigned char
#endif

#ifndef uint
#define uint unsigned int 
#endif

sbit s=P3^7;
void Delay1ms(uint y);
uchar key();//初始化
uchar drb();//读数据
void dwb(uchar i );        //写数据

int drt();//温度转换,取出数据
void dct();//启动温度转换
void drtc();//温度读取


#endif

应该没有多少人看到这里吧

第一次写这种博客,有什么不足请指出!谢谢!!








 
  

你可能感兴趣的:(单片机)