📄 perfect.asm
字号:
NUM1 EQU 30H
NUM2 EQU 31H
NUM3 EQU 32H
NUM4 EQU 33H
NUM11 EQU 40H
NUM22 EQU 41H
NUM33 EQU 42H
NUM44 EQU 43H
FLAG1 BIT 34H
TEMP_H EQU 35H
TEMP_L EQU 36H
T_DF EQU 37H
T_INTEGER EQU 38H
VSTATE EQU 39H
DQ BIT P2.6
ORG 0000H
LJMP START
ORG 000BH
LJMP TIME
START:
LCALL INIT
STA: LCALL INIT_1820
JB FLAG1,ST ;若1820存在则进行温度转换
LJMP STA ; 若DS18B20不存在则返回
ST:
LCALL DELAY60
MOV A,#0CCH ; 跳过ROM匹配
LCALL WRITE_1820 ;写1820的程序
MOV A,#44H ; 发出温度转换命令
LCALL WRITE_1820
LCALL DELAY750MS
S1:
LCALL INIT_1820
JB FLAG1,S2
LJMP S1
S2:
LCALL DELAY60
MOV A,#0CCH ; 跳过ROM匹配
LCALL WRITE_1820
MOV A,#0BEH ; 发出读温度命令
LCALL WRITE_1820
LCALL READ_1820 ;读1820程序
LCALL COV_TEMPER
LCALL TRANSISTOR
LJMP STA
RET
INIT_1820: CLR EA
SETB DQ
NOP
CLR DQ ;复位要求主CPU将数据线下拉500US,然后释放
LCALL DELAY500
SETB DQ ;然后释放
MOV R0,#15H ;DS18B20收到信号后等待16-60us然后发出60-240us的存在低脉冲
TSR1:
JNB DQ,TSR2
DJNZ R0,TSR1
CLR FLAG1 ; 清标志位,表示DS1820不存在
LJMP TSR3
TSR2:
SETB FLAG1 ; 置标志位,表示DS1820存在
LCALL DELAY500
TSR3:
SETB DQ
SETB EA
RET
WRITE_1820: CLR EA
MOV R2,#8 ;一共8位数据
CLR C
WR1:
CLR DQ ;总线低位开始写入
MOV R3,#6 ;12us
DJNZ R3,$
RRC A ;把DATA分成8个位环移给C
MOV DQ,C ;写入一个位
MOV R3,#23 ;48us
DJNZ R3,$
SETB DQ ;重新释放总线
NOP
DJNZ R2,WR1
SETB DQ
SETB EA
RET
READ_1820: CLR EA
MOV R4,#2 ; 将温度高位和低位从DS18B20中读出
MOV R1,#36H ; 低位存入36H(TEMP_L),高位存入35H(TEMP_H)
RE0:
MOV R2,#8
RE1:
CLR C
SETB DQ
NOP
NOP
CLR DQ ;读前总线保持为低
NOP
NOP
NOP
SETB DQ ;开始读总线释放
MOV R3,#7
DJNZ R3,$
MOV C,DQ ;从总线读到一个位
MOV R3,#25
DJNZ R3,$ ;50us
RRC A
DJNZ R2,RE1
MOV @R1,A
DEC R1
DJNZ R4,RE0
SETB EA
RET
COV_TEMPER: CLR EA
MOV A,#0FH
ANL A,TEMP_L
MOV T_DF,A ;获得小数部分(4位)
MOV A,TEMP_L
SWAP A
MOV @R0,A
MOV A,TEMP_H
SWAP A
XCHD A,@R0
ANL A,#7FH
MOV T_INTEGER,A ;获得整数部分(1字节)
MOV B,#10
DIV AB
MOV NUM1,A
MOV NUM2,B
MOV A,T_DF
MOV B,#10
MUL AB
MOV B,#16
DIV AB
MOV NUM3,A
MOV A,B
MOV B,#10
MUL AB
MOV B,#16
DIV AB
MOV NUM4,A
MOV NUM11,NUM1
MOV NUM22,NUM2
MOV NUM33,NUM3
MOV NUM44,NUM4
SETB EA
RET
TRANSISTOR:
MOV A,T_INTEGER ;二极管报警
SUBB A,#30
JNC LIGHT
RET
LIGHT:
CLR P2.1
LCALL DELAY1MS
LCALL DELAY1MS
RET
TIME:
PUSH ACC ;保护现场
PUSH PSW
MOV TL0,#78H ;赋5ms定时初值
MOV TH0,#0ECH
ET11:
INC VSTATE ;显示状态判断
MOV A,VSTATE
CJNE A,#5,RZ1 ;A不等于5,转向RZ1
MOV VSTATE,#1 ;从第一位开始
RZ1:
MOV A,VSTATE
CJNE A,#1,RZ2
MOV A,NUM44
ORL A,#80H
MOV P0,A;显示小数点后第二位
LJMP RZEND1
RZ2:
MOV A,VSTATE
CJNE A,#2,RZ3
MOV A,NUM33
ORL A,#40H
MOV P0,A;显示小数点后第一位
LJMP RZEND1
RZ3:
MOV A,VSTATE
CJNE A,#3,RZ4
MOV A,NUM22
ORL A,#20H
MOV P0,A;显示个位
MOV P2,#3FH
LJMP RZEND1
RZ4:
MOV A,VSTATE
CJNE A,#4,RZEND1
MOV P2,#0BFH
MOV A,NUM11
ORL A,#10H
MOV P0,A;显示十位
LJMP RZEND1
RZEND1:
POP PSW ;恢复现场
POP ACC
RETI
INIT:
MOV NUM11,#0
MOV NUM22,#0
MOV NUM33,#0
MOV NUM44,#0
MOV VSTATE,#4
MOV TMOD,#01H ;设定定时器工作方式
MOV TL0,#78H ;赋5ms定时初值
MOV TH0,#0ECH
SETB TR0 ;启动定时
SETB EA
SETB ET0
RET
DELAY750MS:
MOV R1,#3 ;750ms延时
LOOP: MOV R2,#250
LOOP2: MOV R3,#250
LOOP3:
NOP
NOP
DJNZ R3,LOOP3
DJNZ R2,LOOP2
DJNZ R1,LOOP
RET
DELAY1MS:
MOV R7,#250 ;1ms延时
LOOP4:
NOP
NOP
DJNZ R7,LOOP4
RET
DELAY500:
MOV R1,#0FAH ;500us延时
DJNZ R1,$
RET
DELAY60:
MOV R2,#20H ;68us延时
DJNZ R2,$
RET
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -