51蓝桥杯 DS18B20温度传感器

目录


一、DS18B20温度传感器原理

1.1 内部结构

1.2 电路图

二、DS18B20温度传感器 操作步骤

2.1 初始化

2.2 ROM操作指令

2.3 功能指令

2.4 写时序

2.5 读时序

三、代码

3.1 mian.c

3.2 bsp_onewire.c

 3.3 bsp_onewire.h

四、板子实现


一、DS18B20温度传感器原理

1.1 内部结构

1.2 电路图

二、DS18B20温度传感器 操作步骤

通过单线总线端口访问DS18B20的协议如下:

  1. 初始化
  2. ROM 操作指令
  3. DS18B20 功能指令
  • 每一次 DS18B20 的操作都必须满足以上步骤,若是缺少步骤或是顺序混乱,器件将不会返回值

2.1 初始化

  • 和 DS18B20 间的任何通讯都需要以初始化开始,初始化序列如上图。
  • 一个复位脉冲跟着一个存在脉冲表明 DS18B20 已经准备好发送和接收数据。

在初始化序列期间,拉低总线并保持480us 以发出(TX)一个复位脉冲,然后释放总线,进入接收状态(RX)。单总线是由5k上拉电阻拉到高电平的。当 DS18B20 检测到I/O引脚上的上升沿后,等待15-60us,然后发出一个由60-240us低电平信号构成的存在脉冲。

2.2 ROM操作指令

2.3 功能指令

2.4 写时序

有两种写时序,一种写1时序,一种写0时序。

所有写时序必须最少持续60us。包括两个写周期之间至少1us的恢复时间。

当总线从逻辑高电平拉到低电平时,写时序开始。

  • 要写一个时序时,必须把数据线拉到低电平,然后释放,在写时序后的15us释放总线。当总线被释放时,5k的上拉电阻将拉高总线(这是写1)总控制器要生成一个写0时序,必须把数据先拉到低电平并持续保持至少60us。

总结:当总线控制器初始化写时序后,DS18B20 在一个 15us 到 60us 的窗口内对I/O线采样。如果线上是高电平,就是写1。如果线上是低电平,就是写0。

2.5 读时序

总线控制器在发出“读指令”后必须立刻开始读时序。

所有的读时序必须最少60us,包括两个读周期间至少1u的恢复时间。

当总线从逻辑高电平拉到低电平时(至少保持1us),读时序开始。然后总线被释放。

DS1B20通过拉高或拉低总线来传输1或0。当传输逻辑0结束后,总线将被释放,通过上拉电阻回到上升沿状态。

三、代码

3.1 mian.c

 #include "bsp_init.h"
#include "timer.h"
#include "bsp_seg.h"
#include "bsp_key.h"
#include "stdio.h"
#include "bsp_led.h"
#include "bsp_ds1302.h"
#include "bsp_onewire.h"
/******函数声明******/
void Key_Proc();	
void Seg_Proc();
void Led_Proc();

/******数码管显示专用******/
unsigned char seg_buf[8];
unsigned char seg_string[10];
unsigned char pos = 0;

/******按键专用******/
unsigned char Key_value;
unsigned char Key_Down,Key_Old;	

/******按键和显示函数减速专用******/
unsigned int Key_Slow_Down;
unsigned int Seg_Slow_Down;	

/******ds1302专用******/
unsigned char ucRtc[3] = {11,22,33};//时分秒

unsigned int ms_count;//记录毫秒
unsigned char s_count;//记录秒

unsigned char ucled;
unsigned char state;	//运行状态,按下按键后状态state变化

void main()
{
	Cls_Peripheral();		//关闭外设

	Timer1Init();			//定时器1初始化
	EA = 1;
	
	Set_Rtc(ucRtc);			//初始化时间
	
	while(1)
	{
		Key_Proc();
		Seg_Proc();
		Led_Proc();		
	}
}

void tm1_isr() interrupt 3
{
	if(++Key_Slow_Down == 10)Key_Slow_Down = 0;
	if(++Seg_Slow_Down == 10)Seg_Slow_Down = 0;
	
	Led_Disp(ucled);
	
	if(++ms_count == 1000)		//记录运行时间
	{
		ms_count = 0;
		s_count++;
	}
	
	Seg_Disp(seg_buf,pos);
	if(++pos == 8) pos = 0;
}

void Key_Proc()								//按键处理
{
	if(Key_Slow_Down)return;
	Key_Slow_Down = 1;
	
	Key_value = Key_Read();		//读取按键按下的键码
	
	//下降沿检测
	Key_Down = Key_value & (Key_Old ^ Key_value);
	Key_Old = Key_value;
	
	if(Key_Down)
	{
		if(++state == 3)state = 0;
	}
}

void Seg_Proc()							//显示处理
{
	if(Seg_Slow_Down)return;
	Seg_Slow_Down = 1;
	
	switch(state)
	{
		case 0:
			sprintf(seg_string,"----%04.2f",read_temperature()/16.0);	//将温度显示到数码管上
			break;
		case 1:	
			Read_Rtc(ucRtc);//读取ds1302中的时间,并将其放到数组中
	        sprintf(seg_string,"%02d-%02d-%02d",(unsigned int)ucRtc[0],(unsigned int)ucRtc[1],(unsigned int)ucRtc[2]);
			break;
		case 2:
			sprintf(seg_string,"-----%3d",(unsigned int)s_count);
	}
	
	/****永远不变****/
	Seg_Tran(seg_string,seg_buf);
}

void Led_Proc()							//Led处理
{
	switch(state)
	{
		case 0:
			ucled = 0x03;break;
		case 1:
			ucled = 0x0C;break;
		case 2:
			ucled = 30;
	}
}

3.2 bsp_onewire.c

#include "bsp_onewire.h"


//单总线延时函数
 void Delay_OneWire(unsigned int t)
 {
	 unsigned char i;
	 while(t--)
	 {
		 for(i = 0;i < 12;i++);
	 }
 }
 
 void Write_DS18B20(unsigned char dat)
 {
	 unsigned char i;
	 for(i = 0;i < 8;i++)
	 {
		 DQ = 0;
		 DQ = dat & 0x01;
		 Delay_OneWire(5);
		 DQ = 1;
		 dat >>= 1;
	 }
	 Delay_OneWire(5);
 }
 
 unsigned char Read_DS18B20()
 {
	unsigned char i;
	unsigned char dat;
	 
	 for(i = 0;i < 8;i++)
	 {
		 DQ = 0;
		 dat >>= 1;
		 DQ = 1;
		 if(DQ)
		 {
			 dat |= 0x80;
		 }
		 Delay_OneWire(5);
	 }
	 return dat;
 }
 
 
 bit init_ds18b20()
 {
	 bit initflag = 0;
	 
	 DQ =1;
	 Delay_OneWire(12);
	 DQ = 0;
	 
	 Delay_OneWire(80);		//延时大于480us
	 DQ = 1;
	 Delay_OneWire(10);
	 initflag  = DQ;
	 Delay_OneWire(5);
	 
	 return initflag;
 }

 /**
   * @brief  温度读取函数
   * @param  吴
   * @retval 高、低温度的两个字节
   * @functon 温度转换,并将其返回
   */
unsigned int read_temperature()
{
	unsigned char low,high;	//返回的高、低温度(8位)
	
	init_ds18b20();			//初始化
	Write_DS18B20(0xCC);	//跳过ROM
	Write_DS18B20(0x44);	//进行温度转化
	
	init_ds18b20();			//初始化
	Write_DS18B20(0xCC);	//跳过ROM
	Write_DS18B20(0xBE);	//进行温度转化
	
	low = Read_DS18B20();	//温度低位
	high = Read_DS18B20();	//温度高位
	
	return (high << 8) | low;
}	

3.3 bsp_onewire.h

#include <STC15F2K60S2.H>

sbit DQ = P1^4;

 void Delay_OneWire(unsigned int t);
	 
 void Delay_OneWire(unsigned int t);
	 
 unsigned char Read_DS18B20();
 
 unsigned int read_temperature();

四、板子实现

用手捂住温度传感器后显示的温度

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值