04_蓝桥杯_ds18b20

蓝桥杯杯板子上的DS18B20温度传感器,通信方式为单总线通信。

  • 测量范围:+125~-55
  • 代表意义:看芯片手册

在这里插入图片描述
在这里插入图片描述
存储温度的暂存区总共有16位,其中12~16位代表是正负极
低四位代表是小数部分。
读温度分两次读,一次读八位,

  • 命令说明:只说明我们用的到的,如果需要深入了解请查阅手册
    0x44 :温度转换,
    0xbe:读取暂存器和CRC字节
    0xcc:忽略
    在这里插入图片描述

  • 时序图

  • 在这里插入图片描述

#include <stc15f2k60s2.h>
#include <intrins.h>

#define uchar unsigned char 
#define uint unsigned int 



//sbit DQ = P1^4;  //单总线接口
sbit DQ = P4^1;  //单总线接口
uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,
									0x92,0x82,0xf8,0x80,0x90,
									0xbf,0xff};//0123456789-灭
int tt=0;
uchar wendu;
uchar min=20,max=30;
uchar yi,er,san,si,wu,liu,qi,ba;
uchar shezhi,jia,jian,qingchu,flag;
									
/*DS18B20*/									
//单总线延时函数
void Delay_OneWire(unsigned int t) ; //STC89C52RC
//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat);
//从DS18B20读取一个字节
unsigned char Read_DS18B20(void);
//DS18B20设备初始化
bit init_ds18b20(void);

uchar temget(); //用ds18b20获取温度									
									
void init();
void delay1ms(uint ms);//延时n个一毫秒
void key_scan();
void Timer0Init(void)	;	//5毫秒@11.0592MHz
/*数码管*/
void display12(uchar yi,uchar er);
void display34(uchar san,uchar si);
void display56(uchar wu,uchar liu);
void display78(uchar qi,uchar ba);

void main()
{
 init();
	yi=11;er=11;san=11;si=11;
	wu=11;liu=11;//qi=11;ba=11;
	Timer0Init();

	while(1)
	{
		if(shezhi==0)
		{
			EA=1;		//开总中断
			ET0=1;//开启中断0
			P2=((P2&0x1f)|0x80);
			P0=0XFE;
			P2&=0x1f;
			wendu=temget();
			yi=11;er=11;san=11;si=11;
			wu=11;liu=11;qi=wendu/10;;ba=wendu%10;
		}
		else if(shezhi==1)
		{
			EA=0;		//关闭总中断
			ET0=0;//关闭中断0
			P2=((P2&0x1f)|0x80);
			P0=0X7E;
			P2&=0x1f;
			if(flag==1)
			{
				if(jia==1)
				{
					jia=0;
					if(min>=0)
					{
						min=min+1;
					}		
				}
				else if(jian==1)
				{
					jian=0;
					if(min>0)
					{
						min=min-1;
					}
					else
						{
						min=0;
						}
				}
			}
			else if(flag==0)
			{
				if(jia==1)
				{
					jia=0;
					max=max+1;
				}
				else if(jian==1)
				{
					jian=0;
					max=max-1;
				}
			}
			
			yi=10;er=min/10;san=min%10;si=11;
			wu=11;liu=10;qi=max/10;ba=max%10;
		}
		  key_scan();
		  display12(yi,er);
			display34(san,si);
			display56(wu,liu);
			display78(qi,ba);
		
	}
}



uchar  temget()
{
	uchar temp ,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<<4);
	temp=(low>>4)|temp;
	return temp;
	
}

void Timer0Init(void)		//5毫秒@11.0592MHz
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x00;		//设置定时初值
	TH0 = 0x28;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
}

void timer0() interrupt 1
{
	tt++;
	if(tt>=200)
	{
		tt=0;
		if(wendu<min)
		{
			P2=((P2&0X1F)|0xa0);
			P0=0x40;
			P2&=0X1F;
			
			P2=((P2&0X1F)|0x80);
			P0=0xff;
			P2&=0X1F;
			
		}
		else if((wendu<max)&&(wendu>min))
		{
			P2=((P2&0X1F)|0xa0);
			P0=0x00;
			P2&=0X1F;
			
			P2=((P2&0X1F)|0x80);
			P0=0xff;
			P2&=0X1F;			
		}
		else if(wendu>max)
		{
			P2=((P2&0X1F)|0xa0);
			P0=0x50;
			P2&=0X1F;
			
			P2=((P2&0X1F)|0x80);
			P0=0xfe;
			P2&=0X1F;		
		}
	}
	
	
}


void key_scan()
{
		if(P30==0)//S7
		{
			delay1ms(5);
			if(P30==0)
			{
				if(shezhi==0)//反转模式
				{
					shezhi=1;
				}
				else if(shezhi==1)
				{
					shezhi =0;
				}
				
				
			}
			while(!P30);
			
		}
		if(P31==0)//S6	修改最大值与最小值的切换
		{
			delay1ms(5);
			if(P31==0)
			{
				if(flag==0)
				{
					flag=1;
				}
				else if(flag==1)
				{
					flag=0;
				}
			}
			while(!P31);			
		}
		
		if(P32==0)//S5  //加
		{
			delay1ms(5);
			if(P32==0)
			{
				jia=1;	
			}
			while(!P32);			
		}
		
		if(P33==0)//S4 //减
		{
			delay1ms(5);
			if(P33==0)
			{
			jian=1;
				
				
			}
			while(!P33);			
		}
	
}

void display12(uchar yi,uchar er)
{
	P2=((P2&0X1F)|0Xc0);
	P0=0x01;//数码管段选关
	P2&=0x1f;
	
	P0=0xff;//消隐
	
	P2=((P2&0X1F)|0XE0);
	P0=tab[yi];//数码管位选关
	P2&=0x1f;
	
	delay1ms(1);
	
	P2=((P2&0X1F)|0Xc0);
	P0=0x02;//数码管段选关
	P2&=0x1f;
	
	P0=0xff;//消隐
	
	P2=((P2&0X1F)|0XE0);
	P0=tab[er];//数码管位选关
	P2&=0x1f;
	
	delay1ms(1);
}
void display34(uchar san,uchar si)
{
	P2=((P2&0X1F)|0Xc0);
	P0=0x04;//数码管段选关
	P2&=0x1f;

	
	P2=((P2&0X1F)|0XE0);
	P0=tab[san];//数码管位选关
	P2&=0x1f;
	
	delay1ms(1);
	
	P2=((P2&0X1F)|0Xc0);
	P0=0x08;//数码管段选关
	P2&=0x1f;
	

	
	P2=((P2&0X1F)|0XE0);
	P0=tab[si];//数码管位选关
	P2&=0x1f;
	
	delay1ms(1);
	
}
void display56(uchar wu,uchar liu)
{
	P2=((P2&0X1F)|0Xc0);
	P0=0x10;//数码管段选关
	P2&=0x1f;
	

	
	P2=((P2&0X1F)|0XE0);
	P0=tab[wu];//数码管位选关
	P2&=0x1f;
	
	delay1ms(1);
	
	P2=((P2&0X1F)|0Xc0);
	P0=0x20;//数码管段选关
	P2&=0x1f;
	

	
	P2=((P2&0X1F)|0XE0);
	P0=tab[liu];//数码管位选关
	P2&=0x1f;
	
	delay1ms(1);
	
}
void display78(uchar qi,uchar ba)
{
	P2=((P2&0X1F)|0Xc0);
	P0=0x40;//数码管段选关
	P2&=0x1f;
	

	P2=((P2&0X1F)|0XE0);
	P0=tab[qi];//数码管位选关
	P2&=0x1f;
	
	delay1ms(1);
	
	P2=((P2&0X1F)|0Xc0);
	P0=0x80;//数码管段选关
	P2&=0x1f;
	

	
	P2=((P2&0X1F)|0XE0);
	P0=tab[ba];//数码管位选关
	P2&=0x1f;
	delay1ms(1);
	
}
void delay1ms(uint ms)
{
	uchar i,j,k;

	_nop_();
	_nop_();
	for(i=0;i<6;i++)
		for(j=0;j<93;j++)
			for(k=0;k<ms;k++);
}
void init()
{
//单总线延时函数
void Delay_OneWire(unsigned int t)  //STC89C52RC
{
	unsigned char i;
	while(t--)
		{
		for(i=0; i<8; i++);
		}
}

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

//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{
	unsigned char i;
	unsigned char dat;
  
	for(i=0;i<8;i++)
	{
		DQ = 0;
		dat >>= 1;
		DQ = 1;
		if(DQ)
		{
			dat |= 0x80;
		}	    
		Delay_OneWire(10);
	}
	return dat;
}

//DS18B20设备初始化
bit init_ds18b20(void)
{
  	bit initflag = 0;
  	
  	DQ = 1;
  	Delay_OneWire(24);
  	DQ = 0;
  	Delay_OneWire(160);
  	DQ = 1;
  	Delay_OneWire(20); 
    initflag = DQ;     
  	Delay_OneWire(10);
  
  	return initflag;
}





版权声明:本文为weixin_44653395原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_44653395/article/details/89645476