51单片机 | DS18B20 温度传感器实验

系统设计

设计要求

(1) 主体电路包括晶振、复位、电源指示电路,预留程序下载接口;
(2) 要求能够实现温度数值的自动显示,值根据实际温度变化自动变化。
(3) 并按照题目要求完成程序源码编写、调试及关键代码注释。

设计任务

使用给定硬件实现温度测量和显示电路的搭建和实现,完成相关代码编写,使其具备温度显示功能。

性能指标要求

(1) 要求能够实现温度数值的自动显示,值根据实际温度变化自动变化。
(2) 扩展功能: 实现打开空调控制模拟的功能,即当温度高于某一阈值时,控制空调打开;当其高于某一阈值时关闭。空调的开关控制使用一个LED灯进行模拟,如空调处于打开状态时,将某一LED灯点亮即可

设计思路及设计框图

设计思路

(1) 了解设计要求后,查询各元件的特性及使用方法
(2) 查找类似实验资料,并吸收其设计经验
(3) 由于本次下发的是万能板,需自己排版并焊接。为焊接电路的美观我决定先用AD制图软件进行排版,绘制结束后根据电路图直接焊接即可。
(4) 焊接结束后先测试数码管显示,再测试DS18B20的温度传感器测试温度采集;
(5) 经过上述硬件测试后,开始根据硬件设计出数码管驱动代码及DS18B20的温度传感器驱动代码;
(6) 将DS18B20的温度传感器采集到的数据处理后显示到数码管上;
(7) 对拓展功能进行设计及实现;

硬件设计

原理图

51单片机 | DS18B20 温度传感器实验_第1张图片

PCB图

51单片机 | DS18B20 温度传感器实验_第2张图片
用万用板连线时,可参考PCB图,避免连线时飞线的出现

程序如下

#include  
#include  
#define uchar unsigned char
#define uint  unsigned int
#define jump_ROM 0xCC
#define start 0x44
#define read_EEROM 0xBE
#define  uchar  unsigned  char 
#define  uint   unsigned  int
unsigned char TMPH,TMPL; 

sbit DQ = P3^3;            //DS18B20数据口
sbit P30=P3^0;
sbit P31=P3^1;
sbit P27=P2^7;

sbit  DATA = P3^3; //DS18B20接入口
unsigned char my_SEG7[] = {0x5f , 0x44 , 0x9d, 0xd5 , 0xc6, 0xd3 , 0xda , 0x45 , 0xdf  ,0xc7};

char  bai,shi,ge; //定义变量

/*延时子函数*/
void delay(uint num)
{
	while(num--) ;
}


Init_DS18B20(void)		   //传感器初始化
{
 	uchar x=0;
 	DATA = 1;    //DQ复位
 	delay(10);  //稍做延时
 	DATA = 0;    //单片机将DQ拉低
 	delay(80); //精确延时 大于 480us    //450
 	DATA = 1;    //拉高总线
 	delay(20);
 	x=DATA;      //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
 	delay(30);
}

//读一个字节
ReadOneChar(void)
{
	uchar i=0;
	uchar dat = 0;
	for (i=8;i>0;i--)
 	{
  		DATA = 0; // 给脉冲信号
  		dat>>=1;
  		DATA = 1; // 给脉冲信号
  		if(DATA)
   		dat|=0x80;
  		delay(8);
 	}
 	return(dat);
}

//写一个字节
WriteOneChar(unsigned char dat)
{
 	uchar i=0;
 	for (i=8; i>0; i--)
 	{
  		DATA = 0;
  		DATA = dat&0x01;
  	delay(10);
  	DATA = 1;
  	dat>>=1;
 	}
	delay(8);
}

//读取温度
int ReadTemperature(void)
{
	uchar a=0;
	uchar b=0;
	int t=0;
	float tt=0;
	Init_DS18B20();
	WriteOneChar(0xCC); // 跳过读序号列号的操作
	WriteOneChar(0x44); // 启动温度转换
	Init_DS18B20();
	WriteOneChar(0xCC); //跳过读序号列号的操作
	WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
	a=ReadOneChar();//低位
	b=ReadOneChar();//高位
	t=b;
	t<<=8;
	t=t|a;
	tt=t*0.0625;
	t= tt*10+0.5; 
	return(t);
}

/*显示子函数*/
void  display(int bai,int shi,int ge)
{
	
	P2=0xFD; P0=my_SEG7[bai]; delay(100);
	P2=0xFB; P0=my_SEG7[shi]+0x20; delay(100);
	P2=0xF7; P0=my_SEG7[ge]; delay(100);
	
}

void  main()
{
	int  temp;
	while(1)
	{	 
		temp=ReadTemperature();//读温度
		bai=temp%1000/100;//显示百位
		shi=temp%100/10;//显示十位
		ge=temp%10;//显示个位
		if(temp >= 300 && temp <= 320 )//高于30度小于32度P2_7口LED灯亮
		{
			P27 = 0;
			delay(100);
		}
		display(bai,shi,ge);//显示函数	
	}	 
}

调试过程及注意事项

1)DS18B20对于数据的读取、检测等方式讲究严格的时序,在编写程序的过程中,需要考虑好相应指令所需的机器周期,以及进行相应的延时操作来读写数据。我再实验过程中尤其是读取DS18B20传输过来的数据时,最开始一直不对,根本原因就是时序延时没有掌握好,掌握好延时和时序后,就能够顺利读取数据。

2)在对DS18B20操作时需要,讲究遵守规则,需要先复位,跳过 ROM,才能进行读写,更改初值等操作。在编写代码的过程中,需要严格历经这三个过程,不要漏步跳步。

3)动态数码管的温度显示要求时刻不断对数码管有数据输入,不能延迟太大导致肉眼可见的掉帧现象,将显示函数写入函数放在10ms一次的定时器中断当中,完成10ms刷新一次的功能。

4)DS18B20的温度数据传入或给温度传感器的写入都是从地位开始输出,在调试过程中没有注意到这个问题导致,温度读取的数据一直有错误,一直到重新看了一边DS18B20后注意到这个细节,专门写了一个输入和读取函数。

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