📄 ds18b20.c
字号:
/**************************************DS18B20驱动程序************************************************
*单总线通信协义:
*复位脉冲:480us低电平.
复位脉冲发出后经70us检测存在脉冲,DQ=0器件存在,DQ=1不存在
*写时间隙.写时间隙不小于60us.
*写0:将DQ拉低60us.
*写1:将DQ拉低后15us内释放.
*读时间隙.读时间隙不小于60us.
将DQ拉低后15us内释放,在15-50us内若DQ=0则读0,DQ=1则读1.
*通过单总线端口仿问DS18B20的过程如下:
*初始化
*ROM操作命令
*存储器操作命令
*数据处理
*DS18B20引脚:1.GND 2.DQ 3.VDD
*ROM操作命令:
*读出ROM,代码33H,用于读出DS18B20的序列号,取64位激光ROM代码.
*匹配ROM,代码55H,用于辨识(或选中)某一特定的DS18B20进行操作.
*搜索ROM,代码F0H,用于确定总线上的节点数以及所有节点的序列号.
*跳过ROM,代码CCH,命令发出后系统将对所有DS18B20进行操作.
*报警搜索,代码ECH,主要用于鉴别和定位系统中超出程序设定的报警温度
界限的节点.
*DS18B20的存储器资源如下表 (为了便于理解,存储器A、B、C是我自己定义的名字):
ROM(8个字节) A0 A1 A2 A3 A4 A5 A6 A7 --
RAM(9个字节) B0 B1 B2 B3 B4 B5 B6 B7 B8
EEPROM(3个字节) C0 C1 C2 -- -- -- -- -- --
A0既是64位ID码的一部分,也是64位ID码的的CRC校验值,A1~A6是ID码其中的48位,A7是器件码(28H)。
B0温度低8位值、B1是温度高8位值,B2、B3是温度报警值,B4是温度转换精度值,B5、B6、B7是系统保留用,
就相当于运算内存,B8是B0~B7的校验码
*存储器操作命令:
-------------------------------------------------------------------------------
代码 指令说明
-------------------------------------------------------------------------------
44 温度转换指令,并把转换后的数据存放在RAM的B0、B1的两个字节里
BE 读取指令,器件收到这个指令后把B0、B1两个字节的数据传送给主机
4E 改写RAM的B2、B3、B4的数据,主机发出这个指令后跟着再分别发送相应的数据
48 器件收到这个指令后就将B2、B3、B4的数据写到EEPROM
B8 器件收到这个指令后就把EEPROM的高H、低L温度报警值写到进B2、B3
B4 器件收到这个指令后就返回0或者1给主机,0为寄生电源,1为外部电源
-------------------------------------------------------------------------------
******************************************************************************************************/
#include<reg52.h>
#include"DS18B20.h"
#define uchar unsigned char
sbit DQ= P1^5;
//sbit LED=P1^0;
/**************复位函数*****************
*功能:完成单总线的复位操作
*返回值:0-器件存在,1-器件不存在
***************************************/
bit ow_reset(void)
{ uchar t;
bit ea=EA;
bit presence;
EA=0;
DQ=0;
for(t=240;t>0;t--); //延时480us
DQ=1;
for(t=35;t>0;t--); //延时70us
presence=DQ;
for(t=30;t>0;t--); //延时60us
EA=ea;
return presence;
}
/**************位写入函数**************
*功能:向单总线写入1位值
**************************************/
void write_bit(bit bitval)
{ uchar t;
bit ea=EA;
EA=0;
DQ=0;
DQ=bitval;
for(t=30;t>0;t--); //延时60us
DQ=1;
EA=ea;
}
/**************字节写入函数***********
*功能:向单总线写入一个字节值.先写低位
*************************************/
void write_byte(uchar val)
{
uchar i;
for(i=8;i>0;i--)
{
write_bit(val&0x01);
val>>=1;
}
}
/***********位读取函数**************
*功能:从单总线上读取一位信号
***********************************/
bit read_bit(void)
{
uchar t;
bit temp;
bit ea=EA;
EA=0;
DQ=0;
DQ=1;
for(t=8;t>0;t--); //延时16us
temp=DQ;
for(t=22;t>0;t--);
EA=ea;
return temp;
}
/***********字节读取函数***********
*功能:从单总线上读取一字节.先读低位
**********************************/
uchar read_byte(void)
{
uchar i,value=0;
for(i=8;i>0;i--)
{
value=value>>1;
if(read_bit()) value|=0x80;
}
return value;
}
/**********启动温度转换函数***********/
void start_temper(void)
{
if(ow_reset())return;
write_byte(0xcc); //跳过ROM
write_byte(0x44); //启动温度转换,默认的12位转化,最大转化时间750ms
}
/**********读温度函数*************/
unsigned read_temper(void)
{
uchar get[2],i;
if(ow_reset())return 0x0000;
write_byte(0xcc); //跳过ROM
write_byte(0xbe); //读暂存器
for(i=0;i<2;i++)
get[i]=read_byte();
return (get[1]<<8|get[0]);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -