宏晶科技提供提供的18B20温度传感器读写程序
下面是1T单片机时的时序图。
/**************************************
;WWW.STCMCU.COM
;Mobile:13922805190
;0755-82948412
温度传感器DS18B20测试程序
主芯片 : STC12C5A60S2 (1T)
工作频率: 12.000MHz
**************************************/
#include "REG51.H"
#include "INTRINS.H"
typedef unsigned char BYTE;
sbit DQ = P3^3; //DS18B20的数据口位P3.3
BYTE TPH; //存放温度值的高字节
BYTE TPL; //存放温度值的低字节
void DelayXus(BYTE n);
void DS18B20_Reset();
void DS18B20_WriteByte(BYTE dat);
BYTE DS18B20_ReadByte();
void main()
{
DS18B20_Reset(); //设备复位
DS18B20_WriteByte(0xCC); //跳过ROM命令
DS18B20_WriteByte(0x44); //开始转换命令
while (!DQ); //等待转换完成
DS18B20_Reset(); //设备复位
DS18B20_WriteByte(0xCC); //跳过ROM命令
DS18B20_WriteByte(0xBE); //读暂存存储器命令
TPL = DS18B20_ReadByte(); //读温度低字节
TPH = DS18B20_ReadByte(); //读温度高字节
while (1);
}
/**************************************
延时X微秒(STC12C5A60S2@12M)
不同的工作环境,需要调整此函数
此延时函数是使用1T的指令周期进行计算,与传统的12T的MCU不同
**************************************/
void DelayXus(BYTE n)
{
while (n--)
{
_nop_();
_nop_();
}
}
/**************************************
复位DS18B20,并检测设备是否存在
**************************************/
void DS18B20_Reset()
{
CY = 1;
while (CY)
{
DQ = 0; //送出低电平复位信号
DelayXus(240); //延时至少480us
DelayXus(240);
DQ = 1; //释放数据线
DelayXus(60); //等待60us
CY = DQ; //检测存在脉冲
DelayXus(240); //等待设备释放数据线
DelayXus(180);
}
}
/**************************************
从DS18B20读1字节数据
**************************************/
BYTE DS18B20_ReadByte()
{
BYTE i;
BYTE dat = 0;
for (i=0; i<8; i++) //8位计数器
{
dat >>= 1;
DQ = 0; //开始时间片
DelayXus(1); //延时等待
DQ = 1; //准备接收
DelayXus(1); //接收延时
if (DQ) dat |= 0x80; //读取数据
DelayXus(60); //等待时间片结束
}
return dat;
}
/**************************************
向DS18B20写1字节数据
**************************************/
void DS18B20_WriteByte(BYTE dat)
{
char i;
for (i=0; i<8; i++) //8位计数器
{
DQ = 0; //开始时间片
DelayXus(1); //延时等待
dat >>= 1; //送出数据
DQ = CY;
DelayXus(60); //等待时间片结束
DQ = 1; //恢复数据线
DelayXus(1); //恢复延时
}
}
1T时的 汇编程序
;**************************************
;WWW.STCMCU.COM
;Mobile:13922805190
;0755-82948412
;温度传感器DS18B20测试程序
;主芯片 : STC12C5A60S2 (1T)
;工作频率: 12.000MHz
;**************************************
DQ BIT P3.3 ;DS18B20的数据口位P3.3
TPH DATA 20H ;存放温度值的高字节
TPL DATA 21H ;存放温度值的低字节
ORG 0
JMP Reset
ORG 100H
Reset:
CALL DS18B20_Reset ;设备复位
MOV A,#0CCH ;跳过ROM命令
CALL DS18B20_WriteByte ;送出命令
MOV A,#044H ;开始转换
CALL DS18B20_WriteByte ;送出命令
JNB DQ,$ ;等待转换完成
CALL DS18B20_Reset ;设备复位
MOV A,#0CCH ;跳过ROM命令
CALL DS18B20_WriteByte ;送出命令
MOV A,#0BEH ;读暂存存储器
CALL DS18B20_WriteByte ;送出命令
CALL DS18B20_ReadByte ;读温度低字节
MOV TPL,A ;存储数据
CALL DS18B20_ReadByte ;读温度高字节
MOV TPH,A ;存储数据
JMP $
;**************************************
;延时X微秒(STC12C5A60S2@12M)
;不同的工作环境,需要调整此函数
;入口参数:R7
;出口参数:无
;**************************************
DelayXus: ;6 此延时函数是使用1T的指令周期进行计算,与传统的12T的MCU不同
NOP ;1
NOP ;1
NOP ;1
NOP ;1
NOP ;1
NOP ;1
NOP ;1
NOP ;1
DJNZ R7,DelayXus ;4
RET ;4
;**************************************
;复位DS18B20,并检测设备是否存在
;入口参数:无
;出口参数:无
;**************************************
DS18B20_Reset:
CLR DQ ;送出低电平复位信号
MOV R7,#240 ;延时至少480us
CALL DelayXus
MOV R7,#240
CALL DelayXus
SETB DQ ;释放数据线
MOV R7,#60 ;等待60us
CALL DelayXus
MOV C,DQ ;检测存在脉冲
MOV R7,#240 ;等待设备释放数据线
CALL DelayXus
MOV R7,#180
CALL DelayXus
JC DS18B20_Reset ;如果设备不存在,则继续等待
RET
;**************************************
;从DS18B20读1字节数据
;入口参数:无
;出口参数:ACC
;**************************************
DS18B20_ReadByte:
CLR A
PUSH 0
MOV 0,#8 ;8位计数器
ReadNext:
CLR DQ ;开始时间片
MOV R7,#1 ;延时等待
CALL DelayXus
SETB DQ ;准备接收
MOV R7,#1
CALL DelayXus
MOV C,DQ ;读取数据
RRC A
MOV R7,#60 ;等待时间片结束
CALL DelayXus
DJNZ 0,ReadNext
POP 0
RET
;**************************************
;向DS18B20写1字节数据
;入口参数:ACC
;出口参数:无
;**************************************
DS18B20_WriteByte:
PUSH 0
MOV 0,#8 ;8位计数器
WriteNext:
CLR DQ ;开始时间片
MOV R7,#1 ;延时等待
CALL DelayXus
RRC A ;输出数据
MOV DQ,C
MOV R7,#60 ;等待时间片结束
CALL DelayXus
SETB DQ ;准备送出下一位数据
MOV R7,#1
CALL DelayXus
DJNZ 0,WriteNext
POP 0
RET
END
12T的C51程序
/**************************************
;WWW.STCMCU.COM
;Mobile:13922805190
;0755-82948412
温度传感器DS18B20测试程序
主芯片 : STC90C52RC (12T)
工作频率: 12.000MHz
**************************************/
#include "REG51.H"
#include "INTRINS.H"
typedef unsigned char BYTE;
sbit DQ = P3^3; //DS18B20的数据口位P3.3
BYTE TPH; //存放温度值的高字节
BYTE TPL; //存放温度值的低字节
void DelayXus(BYTE n);
void DS18B20_Reset();
void DS18B20_WriteByte(BYTE dat);
BYTE DS18B20_ReadByte();
void main()
{
DS18B20_Reset(); //设备复位
DS18B20_WriteByte(0xCC); //跳过ROM命令
DS18B20_WriteByte(0x44); //开始转换命令
while (!DQ); //等待转换完成
DS18B20_Reset(); //设备复位
DS18B20_WriteByte(0xCC); //跳过ROM命令
DS18B20_WriteByte(0xBE); //读暂存存储器命令
TPL = DS18B20_ReadByte(); //读温度低字节
TPH = DS18B20_ReadByte(); //读温度高字节
while (1);
}
/**************************************
延时X*10微秒(STC90C52RC@12M)
不同的工作环境,需要调整此函数
当改用1T的MCU时,请调整此延时函数
**************************************/
void DelayX0us(BYTE n)
{
while (n--)
{
_nop_();
_nop_();
}
}
/**************************************
复位DS18B20,并检测设备是否存在
**************************************/
void DS18B20_Reset()
{
CY = 1;
while (CY)
{
DQ = 0; //送出低电平复位信号
DelayX0us(48); //延时至少480us
DQ = 1; //释放数据线
DelayX0us(6); //等待60us
CY = DQ; //检测存在脉冲
DelayX0us(42); //等待设备释放数据线
}
}
/**************************************
从DS18B20读1字节数据
**************************************/
BYTE DS18B20_ReadByte()
{
BYTE i;
BYTE dat = 0;
for (i=0; i<8; i++) //8位计数器
{
dat >>= 1;
DQ = 0; //开始时间片
_nop_(); //延时等待
_nop_();
DQ = 1; //准备接收
_nop_(); //接收延时
_nop_();
if (DQ) dat |= 0x80; //读取数据
DelayX0us(6); //等待时间片结束
}
return dat;
}
/**************************************
向DS18B20写1字节数据
**************************************/
void DS18B20_WriteByte(BYTE dat)
{
char i;
for (i=0; i<8; i++) //8位计数器
{
DQ = 0; //开始时间片
_nop_(); //延时等待
_nop_();
dat >>= 1; //送出数据
DQ = CY;
DelayX0us(6); //等待时间片结束
DQ = 1; //恢复数据线
}
}
12T 汇编程序
;**************************************
;WWW.STCMCU.COM
;Mobile:13922805190
;0755-82948412
;温度传感器DS18B20测试程序
;主芯片 : STC90C52RC (12T)
;工作频率: 12.000MHz
;**************************************
DQ BIT P3.3 ;DS18B20的数据口位P3.3
TPH DATA 20H ;存放温度值的高字节
TPL DATA 21H ;存放温度值的低字节
ORG 0
JMP Reset
ORG 100H
Reset:
CALL DS18B20_Reset ;设备复位
MOV A,#0CCH ;跳过ROM命令
CALL DS18B20_WriteByte ;送出命令
MOV A,#044H ;开始转换
CALL DS18B20_WriteByte ;送出命令
JNB DQ,$ ;等待转换完成
CALL DS18B20_Reset ;设备复位
MOV A,#0CCH ;跳过ROM命令
CALL DS18B20_WriteByte ;送出命令
MOV A,#0BEH ;读暂存存储器
CALL DS18B20_WriteByte ;送出命令
CALL DS18B20_ReadByte ;读温度低字节
MOV TPL,A ;存储数据
CALL DS18B20_ReadByte ;读温度高字节
MOV TPH,A ;存储数据
JMP $
;**************************************
;延时X*10微秒(STC90C52RC@12M)
;不同的工作环境,需要调整此函数
;入口参数:R7
;出口参数:无
;**************************************
DelayX0us: ;2 当改用1T的MCU时,请调整此延时函数
NOP ;1
NOP ;1
NOP ;1
NOP ;1
NOP ;1
NOP ;1
NOP ;1
NOP ;1
DJNZ R7,DelayX0us ;2
RET ;2
;**************************************
;复位DS18B20,并检测设备是否存在
;入口参数:无
;出口参数:无
;**************************************
DS18B20_Reset:
CLR DQ ;送出低电平复位信号
MOV R7,#48 ;延时至少480us
CALL DelayX0us
SETB DQ ;释放数据线
MOV R7,#6 ;等待60us
CALL DelayX0us
MOV C,DQ ;检测存在脉冲
MOV R7,#42 ;等待设备释放数据线
CALL DelayX0us
JC DS18B20_Reset ;如果设备不存在,则继续等待
RET
;**************************************
;从DS18B20读1字节数据
;入口参数:无
;出口参数:ACC
;**************************************
DS18B20_ReadByte:
CLR A
PUSH 0
MOV 0,#8 ;8位计数器
ReadNext:
CLR DQ ;开始时间片
NOP
NOP
SETB DQ ;准备接收
NOP
NOP
MOV C,DQ ;读取数据
RRC A
MOV R7,#6 ;等待时间片结束
CALL DelayX0us
DJNZ 0,ReadNext
POP 0
RET
;**************************************
;向DS18B20写1字节数据
;入口参数:ACC
;出口参数:无
;**************************************
DS18B20_WriteByte:
PUSH 0
MOV 0,#8 ;8位计数器
WriteNext:
CLR DQ ;开始时间片
NOP
NOP
RRC A ;输出数据
MOV DQ,C
MOV R7,#6 ;等待时间片结束
CALL DelayX0us
SETB DQ ;准备送出下一位数据
DJNZ 0,WriteNext
POP 0
RET
END