基于 DS18B20 温度传感器的 51 单片机精确测量教程
51 单片机 DS18B20 温度测量教程:保留一位小数
作者:凉面 ya
一、引言
嘿,朋友!今天咱们要一起玩个超有趣的东西,就是用 51 单片机和 DS18B20 温度传感器来测量温度,并且把温度值显示出来,还保留一位小数呢。这就好比你有一个小管家(51 单片机)和一个小温度计(DS18B20),小管家负责指挥,小温度计负责测量温度,最后把温度显示在一个小屏幕(数码管)上,是不是很有意思?
二、概念解释
1. 51 单片机
51 单片机就像是一个聪明的小管家,它能接收各种指令,然后按照指令去做事情。它有很多小房间(引脚),可以和其他东西(比如传感器、数码管)连接,通过这些连接来传递信息和控制其他东西。
2. DS18B20 温度传感器
DS18B20 就像是一个小温度计,它能感知周围的温度,并且把温度信息转换成数字信号,然后告诉 51 单片机。这就好比你用一个普通的温度计测量温度,然后把温度值告诉别人一样。
3. 数码管
数码管就像是一个小屏幕,它可以显示数字。51 单片机把从 DS18B20 得到的温度信息处理后,通过数码管显示出来,这样我们就能看到具体的温度值啦。
4. 代码中的关键概念
unsigned int 就像是一个大箱子,能装比较大的数字,我们用它来装温度值。因为温度值可能会比较大,小箱子(unsigned char)装不下,所以要用大箱子。三、代码详细解释
1. 头文件部分
#include "reg52.h"
#include "onewire.h"
这就好比你请来了两个帮手,reg52.h 是 51 单片机的说明书,里面有很多关于 51 单片机的信息和工具;onewire.h 是和 DS18B20 通信的说明书,有很多和 DS18B20 交流的方法。
2. 数码管段码表
unsigned char code SMG[18]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf};
unsigned char code SMGpoint[18]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0xff,0xbf};
这两个表就像是一本字典,数码管要显示数字的时候,就从这个字典里找到对应的编码,然后显示出来。
3. 温度变量
unsigned int temp = 0; //必须 int
这就是我们用来装温度值的大箱子,一开始里面是空的。
4. 延时函数
void Delay(unsigned int t)
{
while(t--);
}
这个函数就是让小管家休息一会儿,t 就像是休息的时间,t 越大,休息的时间就越长。
5. 选择 74HC573 锁存器通道函数
void Select573(unsigned char channel)
{
switch(channel)
{
case 4:
{
P2 = (P2&0x1f)|0x80;
break;
}
case 5:
{
P2 = (P2&0x1f)|0xa0;
break;
}
case 6:
{
P2 = (P2&0x1f)|0xc0;
break;
}
case 7:
{
P2 = (P2&0x1f)|0xe0;//wrong
break;
}
}
P2 = (P2&0x1f);
}
这个函数就像是一个小秘书,负责根据不同的指令(channel),打开不同的门(控制 74HC573 锁存器的不同通道)。
6. 数码管显示函数
void Display(unsigned char pos,unsigned char num)
{
P0 = 0xff;
Select573(7);
//实验能不能不加0xff
P0 = 0x01<<pos;
Select573(6);
P0 = num;
Select573(7);
}
这个函数就是让数码管显示数字的。pos 表示要显示在哪个位置,num 表示要显示的数字编码。就好比你要在小屏幕的第几个位置显示什么数字。
7. 读取 DS18B20 温度值函数
void DS18B20()
{
unsigned char LSB,MSB;//low modle sb
init_ds18b20();//重置
Write_DS18B20(0xCC);//操操
Write_DS18B20(0x44);//死死
Delay(1000); //必须延迟!!!!!!!!!!!!!!头文件里面的延时必须都×12
init_ds18b20();//重置
Write_DS18B20(0xCC);//操操
Write_DS18B20(0xbe);//bad end 温度计笑传之ccb
LSB = Read_DS18B20();//L三位
MSB = Read_DS18B20();//M三位
temp = MSB;
temp = (temp<<8)|LSB;
if((temp & 0xf800) == 0x0000)//又写错双等号了
{
temp >>= 4;
temp = temp * 10;
temp = temp + (LSB&0x0f) * 0.625;
}
}
这个函数就是让小管家和小温度计交流,获取温度值的过程。首先要对小温度计进行重置(init_ds18b20()),然后发送一些指令(Write_DS18B20()),让小温度计开始测量温度。测量完后,再读取温度值(Read_DS18B20()),最后把温度值处理一下,放到大箱子(temp)里。
8. 显示所有温度值函数
void DisplayALL()
{
Display(5,SMG[(temp/100)%10]);
Delay(100);
Display(6,SMGpoint[(temp/10)%10]);
Delay(100);
Display(7,SMG[temp%10]);
Delay(100);
P0 = 0xff;
Select573(7);
//记得补充
}
这个函数就是把大箱子里的温度值,通过数码管显示出来。先显示百位,再显示十位(带小数点),最后显示个位。每次显示完都要让小管家休息一会儿,防止显示闪烁。
9. 系统初始化函数
void Initsystem()
{
P0 = 0x00;
Select573(5);
P0 = 0xff;
Select573(4);
}
这个函数就是在开始干活之前,把一些东西初始化一下,就好比你要打扫一下房间,让一切都准备好。
10. 主函数
void main()
{
Initsystem();
while(1)
{
DisplayALL();
DS18B20();
}
}
这是整个程序的核心,就像是小管家的工作流程。首先进行系统初始化,然后进入一个无限循环,在循环里不断地显示温度值,然后再去获取新的温度值,这样就能实时显示温度啦。
四、逻辑图
开始
|
|-- 系统初始化(Initsystem)
|
|-- 进入无限循环
| |
| |-- 显示温度值(DisplayALL)
| | |
| | |-- 显示百位
| | |-- 延时
| | |-- 显示十位(带小数点)
| | |-- 延时
| | |-- 显示个位
| | |-- 延时
| |
| |-- 获取温度值(DS18B20)
| |
| |-- 重置 DS18B20
| |-- 发送测量指令
| |-- 延时
| |-- 重置 DS18B20
| |-- 发送读取指令
| |-- 读取温度值
| |-- 处理温度值
|
结束
五、总结
通过这个教程,你就学会了如何用 51 单片机和 DS18B20 温度传感器来测量温度,并且把温度值显示在数码管上,还保留一位小数。希望你能把这个小项目玩得开心,还能学到很多知识哦!
作者:凉面ya