蓝桥杯单片机----DS18B20的基本应用

        DS18B20是常用的数字温度传感器,其输出的是数字信号,具有体积小,硬件开销低,抗干扰能力强,精度高的特点。面对着平的那一面,左负右正,一旦接反就会立刻发热,有可能烧毁!同时,接反也是导致该传感器总是显示85℃的原因。实际操作中将正负反接,传感器立即发热,液晶屏不能显示读数,正负接好后显示85℃。另外,如果使用51单片机的话,那么中间那个引脚必须接上4.7K-10K的上拉电阻,否则,由于高电平不能正常输入/输出,要么通电后立即显示85℃,要么用几个月后温度在85℃与正常值上乱跳。

设计内容:

        1.检测室内温度,显示在数码管上,格式如下图所示:

蓝桥杯单片机----DS18B20的基本应用_第1张图片

        2.设置温度阈值为25℃,超过温度阈值L1点亮,否则L1熄灭。

        对于单总线的操作,相对于IIC,DS1302来说要简单的多,考试的时候官方是会提供这三个驱动给我们的,不太清楚的同学可以参考蓝桥杯大赛——驱动程序,官方给我们提供了这部分程序,对我们的代码编写工作量来说确实减少了很多,但这个驱动并不是可以直接拿来用的,我们还需要再写一部分程序才能真正利用到这部分代码,下面咱们就用官方提供的驱动来编程吧。

#include

#define uchar unsigned char   //定义无符号字符类型uchar
#define uint unsigned int     //定义无符号整型类型uint
	
sbit DQ = P1^4;  //单总线接口

uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff,0xc6};//数字0~9,“-”,“关”,“C”
uchar yi,er,san,si,wu,liu,qi,ba;   //定义字符型变量yi,er,san,si,wu,liu,qi,ba,当作数码管显示控制变量
uchar wendu;

void delayms(int ms);          //延时函数
void allinit();                //初始化函数
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 Delay_OneWire(unsigned int t);
void Write_DS18B20(unsigned char dat);
unsigned char Read_DS18B20(void);
bit init_ds18b20(void);
unsigned char Tempget();

void main()//主函数
{
	allinit();                  //初始化函数
	yi=11;er=11;san=11;si=11;wu=11;liu=11;qi=11;ba=11;//让数码管全部熄灭
	while(1)
	{
		wendu=Tempget();                 //获取温度
		liu=wendu/10;qi=wendu%10;ba=12;  //把获取到的温度和标识符C显示在第六、七、八位数码管上
		if(wendu>25){P2=0X80;P0=0XFE;}   //温度大于25℃,L1点亮
		else {P2=0X80;P0=0XFF;}          //否则L1熄灭
		display1(yi,er);          //第一、二段数码管函数
		display2(san,si);         //第三、四段数码管函数
		display3(wu,liu);         //第五、六段数码管函数
		display4(qi,ba);          //第七、八段数码管函数
	}
}
void delayms(int ms)//延时函数
{
	uint i,j;
	for(i=ms;i>0;i--)
		for(j=845;j>0;j--);
}
void allinit()//初始化函数
{
	P2=0XA0;P0=0X00;      //关闭蜂鸣器继电器
	P2=0X80;P0=0XFF;      //关闭所有LED灯
	
	P2=0XC0;P0=0XFF;      //选中所有数码管段选
	P2=0XFF;P0=0XFF;      //关闭所有数码管
}
void display1(uchar yi,uchar er)//第一、二段数码管函数
{
	P2=0XC0;P0=0X01;               //选中第一个数码管段选
	P2=0XFF;P0=tab[yi];            //让第一个数码管显示yi指向的值
	delayms(1);                    //延时1ms
	
	P2=0XC0;P0=0X02;               //选中第二个数码管段选
	P2=0XFF;P0=tab[er];            //让第一个数码管显示er指向的值
	delayms(1);	                   //延时1ms
}
void display2(uchar san,uchar si)//第三、四段数码管函数
{
	P2=0XC0;P0=0X04;               //选中第s三个数码管段选
	P2=0XFF;P0=tab[san];           //让第一个数码管显示san指向的值
	delayms(1);                    //延时1ms
	
	P2=0XC0;P0=0X08;               //选中第四个数码管段选
	P2=0XFF;P0=tab[si];            //让第一个数码管显示si指向的值
	delayms(1);	                   //延时1ms
}
void display3(uchar wu,uchar liu)//第五、六段数码管函数
{
	P2=0XC0;P0=0X10;               //选中第五个数码管段选
	P2=0XFF;P0=tab[wu];            //让第一个数码管显示wu指向的值
	delayms(1);                    //延时1ms
	
	P2=0XC0;P0=0X20;               //选中第六个数码管段选
	P2=0XFF;P0=tab[liu];           //让第一个数码管显示liu指向的值
	delayms(1);	                   //延时1ms
}
void display4(uchar qi,uchar ba)//第七、八段数码管函数
{
	P2=0XC0;P0=0X40;               //选中第七个数码管段选
	P2=0XFF;P0=tab[qi];            //让第一个数码管显示qi指向的值
	delayms(1);                    //延时1ms
	
	P2=0XC0;P0=0X80;               //选中第八个数码管段选
	P2=0XFF;P0=tab[ba];            //让第一个数码管显示ba指向的值
	delayms(1);                    //延时1ms
	P2=0XC0;P0=0X80;               //选中第八个数码管段选
	P2=0XFF;P0=0XFF;               //让第八个数码管熄灭
}
/*********************** DS18B20驱动程序 ************************/

//单总线延时函数
void Delay_OneWire(unsigned int t)  
{
	while(t--);
}


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

//从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(50);
	}
	return dat;
}

//DS18B20设备初始化
bit init_ds18b20(void)
{
  	bit initflag = 0;
  	
  	DQ = 1;
  	Delay_OneWire(120);
  	DQ = 0;
  	Delay_OneWire(800);
  	DQ = 1;
  	Delay_OneWire(100); 
    	initflag = DQ;     
  	Delay_OneWire(50);
  
  	return initflag;
}

//DS18B20温度获取
unsigned char Tempget()          //温度的读取,可参照DS18B20芯片手册
{
	unsigned char temp,low,high; //定义无符号字符型变量temp,low,high;
	init_ds18b20();              //DS18B20设备初始化
	Write_DS18B20(0xcc);         //通过单总线向DS18B20写0xcc:这条命令允许总线控制器不用提供64位ROM编码就使用存储器操作命令,在单总线情况下右以节省时间。
	Write_DS18B20(0x44);         //这条命令启动一次温度转换而无需其他数据。
	Delay_OneWire(200); 	     //延时
	
	init_ds18b20();              //DS18B20设备初始化
	Write_DS18B20(0xcc);         //通过单总线向DS18B20写0xcc:这条命令允许总线控制器不用提供64位ROM编码就使用存储器操作命令,在单总线情况下右以节省时间。
	Write_DS18B20(0xbe);	     //这个命令读取暂存器的内容。
	
	low=Read_DS18B20();          // 因为温度传感器是16位所以依次读取低八位和高八位
	high=Read_DS18B20();         // 因为温度传感器是16位所以依次读取低八位和高八位
	
	temp=high<<4;                //高四位是符号位不要
	temp|=(low>>4);			     //低四位是小数位不要,让去除符号的高四位或上去除小数的低四位,即温度的值
	
	return temp;                 //返回temp
}

 

你可能感兴趣的:(《蓝桥杯》系列,蓝桥杯,单片机)