DS18B20的工作原理及应用

FLAG1 BIT F0 ;DS18B20存在标志位 DQ BIT P1.7

TEMPER_L EQU 29H TEMPER_H EQU 28H A_BIT EQU 35H B_BIT EQU 36H

;************ds18b20汇编程序起始******************** ORG 0000H AJMP MAIN ORG 0100H

;**************主程序开始************ MAIN:

LCALL INIT_18B20 ;LCALL RE_CONFIG LCALL GET_TEMPER AJMP CHANGE

;**********DS18B20复位程序***************** INIT_18B20: SETB DQ NOP

CLR DQ

MOV R0,#0FBH

TSR1: DJNZ R0,TSR1 ;延时 SETB DQ

MOV R0,#25H TSR2: JNB DQ ,TSR3 DJNZ R0,TSR2

TSR3: SETB FLAG1 ;置标志位,表明DS18B20存在 CLR P2.0 ;二极管指示 AJMP TSR5 TSR4: CLR FLAG1 LJMP TSR7

TSR5: MOV R0,#06BH TSR6: DJNZ R0,TSR6

TSR7:SETB DQ ;表明不存在 RET

;********************设定DS18B20暂存器设定值************** ;RE_CONFIG:

;JB FLAG1,RE_CONFIG1 ;RET

;RE_CONFIG1: MOV A,#0CCH ;放跳过ROM命令 ;LCALL WRITE_18B20 ;MOV A,#4EH

;LCALL WRITE_18B20 ;写暂存器命令

;MOV A,#00H ;报警上限中写入00H ;LCALL WRITE_18B20

;MOV A,#00H ;报警下限中写入00H

16

; LCALL WRITE_18B20

;MOV A,#1FH ;选择九位温度分辨率 ; LCALL WRITE_18B20 ; RET

;*****************读转换后的温度值**************** GET_TEMPER:

SETB DQ

LCALL INIT_18B20 JB FLAG1,TSS2

RET ;若不存在则返回 TSS2: MOV A,#0CCH ;跳过ROM LCALL WRITE_18B20

MOV A,#44H ;发出温度转换命令 LCALL WRITE_18B20

LCALL DISPLAY ;延时 LCALL INIT_18B20

MOV A,#0CCH ;跳过ROM LCALL WRITE_18B20

MOV A,#0BEH ;发出读温度换命令 LCALL WRITE_18B20

LCALL READ2_18B20 ;读两个字节的温度 RET

;***************写ds18b20汇编程序************ WRITE_18B20:

MOV R2,#8 CLR C WR1:

CLR DQ

MOV R3,#6 DJNZ R3,$ RRC A

MOV DQ,C MOV R3,#23 DJNZ R3,$ SETB DQ NOP

DJNZ R2,WR1 SETB DQ RET

;***********读18B20程序,读出两个字节的温度********* READ2_18B20:

MOV R4,#2 ;低位存在29 H,高位存在28H

17

MOV R1,#29H RE00: MOV R2,#8 RE01: CLR C SETB C NOP NOP

CLR DQ NOP NOP NOP

SETB DQ MOV R3,#7 DJNZ R3,$ MOV C,DQ MOV R3,#23 DJNZ R3,$ RRC A

DJNZ R2,RE01 MOV @R1,A DEC R1

DJNZ R4,RE00 RET

;************读出的温度进行数据转换**************

CHANGE: MOV A,29H

MOV C,28H.0 ;将28H中的最低位移入C RRC A

MOV C,28H.1 RRC A

MOV C,28H.2 RRC A

MOV C,28H.3 RRC A

MOV 29H,A ;setb p2.0

LCALL DISPLAY ;调用数码管显示子程序

; setb P2.0 LJMP MAIN

;*******************DISPLAY******

DISPLAY: mov a,29H;将29H中的十六进制数转换成10进制 mov b,#10 ;10进制/10=10进制 div ab

mov b_bit,a ;十位在a mov a_bit,b ;个位在b

mov dptr,#TAB ;指定查表启始地址

18

mov r0,#4

dpl1: mov r1,#250 ;显示1000次 dplop: mov a,a_bit ;取个位数

MOVC A,@A+DPTR ;查个位数的7段代码 mov p0,a ;送出个位的7段代码 clr p2.5;开个位显示 acall d1ms ;显示1ms setb p2.5

mov a,b_bit ;取十位数

MOVC A,@A+DPTR ;查十位数的7段代码 mov p0,a ;送出十位的7段代码 clr p2.4;开十位显示 acall d1ms ;显示1ms setb p2.4

djnz r1,dplop ;100次没完循环 djnz r0,dpl1 ;4个100次没完循环 ret

;***********************************

D1MS: MOV R7,#80 ;1MS延时(按12MHZ算) DJNZ R7,$ RET

;*************************

TAB: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H

DS18B20 DQ 引脚对应的链接是PA5。

源码:

=================================================================== //1400-DS18B20.c //简单的驱动程式 //akuei2 08-01-10 #include \

19

#include \#include \#define DQ PA5 //微妙级延迟函数

void Delay_1us(unsigned int x) {

unsigned int i; x=x*5/4;

for( i=0;i

//DS1302 复位函数 void DS1302_Reset() {

DDRA|=BIT(DQ); //DQ 为输出状态 PORTA&=~BIT(DQ); //输出低电平 Delay_1us(500); //延迟500 微妙 PORTA|=BIT(DQ); //示范总线 Delay_1us(60); //延迟60 微妙 DDRA&=~BIT(DQ); //DQ 位输出状态

while(PINA&BIT(DQ)); //等待从机DS18B20 应答(低电平有效) while(!(PINA&BIT(DQ))); //等待从机DS18B20 释放总线 }

//DS1302 写字节函数

void DS1302_Write(unsigned char Data) {

unsigned char i;

DDRA|=BIT(DQ); //DQ 为输出 for(i=0;i<8;i++) {

PORTA&=~BIT(DQ); //拉低总线

Delay_1us(10); //延迟10 微妙(最大15 微妙) if(Data&0x01) PORTA|=BIT(DQ); else PORTA&=~BIT(DQ);

Delay_1us(40); //延迟40 微妙(最大45 微妙) PORTA|=BIT(DQ); //释放总线 Delay_1us(1); //稍微延迟 Data>>=1; } }

//DS1302 读字节函数

unsigned char DS1302_Read() {

unsigned char i,Temp; for(i=0;i<8;i++) {

Temp>>=1; //数据右移

DDRA|=BIT(DQ); //DQ 为输出状态

20

联系客服:779662525#qq.com(#替换为@) 苏ICP备20003344号-4