蓝桥杯DS18B20学习(读取温度显示在数码管上)

DS18B20是最常见的数字温度传感器,有着诸多优点,比如:体积小;精度高(12位时精度可以达到0.625摄氏度,出厂默认12位);接线简单,无需外围短路;封装形式多样,能满足不同应用需求等等。DS18B20工作时序十分复杂,信号传输只在微妙之间,稍有不慎(例如延时函数的使用不够恰当)就可能导致其整个传感器的工作时序混乱。因此,在写DS18B20的控制程序时一定要弄清工作时序并使用合适的延时函数。
引脚图
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

void dsinit()//初始化
{
  DQ=0;
	Delay500us();
  DQ=1;
	Delay500us();
}

在这里插入图片描述

uchar read()
{
	uchar dat;
	uchar i;
	for(i=0;i<8;i++)
	{
	DQ=0;
	_nop_();
	dat>>=1;//循环右移补零 
	//根据芯片选择读取数据低位到高右移  反之左移
	DQ=1;
		if(DQ==1)  
	{
	  dat|=0x80;
	}		
	 Delay100us();//读的较慢至少60us 延时设置长
	}
return dat;
}



void write(uchar dat)
{
	uchar i;
	for(i=0;i<8;i++)
	{
	  DQ=0;
		DQ=dat&0x01;//0100 0100&0000 0001=0000 0000                                                
	  Delay100us();
		DQ=1;
		dat>>=1;//循环右移补零 
		//根据芯片选择读取数据低位到高右移   反之左移
	}

}

在这里插入图片描述
温度数据存储在高八位的低四位,低八位的前四位,分别读取再合并

uchar temget()//温度获取
{
	uchar temp;
	uchar low,high;
	
  dsinit();
	write(0xcc);//忽略rom指令
	write(0x44);//温度转换指令
	Delay500us();Delay500us();
	
  dsinit();
	write(0xcc);//忽略rom指令
	write(0xbe);//读取暂存器的内容
	low=read(); 
	high=read();
	
	temp=((high<<4)|(low>>4));
	return temp;
}

验证后的完整程序如下在半小时程序基础上修改,本程序不需要按键扫描

#include <STC15F2K60S2.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit s7=P3^0;
sbit s6=P3^1;
sbit DQ=P1^4;
uchar code tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF};
//0 1 2 3 4 5 6 7 8 9 - 灭
uchar code dottab[]={0X40,0X79,0X24,0X30,0X19,0X12,0X02,0X78,0X00,0X10};
//带小数点的数字,程序主要用第二位,第六位 0. 1. 2. 3. 4. 5. 6. 7. 8. 9.
uchar yi,er,san,si,wu,liu,qi,ba;

void Delay1ms(uchar ms);
void display1(uchar yi,uchar er);
void display2(uchar san,uchar si);
void display3(uchar wu,uchar liu);
void display4(uchar qi,uchar ba);
void allinit();
void keyscan();
void dsinit();
void Delay100us();
void Delay500us();
void write(uchar dat);
uchar read();
uchar temget();

void main()
{
	uchar tem;//温度
	allinit();
	yi=11,er=11,san=11,si=11,wu=11,liu=6,qi=7,ba=8;
	while(1)
	{
	 tem=temget();
		liu=tem/100;
		qi=tem%100/10;
		ba=tem%10;
		
	 display1( yi, er);
	 display2( san, si);
	 display3( wu, liu);
	 display4( qi, ba);
	 keyscan();
	}
}



void Delay100us()		//@12.000MHz
{
	unsigned char i, j;

	i = 2;
	j = 39;
	do
	{
		while (--j);
	} while (--i);
}


void Delay500us()		//@12.000MHz
{
	unsigned char i, j;

	i = 6;
	j = 211;
	do
	{
		while (--j);
	} while (--i);
}


uchar temget()//温度获取
{
	uchar temp;
	uchar low,high;
	
  dsinit();
	write(0xcc);//忽略rom指令
	write(0x44);//温度转换指令
	Delay500us();Delay500us();
	
  dsinit();
	write(0xcc);//忽略rom指令
	write(0xbe);//读取暂存器的内容
	low=read(); 
	high=read();
	
	temp=((high<<4)|(low>>4));
	return temp;
}



uchar read()
{
	uchar dat;
	uchar i;
	for(i=0;i<8;i++)
	{
	DQ=0;
	_nop_();
	dat>>=1;//循环右移补零 
	//根据芯片选择读取数据低位到高右移  反之左移
	DQ=1;
		if(DQ==1)  
	{
	  dat|=0x80;
	}		
	 Delay100us();//读的较慢至少60us 延时设置长
	}
return dat;
}



void write(uchar dat)
{
	uchar i;
	for(i=0;i<8;i++)
	{
	  DQ=0;
		DQ=dat&0x01;//0100 0100&0000 0001=0000 0000                                                
	  Delay100us();
		DQ=1;
		dat>>=1;//循环右移补零 
		//根据芯片选择读取数据低位到高右移   反之左移
	}

}


void dsinit()
{
  DQ=0;
	Delay500us();
  DQ=1;
	Delay500us();
}


void Delay1ms(uchar ms)		//@12.000MHz  最多延时255ms
{
	unsigned char i, j;
  uchar k;
	for(k=ms;k>0;k--)
	{
	i = 12;
	j = 169;
	do
	{
		while (--j);
	} while (--i);
	
	}

}


void display1(uchar yi,uchar er)
{
	P2=0XC0;
	P0=0X01;
	P2=0XE0;
	P0=tab[yi];
	Delay1ms(2);
	
	P2=0XC0;
	P0=0X02;
	P2=0XE0;
	P0=tab[er];
	Delay1ms(2);
}

void display2(uchar san,uchar si)
{
		P2=0XC0;
		P0=0X04;
		P2=0XE0;
		P0=tab[san];
		Delay1ms(2);;

		P2=0XC0;
		P0=0X08;
		P2=0XE0;
		P0=tab[si];
		Delay1ms(2);

}

void display3(uchar wu,uchar liu)
{
		P2=0XC0;
		P0=0X10;
		P2=0XE0;
		P0=tab[wu];
		Delay1ms(2);

		P2=0XC0;
		P0=0X20;
		P2=0XE0;
		P0=tab[liu];
		Delay1ms(2);
}

void display4(uchar qi,uchar ba)
{
		P2=0XC0;
		P0=0X40;
		P2=0XE0;
		P0=tab[qi];
		Delay1ms(2);

		P2=0XC0;
		P0=0X80;
		P2=0XE0;
		P0=tab[ba];
		Delay1ms(2);

}
void allinit()
{
	P2=0X80;
	P0=0XFF;//关LED
	
	P2=0XC0;
	P0=0XFF;
	P2=0XE0;
	P0=0XFF;//关数码管
	
	P2=0XA0;
	P0=0X00;//关蜂鸣器 继电器	
}

void keyscan()
{
	if(s7==0)
	{
	 Delay1ms(5);//延时消抖
		if(s7==0)
		{
			yi=11,er=11,san=11,si=11,wu=11,liu=11,qi=11,ba=11;//所有数码管灭
		}
		while(!s7);
	}
	else if(s6==0)
	{
	 Delay1ms(5);
		if(s6==0)
		{
			yi=0,er=0,san=0,si=0,wu=0,liu=0,qi=0,ba=0;//所有数码管为0
		}
		while(!s6);
	}
	
}





评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值