DS18B20是一种常用的数字温度传感器,输出数字信号,温度转换的延迟时间为。
蓝桥杯单片机资源包将提供一个关于DS18B20底层驱动库文件,文件和其实里面只有文件。DS18B20、和三个函数。温度传感器DS18B20是,操作总线。如果序列混乱,设备将不响应主机DS18B时序在20底层驱动程序中非常重要。可能需要适当调整不同系统时钟的微处理器。
【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判断读取结果的符号,处理正负温度的数据。
DS18B20以16位读出扩展的二进制补码形式。高5位为符号位,低4位为小数,中7位为整数。
DS18B20的分辨率为0.0625.当读取数据为正温时,将会LSB和MSB16位整数直接乘以0.0625就够了。当读取数据为负温度时,需要将数据读取LSB和MSB16位整数,取反加1,乘以0.0625。
举个例子来说明这种处理的具体过程: 假设DS18B20温度采样结果如下:。 温度数据变量T_dat为16位无符号int整形,初始值为。 执行语句后, T_dat 的值为:。 执行语句后, T_dat 的值为:。 执行语句后, T_dat 的值为:。 正常情况下,通过判断高5位符号扩展位,正温处理算法应为:,为了简化单片机中的操作,整形处理可以放大10倍
,那就不用那么罗嗦了,直接显示整数:即 T_dat = 0x0019 = 25 摄氏度。
二、编程
<1> 先将文件和将文件复制到当前工程下。 <2> 打开检查文件代码是否完整,确认总线引脚定义是否和CT107D硬件对应,即P1^4.如不对应,则修改。 <3> 打开文件, 研究每个底层驱动代码的具体实现,初步判断时序延迟是否合理,如有明显错误,则修改。 <4> 根据DS18B20工作原理和操作流程,编写读取温度结果和处理温度数据的函数DS18B20应用开发中最重要的环节。 <5> 根据温度结果刷新数字管显示。这部分可以使用MM实现模式,可用IO实现模式。
用小数显示温度
main.c
#include <reg52.h> #include <onewire.h> 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<<pos; P2=0xE0;P0=dat; } void DisplaySMG_temp() { DisplaySMG_Bit(6,duanma[temp]); Delay_SMG(100); DisplaySMG_Bit(5,duanma_x[(temp/10)]); Delay_SMG(100); DisplaySMG_Bit(4,duanma[temp/100]); Delay_SMG(100); DisplaySMG_Bit(7,0xc6); Delay_SMG(100); DisplaySMG_Bit(3,0xff); Delay_SMG(100); DisplaySMG_Bit(2,0xff); Delay_SMG(100); DisplaySMG_Bit(1,0xff); Delay_SMG(100); DisplaySMG_Bit(0,0xff); Delay_SMG(100); P2=0xC0;P0=0xff; P2=0xE0;P0=0xff; } void Delay(unsigned int t) { while(t--) { DisplaySMG_temp(); } } void Read_DS18B20_temp() { unsigned char LSB,MSB; init_ds18b20();//DS18B20复位 Write_DS18B20(0xcc);//跳过ROM操作指令 Write_DS18B20(0x44); //开始温度转换 Delay(1000)ms左右,等待温度转换完成 init_ds18b20(); //DS18B20复位 Write_DS18B20(0xcc);//跳过ROM操作指令 Write_DS18B20(0xbe); ///开始读取高速暂存器 LSB=Read_DS18B20();//读取温度数据低8位 MSB=Read_DS18B20();///读取高8位的温度数据 temp=MSB; temp=(temp<<8)|LSB; //将LSB和MSB整合成16位整数 ///首先通过温度数据的高5位判断结果是正温还是负温 if((temp&0xf800)==0x/正温处理方法 { temp>>=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 <reg52.h>
#include <onewire.h>
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<<pos;
P2=0xE0;P0=dat;
}
void DisplaySMG_temp()
{
DisplaySMG_Bit(6,duanma[temp%10]);
Delay_SMG(100);
DisplaySMG_Bit(5,duanma[temp/10]);
Delay_SMG(100);
DisplaySMG_Bit(4,0xff);
Delay_SMG(100);
DisplaySMG_Bit(7,0xc6);
Delay_SMG(100);
DisplaySMG_Bit(3,0xff);
Delay_SMG(100);
DisplaySMG_Bit(2,0xff);
Delay_SMG(100);
DisplaySMG_Bit(1,0xff);
Delay_SMG(100);
DisplaySMG_Bit(0,0xff);
Delay_SMG(100);
P2=0xC0;P0=0xff;
P2=0xE0;P0=0xff;
}
void Delay(unsigned int t)
{
while(t--)
{
DisplaySMG_temp();
}
}
void Read_DS18B20_temp()
{
unsigned char LSB,MSB;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
Delay(1000);
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
LSB=Read_DS18B20();
MSB=Read_DS18B20();
temp=MSB;
temp=(temp<<8)|LSB;
temp>>=4;
}
void main()
{
P2=0x80;P0=0xff;
while(1)
{
Read_DS18B20_temp();
DisplaySMG_temp();
}
}
用手摸温度传感器U5,温度上升
温度传感器ds18b20