蓝桥杯单片机——DS18B20温度传感器(16)
时间:2022-10-31 04:00:01
一、原理分析
DS18B20是一种常用的数字温度传感器,输出数字信号,温度转换的延迟时间为750ms。
蓝桥杯单片机资源包将提供一个关于DS18B20底层驱动库文件,onewire.c文件和onewire.h其实里面只有文件。DS18B20复位操作、字节写操作和字节读操作三个函数。温度传感器DS18B20是单总线通信设备,操作总线时序要求非常严格。如果序列混乱,设备将不响应主机DS18B时序在20底层驱动程序中非常重要。可能需要适当调整不同系统时钟的微处理器。
1、DS18B20温度转换和读取过程
【1】DS18B20复位。
2写字节0xCC,跳过ROM指令。
3写字节0x44.开始温度转换。
【4】延时700~900ms。
【5】 DS18B20复位。
6写字节0xCC,跳过ROM指令。
7写字节0xBE,读取高速临存器。
8读取暂存器的第0字节,即温度数据LSB。
9读取暂存器的第一字节,即温度数据MSB。
【10】DS18B20复位。表示读取数据结束。
【11】将LSB和MSB整合成16位数据。
12判断读取结果的符号,处理正负温度的数据。
2、DS18B20的数据处理
DS18B20以16位带符号位读出扩展的二进制补码形式。高5位为符号位,低4位为小数,中7位为整数。
DS18B20的分辨率为0.0625.当读取数据为正温时,将会LSB和MSB16位整数直接乘以0.0625就够了。当读取数据为负温度时,需要将数据读取LSB和MSB16位整数,取反加1,乘以0.0625。
举个例子来说明这种处理的具体过程:
假设DS18B20温度采样结果如下:LSB = 0x96,MSB = 0x01。
温度数据变量T_dat为16位无符号int整形,初始值为0x0000。
执行T_dat = MSB;语句后, T_dat 的值为:0x0001。
执行T_dat <<= 8;语句后, T_dat 的值为:0x0100。
执行T_dat = T_dat | LSB;语句后, T_dat 的值为:0x0196。
正常情况下,通过判断高5位符号扩展位,正温处理算法应为:
要求温度结果保留一个小数位,为了简化单片机中的操作,整形处理可以放大10倍,将两位小数保留100倍。如果温度结果只显示整个部分,那就不用那么罗嗦了,直接显示整数:
T_dat >>= 4;即 T_dat = 0x0019 = 25 摄氏度。
二、编程
<1> 先将onewire.c文件和onewire.h将文件复制到当前工程下。
<2> 打开onewire.h检查文件代码是否完整,确认总线引脚定义是否和CT107D硬件对应,即P1^4.如不对应,则修改。
<3> 打开onewire.c文件, 研究每个底层驱动代码的具体实现,初步判断时序延迟是否合理,如有明显错误,则修改。(IAP15F2K60S2的操作速度是51的12倍,底层驱动代码一般是51。如果发现温度不准确,只需要把它拿走onewire.c驱动代码中的延迟可以增加10倍或12倍。
<4> 根据DS18B20工作原理和操作流程,编写读取温度结果和处理温度数据的函数DS18B20应用开发中最重要的环节。
<5> 根据温度结果刷新数字管显示。这部分可以使用MM实现模式,可用IO实现模式。
用小数显示温度
main.c
#include #include unsigned char duanma[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; unsigned char duanma_x[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10}; unsigned int temp=0; void Delay_SMG(unsigned int t) { while(t--); } void DisplaySMG_Bit(unsigned char pos,unsigned char dat) { P2=0xE0;P0=0xff;///先关掉所有数码管,避免显示异常 P2=0xC0;P0=0x01<>=4; ////取出温度结果的整数部分 temp=temp*10.//放大10倍,然后加上小数部分 temp=temp (LSB&0x0f)*0.625; } } void main() { P2=0x80;P0=0xff;
while(1)
{
Read_DS18B20_temp();
DisplaySMG_temp();
}
}
onewire.c
/*
程序说明: 单总线驱动程序
软件环境: Keil uVision 4.10
硬件环境: CT107单片机综合实训平台(外部晶振12MHz) STC89C52RC单片机
日 期: 2011-8-9
*/
#include "reg52.h"
sbit DQ = P1^4; //单总线接口
//单总线延时函数
void Delay_OneWire(unsigned int t) //STC89C52RC
{
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(50);
}
//从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;
}
onewire.h
#ifndef __ONEWIRE_H
#define __ONEWIRE_H
unsigned char rd_temperature(void); //; ;
bit init_ds18b20(void);
unsigned char Read_DS18B20(void);
void Write_DS18B20(unsigned char dat);
#endif
2、用整数显示温度
#include
#include
unsigned char duanma[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsigned char duanma_x[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
unsigned int temp=0;
void Delay_SMG(unsigned int t)
{
while(t--);
}
void DisplaySMG_Bit(unsigned char pos,unsigned char dat)
{
P2=0xE0;P0=0xff;//先全部关掉数码管,避免显示不正常
P2=0xC0;P0=0x01<>=4;
}
void main()
{
P2=0x80;P0=0xff;
while(1)
{
Read_DS18B20_temp();
DisplaySMG_temp();
}
}
用手摸温度传感器U5,温度上升
温度传感器ds18b20