📄 ds18b20.c
字号:
TIMER0 EQU 9216 ;TIMER0 10mS INTERRUPT
TMSH EQU (65536-TIMER0)/ 256
TMSL EQU (65536-TIMER0)MOD 256
COUNTL EQU 1DH
COUNTH EQU 1EH
STACK EQU 60H
BPS9600 EQU 0FDH
TIME_FLAG BIT 2FH.0
ORG 0000H
LJMP START
ORG 000BH
JMP T0_INT ;[ENABLE] TIMER0 OVERFLOW INTERRUPT
ORG 0010H
START: MOV SP,#STACK
LCALL SYSTEM_INIT
LCALL T_INIT
LCALL ENABLE_INT
BEGIN: JNB p0.7,K0 ;判断按键是否按下,如果按下程序跳至K0
LCALL FUW
MOV A,#0CCH ;直访ROM
LCALL WRITE1820
MOV A,#44H ;温度转换命令
LCALL WRITE1820
LCALL INT ;温度转换完全,再次初使化ds1820
MOV A,#55H
LCALL WRITE ;送入匹配ROM命令
JNB TIME_FLAG,LOOP1
MOV R0,#4AH
JMP LOOP2
LOOP1: MOV R0,#42H
LOOP2: MOV R7,#08H
LOOP3: MOV A,@R0
LCALL WRITE ;送入匹配ROM命令
INC R0
DJNZ R7,LOOP3
MOV A,#0BEH ;读便笺存储器
LCALL WRITE1820
;------------------------------
LCALL RD1820
LCALL JIS1820
LCALL SHU
LJMP LOP
K0: LCALL JPSR0 ;调用键盘输入子程序
LOP: LJMP BEGIN
FUW: SETB p3.0
NOP
CLR p3.0
MOV R0,#0FAH
DJNZ R0,$
SETB p3.0 ;然后拉高数据线
NOP
NOP
NOP
MOV R0,#18H
LOOP25: JNB p3.0,LOOP35 ;等待DS18B20回应
DJNZ R0,LOOP25
CLR p3.5 ;清标志位,表示DS1820不存在
LJMP LOOP55
LOOP35: SETB p3.5 ;置标志位,表示DS1820存在
MOV R0,#0FAH
LOOP45: DJNZ R0,LOOP45 ;时序要求延时一段时间
LOOP55: SETB p3.0
RET
;写DS18B20的子程序(有具体的时序要求)
WRITE1820:
CLR EA
MOV R2,#8 ;一共8位数据
CLR C
WR11: CLR p3.0
MOV R3,#6
DJNZ R3,$
RRC A
MOV p3.0,C
MOV R3,#23
DJNZ R3,$
SETB p3.0
NOP
DJNZ R2,WR11
SETB p3.0
SETB EA
RET
;读出温度数据(低位在41H,高位在40H)
RD1820:
CLR EA
MOV R4,#2 ;读取字节数
MOV R1,#41H ;低位存入41H,高位存入40H
loop70: MOV R2,#8 ;数据一共有8位
loop12: CLR C
SETB p3.0
NOP
NOP
CLR p3.0
NOP
NOP
NOP
SETB p3.0
MOV R3,#9
loop22: DJNZ R3,loop22
MOV C,p3.0
MOV R3,#23
loop32: DJNZ R3,loop32
RRC A
DJNZ R2,loop12
MOV @R1,A
DEC R1
DJNZ R4,loop70
SETB EA
RET
;数据处理子程序
JIS1820 :
MOV A,41H
MOV R0,#04H
LOOP50: RR A
DJNZ R0,LOOP50
ANL A,#0FH
MOV 31H,A
MOV R0,#03H
MOV A,41H
LOOP01: RR A
DJNZ R0,LOOP01
ANL A,#01H
MOV B,#05H
MUL AB
MOV 32H,A
MOV A,40H
ANL A,#07H
MOV B,#16
MUL AB
ADD A,31H
MOV B,#10
DIV AB
MOV 34H,A
MOV A,B
MOV 33H,A
MOV A,34H
MOV B,#10
DIV AB
JNZ ERROR
MOV A,40H
JB ACC.7,LOOP30
MOV 35H,#0AH
LJMP LOOP40
LOOP30: MOV 35H,#0BH
LJMP LOOP40
ERROR: MOV 33H,#0CH
MOV 34H,#0CH
MOV 35H,#0CH
MOV 32H,#0CH
BAOJ: MOV R0,#250
BAO: SETB P3.7
LCALL DALLY
CLR P3.7
LCALL DALLY
DJNZ R0,BAO
LOOP40: RET
;键盘输入子程序
JPSR0: MOV 33H,#0AH
MOV 34H,#0AH
MOV R1,#34H
MOV 35H,#0AH
MOV 32H,#0AH
JPSR: ACALL KS1
JNZ LK1
AJMP JPSR
LK1: ACALL TM12S
ACALL KS1
JNZ LK2
AJMP JPSR
LK2: MOV R2,#0EFH
MOV R4,#00H
LK4: MOV A,R2
MOV P2,A
JB P0.0,LONE
MOV A,#00H
AJMP LKP
LONE: JB P0.1,LTWO
MOV A,#04H
AJMP LKP
LTWO: JB P0.2,NEXT
MOV A,#08H
LKP: ADD A,R4
PUSH ACC
LK3: ACALL KS1
JNZ LK3
POP ACC
LJMP KEND
NEXT: INC R4
MOV A,R2
JNB P2.7,JPSR
RL A
MOV R2,A
AJMP LK4
KEND: MOV @R1,A
DEC R1
CJNE R1,#31H,JPSR
MOV 38H,34H
MOV 37H,33H
MOV 36H,32H
LM: LCALL DSPLAY
JB P0.7,LM
LCALL TM12S
MC: JNB P0.7,MC
RET
KS1: MOV P2,#00H
MOV A,P0
CPL A
ANL A,#0FH
RET
;延时子程序
TM12S: MOV R7,#18H
TM9: MOV R6,#0FFH
TM6: DJNZ R6,TM6
DJNZ R7,TM9
RET
;数据比较子程序
SHU: CLR C
MOV A,38H
CJNE A,34H,L1
CLR C
MOV A,37H
CJNE A,33H,L2
CLR C
MOV A,36H
CJNE A,32H,L3
JG: LCALL BJ
LJMP WW
L1: JC JG
L2: JC JG
L3: JC JG
WW: NOP
RET
;报警子程序
BJ: MOV 33H,#0CH
MOV 34H,#0CH
MOV 35H,#0CH
MOV 32H,#0CH
JING: MOV R3,#250
J0G: SETB P3.7
LCALL DALLY
CLR P3.7
LCALL DALLY
DJNZ R3,J0G
RET
;动态显示子程序
DSPLAY: MOV DPTR,#TAB ;指定查表启始地址
MOV R0,#1
LOOP00: MOV R5,#5 ;显示1000次
LOOP10: MOV A,32H ;显示小数位
MOVC A,@A+DPTR ;查小位数的7段代码
MOV P1,A ;送出小位的7段代码
CLR P3.1 ;开小位显示
ACALL DALLY ;显示1MS
SETB P3.1
MOV A,33H ;取个位数
MOVC A,@A+DPTR ;查个位数的7段代码
MOV P1,A ;送出个位的7段代码
CLR P3.2 ;开个位显示
ACALL DALLY ;显示1MS
SETB P3.2
MOV A,34H ;取十位数
MOVC A,@A+DPTR ;查十位数的7段代码
MOV P1,A
CLR P3.3
ACALL DALLY
SETB P3.3
MOV A,35H
MOVC A,@A+DPTR
MOV P1,A
CLR P3.4
ACALL DALLY
SETB P3.4
DJNZ R5,LOOP10 ;1000次没完循环
DJNZ R0,LOOP00 ;4个1000次没完循环
RET
DALLY: MOV 14h,#6AH ;延时1MS子程序
LOOP: NOP
DJNZ 14h,LOOP
RET
TAB: DB 3FH ;0 P1.0 接数码管段码的A
DB 06H ;1 P1.1 接数码管段码的B
DB 5BH ;2 P1.2 接数码管段码的C
DB 4FH ;3 P1.3 接数码管段码的D
DB 66H ;4 P1.4 接数码管段码的E
DB 6DH ;5 P1.5 接数码管段码的F
DB 7DH ;6 P1.6 接数码管段码的G
DB 07H ;7 P1.7 接数码管段码的H
DB 7FH ;8
DB 6FH ;9 采用共阴的数码管三位
DB 00H ; 不显示数
DB 40H ; 显示负号
DB 71H ; 显示F
;//------------------------------------------------------------------------
INT: ;初始化ds1820子程序
CLR EA
L0:CLR P3.0 ;ds1820总线为低复位电平
MOV R2,#200
L111: CLR P3.0
DJNZ R2,L111 ;总线复位电平保持400us
SETB P3.0 ;释放ds1820总线
MOV R2,#30
L4:DJNZ R2,L4 ;释放ds1820总线保持60us
CLR C ;清存在信号(存在C=1,不存在c=0)
ORL C,P3.0
JC L0 ;存在吗?不存在则重新来
MOV R6,#80
L5:ORL C,P3.0
JC L333
DJNZ R6,L5
SJMP L0
L333: MOV R2,#240
L222: DJNZ R2,L222
RET
;
WRITE: ;向ds1820写操作命令子程序
CLR EA
MOV R3,#8 ;写入ds1820的bit数,一个字节8个bit
WR1: SETB P3.0
MOV R4,#8
RRC A ;把一个字节data(A)分成8个bit环移给 C
CLR P3.0 ;开始写入ds1820总线要处于复位(低)状态
WR21: DJNZ R4,WR21 ;ds1820总线复位保持16us
MOV P3.0,C ;写入一个bit
MOV R4,#20
WR3: DJNZ R4,WR3 ;等待40us
DJNZ R3,WR1 ;写入下一个bit
SETB P3.0 ;重新释放ds1820总线
RET
READ:
CLR EA
MOV R6,#8 ;连续读8个bit
RE1: CLR P3.0 ;读前总线保持为低
MOV R4,#4
NOP
SETB P3.0 ;开始读,总线释放
RE2: DJNZ R4,RE2 ;持续8us
MOV C,P3.0 ;从ds1820总线读得一个bit
RRC A ;把读得的位值环移给 A
MOV R5,#30
RE3: DJNZ R5,RE3 ;持续60us
DJNZ R6,RE1 ;读下一个bit
SETB P3.0 ;重新释放ds1820总线
RET
DELAY:MOV R0,#100
DEL2:MOV R1,#10
DEL1:MOV R2,#250
DEL3:NOP
NOP
DJNZ R2,DEL3
DJNZ R1,DEL1
DJNZ R0,DEL2
RET
;//////////////////////////////////////////////////////////////////////////
;//INIT
SYSTEM_INIT:
CLR TIME_FLAG
MOV 32H,#0AH
MOV 33H,#0AH
MOV 34H,#0AH
MOV 35H,#0AH
MOV 38H,#0FFH
MOV 37H,#0FFH
MOV 36H,#0FFH
CLR P3.7 ;初始化
MOV COUNTL,#0F4H
MOV COUNTH,#01H
MOV 42H,#28H
MOV 43H,#49H
MOV 44H,#0C1H
MOV 45H,#0D6H
MOV 46H,#00H
MOV 47H,#00H
MOV 48H,#00H
MOV 49H,#1AH
MOV 4AH,#28H
MOV 4BH,#0CAH
MOV 4CH,#5EH
MOV 4DH,#0F7H
MOV 4EH,#00H
MOV 4FH,#00H
MOV 50H,#00H
MOV 51H,#8EH
RET
;--------------------------------------------------------------------------
NOP
NOP
NOP
NOP
LJMP START
;--------------------------------------------------------------------------
T_INIT: ;定时器0初始化
MOV TMOD,#21H ;TIMER0 16 BIT COUNT,TIMER1 9600BPS
MOV TH0,#TMSH
MOV TL0,#TMSL
MOV TH1,#BPS9600
RET
;--------------------------------------------------------------------------
NOP
NOP
NOP
NOP
LJMP START
;--------------------------------------------------------------------------
T0_INT: ;TIMER1 OVERFLOW INTERRUPT
; CLR EA
MOV TH0,#TMSH
MOV TL0,#TMSL
PUSH PSW
PUSH ACC
PUSH DPL
PUSH DPH
PUSH 00H
PUSH 01H
PUSH 02H
PUSH 03H
PUSH 04H
PUSH 05H
PUSH 06H
PUSH 07H
LCALL TIMING
LCALL DSPLAY
POP 07H
POP 06H
POP 05H
POP 04H
POP 03H
POP 02H
POP 01H
POP 00H
POP DPH
POP DPL
POP ACC
POP PSW
SETB EA
RETI
;--------------------------------------------------------------------------
NOP
NOP
NOP
NOP
LJMP START
;--------------------------------------------------------------------------
ENABLE_INT:
;ENABLE TIMER0 INTERRUPT
;TCON(8 BITS) SETTING
CLR TF1
CLR TF0 ;CLEAR TF0
SETB TR0 ;TIMER0 START COUNT(16 BITS)
CLR IE1
CLR IT1 ;INT1 EXTERNAL INTERRUPT DISABLE
CLR IE0 ;CLEAR INT0 FLAG
SETB IT0 ;INT0 NEGATIVE RISING TRIGGER
;SCON(8 BITS) SETTING
CLR RI
CLR TI ;DISABLE TRANSMIT
;IP(8 BITS) SETTING
SETB PX0 ;INT0 HIGHER PRIORITY
;IE(8 BITS) SETTING
SETB ET0 ;ENABLE TIMER0 INTERRUPT
;ENABLE SYSTEM INTERRUPT
SETB EA ;ENABLE SYSTEM INTERRUPT
RET
;--------------------------------------------------------------------------
TIMING:
MOV R0,#COUNTL
MOV R1,#COUNTH
DEC @R0
L42: MOV A,@R0
CJNE A,#0FFH,L44
DEC @R1
MOV A,@R1
CJNE A,#0FFH,L44
MOV @R0,#0F4H
MOV @R1,#01H ;计数一秒钟:0x0064,计数五秒钟:0x01f4,计数一分钟:0x1770
CPL TIME_FLAG
L44: RET
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -