C51:温度传感器-----------简单看看效果,真能检测温度?
时间:2022-08-07 12:00:00
前言
也是检查时序图的内容。
今天,我的游览器跳出了有趣的界面。
温度传感器芯片DS18B20
特点
DS18B20数字温度传感器接线方便,可用于管道、螺纹、磁铁吸附、不锈钢包装等多种场合。它的外观主要根据不同的应用场合而变化。封装后的DS18B20可用于各种非极限温度场合,如电缆沟测温、高炉水循环测温、锅炉测温、机房测温、农业温室测温、洁净室测温、弹药库测温等。耐磨耐碰,体积小,使用方便,包装形式多样,适用于各种狭小空间设备的数字测温控制。
- 适应电压范围较宽,电压范围:3.0~5.5V,数据线可以通过寄生电源供电
- 独特的单线接口方式,DS18B与微处理器连接时,只需要一条口线即可实现微处理器
处理器与DS18B20的双向通讯.- DS18B20支持多点网络功能,多点网络功能DS18B20可并联在唯一的三线上,实现网络多点测温
- DS18B20在使用中不需要任何外围元件,所有传感元件和转换电路都集成在形状上
集成电路中只有三极管。- 温范围-55℃~ 125℃,在-10~ 85℃时精度为±0.5℃
- 可编程的分辨率为9~12位,对应的可分辨温度为0.5℃、0.25℃、0.125℃
和0.0625℃,可实现高精度测温。- 9位分辨率最多为93.75ms将温度转换为数字,12位分辨率最多为750ms
更快地将温度值转换为数字。- 测量结果直接输出数字温度信号"一根总线"串行传送给CPU,同时可传送
CRC验证码,抗干扰纠错能力强。- 负压特性:当电源极性反转时,芯片不会因发热而燃烧, 但不能正常工作。
DS18B20原理图和实物图
物理结构
整体结构
内部结构
MSB、LSB有温度数据。如何通过这两个寄存器获取温度数据?
绿色意味着全部是正的,全部是负的。
橙色是温度的整数部分。
红色是温度的一小部分。
配置寄存器控制温度的数值精度。
?? \;
?? \;
?? \;
指令
什么是ROM指令?什么是RAM指令?
分别是以ROM和RAM作为目的操作物的指令
如何使用指令来控制芯片?
芯片内部有默认的程序运行顺序,规定先复位再执行ROM再执行指令RAM指令,结束顺序。
例如,我想读温度,
复 位 → 跳 过 R O M 指 令 → 开 始 温 度 转 换 → 延 时 → 复 位 → 跳 过 R O M 指 令 → 开 始 温 度 转 换 → 接 收 两 个 字 节 → 结 束 复位 \rightarrow 跳过ROM指令 \rightarrow 开始温度转换 \rightarrow 延时 \rightarrow 复位 \rightarrow 跳过ROM指令 \rightarrow 开始温度转换 \rightarrow 接收两个字节 \rightarrow 结束 复位→跳过ROM指令→开始温度转换→延时→复位→跳过ROM指令→开始温度转换→接收两个字节→结束
- 第一轮我发命令要芯片把温度的模拟信号转换成数字信号,延时等待转换。第二轮就先发命令表示我要开始读了,然后接受就行了
\;
\;
\;
\;
时序
DS18B20的时序的复杂和红外通信中的PPM解码类似,对信号所保持的时间很严格!!!(单总线通信)
\;
\;
\;
示例:检测温度
就是读取DS18B20芯片转换过来的温度的数字信号并显示出来。
//DS18B20
#include"reg52.h"
#include"intrins.h"
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
sbit DS_port=P3^7;
unsigned char num=0;
unsigned char leds[8];
unsigned char code table[]= {
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
void DS_18B20_Delay(unsigned int i);
bit DS_18B20_Init();
void DS_18B20_Send(unsigned char _cmd);
unsigned char DS_18B20_Read();
void DS_18B20_TemperatureTransform();
void DS_18B20_SendCmdOfRead();
unsigned int DS_18B20_ReadTemperature();
//-------------------------------------------------------------
void delay(unsigned int i){
while(i--);
}
void main(){
while(1){
unsigned char i;
unsigned int temperature = DS_18B20_ReadTemperature();
float tp;//用浮点计算更精确
if(temperature<0){
///
leds[0]=0x40;
temperature--;
temperature=~temperature;
tp=temperature;
temperature = 0.0625 * tp * 100 + 0.5 ;
}
else{
leds[0]=0;
tp=temperature;
temperature = 0.0625 * tp * 100 + 0.5;
}
leds[5] = table[temperature%10];
leds[4] = table[temperature/10%10];
leds[3] = table[temperature/100%10]|0x80;
leds[2] = table[temperature/1000%10];
leds[1] = table[temperature/10000];
for(i=0;i<6;i++){
switch(i){
case 0:
LSC=0,LSB=0,LSA=0;
break;
case 1:
LSC=0,LSB=0,LSA=1;
break;
case 2:
LSC=0,LSB=1,LSA=0;
break;
case 3:
LSC=0,LSB=1,LSA=1;
break;
case 4:
LSC=1,LSB=0,LSA=0;
break;
case 5:
LSC=1,LSB=0,LSA=1;
break;
}
P0=leds[5-i];
delay(100);
P0=0x00;
}
}
}
//-------------------------------------------------------------
//delay iX10 us
void DS_18B20_Delay(unsigned int i){
while(i--);
}
bit DS_18B20_Init(){
unsigned char i;
DS_port=0;//拉低480us~960us
DS_18B20_Delay(70);//~642us
//拉高总线,这样DS做出反应会在15us~60us内将总线拉低
DS_port=1;//拉高
i=0;
while(DS_port){
DS_18B20_Delay(100);//~1ms
if(++i>5)//>5ms
return 0;
}
return 1;
}
void DS_18B20_Send(unsigned char _cmd){
unsigned int j;
for(j=0;j<8;j++){
DS_port=0;
_nop_();//拉低1us
DS_port= _cmd << 7;//先发送低位
_cmd>>=1;
DS_18B20_Delay(6);//~68us
DS_port=1;//释放总线
}
}
unsigned char DS_18B20_Read(){
unsigned char receive=0,k=0;
unsigned int j;
for(j=0;j<8;j++){
DS_port=0;//拉低
_nop_();
DS_port=1;//释放
_nop_();
_nop_();
k=DS_port;//从最低位开始读取
receive |=(k<<j);
//receive = (receive>>1)|(k<<7);
DS_18B20_Delay(4);//~48us
}
return receive;
}
void DS_18B20_TemperatureTransform(){
DS_18B20_Init();
DS_18B20_Send(0xcc);//跳过ROM
DS_18B20_Send(0x44);//温度转换
DS_18B20_Delay(100);//~1ms
}
void DS_18B20_SendCmdOfRead(){
DS_18B20_Init();
DS_18B20_Send(0xcc);//跳过ROM
DS_18B20_Send(0xbe);//读取RAM中9字节的内容
DS_18B20_Delay(100);//~1ms
}
unsigned int DS_18B20_ReadTemperature(){
unsigned int temperature;
unsigned char highTemp,lowTemp;
DS_18B20_TemperatureTransform();//温度转换命令
DS_18B20_SendCmdOfRead();//读取内存命令
lowTemp=DS_18B20_Read();//先读低位
highTemp=DS_18B20_Read();
temperature = highTemp;
temperature <<=8;
temperature|=lowTemp;
return temperature;
}
显示效果:
设置精度?应该是设置分辨率吧!
9位(0x1f)对应着0.5
10位(0x3f)对应着0.25
11位(0x5f)对应着0.125
12位(0x7f)对应着0.0625
void DS_18B20_SetPrecious(unsigned int _ex){
//设置配置寄存器
DS_18B20_Init();
DS_18B20_Send(0xcc);//跳过ROM
DS_18B20_Send(0x4e);//发送数据到RAM中3、4字节
DS_18B20_Send(0); //第3字节不用
DS_18B20_Send(_ex);//第4字节是配置寄存器
DS_18B20_Delay(100);
}