以下程序是用18B20测量温度并显示,显示采用74HC595静态显示,晶振为12MHz,读取温度的部分绝对可靠,显示部分要根据你的情况自己改.
dat equ p3.3;18B20的数据线
ser equ p1.3;74HC595的SER
srck equ p1.2;74HC595的SRCK
rck equ p1.1;74HC595的RCK
ORG 0000H
AJMP MAIN
ORG 0020H
MAIN:
clr ser
clr rck
clr srck
lcall output
mmmm: lcall delay
MOV SP,#60H
LCALL GET_TEMP
lcall output
SJMP mmmm
GET_TEMP:
CLR PSW.4
SETB PSW.3 ;设置工作寄存器当前所在的区域
CLR EA ;使用ds1820 一定要禁止任何中断产生
LCALL INT ;调用初使化子程序
MOV A,#0CCH
LCALL WRITE ;送入跳过ROM 命令
MOV A, #44H
LCALL WRITE ;送入温度转换命令
LCALL INT ;温度转换完全,再次初使化ds1820
MOV A,#0CCH
LCALL WRITE ;送入跳过ROM 命令
MOV A,#0BEH
LCALL WRITE ;送入读温度暂存器命令
LCALL READ
MOV R7,A ;读出温度值低字节存入R7
LCALL READ
MOV R6,A ;读出谩度值高字节存入R6
SETB EA
CLR PSW.4
CLR PSW.3
RET
INT: ;初始化ds1820 子程序
CLR EA
L0:CLR dat ;ds1820 总线为低复位电平
MOV R2,#200
L1:CLR dat
DJNZ R2,L1 ;总线复位电平保持400us
SETB dat ;释放ds1820 总线
MOV R2,#30
L4:DJNZ R2,L4 ;释放ds1820 总线保持60us
CLR C ;清存在信号
ORL C,dat
JC L0 ;存在吗?不存在则重新来
MOV R6,#80
L5: ORL C,dat
JC L3
DJNZ R6,L5
SJMP L0
L3:MOV R2,#240
L2:DJNZ R2,L2
RET
WRITE: ;向ds1820 写操作命令子程序
CLR EA
MOV R3,#8 ;写入ds1820 的bit 数,一个字节8 个bit
WR1: SETB dat
MOV R4,#8
RRC A ;把一个字节data(A)分成8 个bit 环移给 C
CLR dat ;开始写入ds1820 总线要处于复位(低)状态
WR2: DJNZ R4,WR2 ;ds1820 总线复位保持16us
MOV dat,C ;写入一个bit
MOV R4,#20
WR3: DJNZ R4,WR3 ;等待40us
DJNZ R3,WR1 ;写入下一个bit
SETB dat ;重新释放ds1820 总线
RET
READ:
CLR EA
MOV R6,#8 ;连续读8 个bit
RE1: CLR dat ;读前总线保持为低
MOV R4,#4
NOP
SETB dat ;开始读总线释放
RE2: DJNZ R4,RE2 ;持续8us
MOV C,dat ;从ds1820 总线读得一个bit
RRC A ;把读得的位值环移给 A
MOV R5,#30
RE3: DJNZ R5,RE3 ;持续60us
DJNZ R6,RE1 ;读下一个bit
SETB dat ;重新释放ds1820 总线
RET
output: nop
mov dptr,#tab
mov a,r6
anl a,#0f0h
swap a
movc a,@a+dptr
lcall out1
mov a,r6
anl a,#00fh
movc a,@a+dptr
lcall out1
mov a,r7
anl a,#0f0h
swap a
movc a,@a+dptr
lcall out1
mov a,r7
anl a,#00fh
movc a,@a+dptr
lcall out1
setb rck
nop
nop
clr rck
ret
out1: mov r2,#8
nextbit:rlc a
mov ser,c
nop
nop
setb srck
nop
nop
clr srck
djnz r2,nextbit
; setb rck
; nop
; nop
; clr rck
ret
delay: push 07h
push 06h
mov r7,#0
mov r6,#0
nop
nop
nop
nop
nop
djnz r7,$-5
djnz r6,$-8
pop 06h
pop 07h
ret
tab: db 0c0h,0f9h,0a4h,0b0h,099h,092h,082h,0f8h,080h,090h,088h,083h,0c6h,0a1h,086h,08eh
END
上面的大哥,从网上找资料谁不会,有本事自己写点程序哇。生气ing。
我有完整的18B20读写及数字处理程序,贡献给你吧,希望你能用上。
所有的都是用子程序方式编写的,不需要改任何设置,直接用就可以了。使用时,直接嵌入到程序中,定义相应的地址就可以了。
说明:
1、T_now是采集温度数据,存放在TEMP_H,TEMP_L中;
2、T_JUG是进行温度数值的处理。精确到小数点后一位。
;***************18B20 Temperature Detect***********
T_NOW:
CLR EA
CLR TMP_F
LCALL T_INT
JB TMP_F,T_END1
MOV A,#0CCH
LCALL T_WRITE
MOV A,#44H
LCALL T_WRITE
LCALL T_INT
MOV A,#0CCH
LCALL T_WRITE
MOV A,#0BEH
LCALL T_WRITE
LCALL T_READ
MOV TEMP_L,A
LCALL T_READ
MOV TEMP_H,A
SJMP T_END0
T_END1:
MOV TEMP_L,#00H
MOV TEMP_H,#00H
T_END0:
SETB EA
RET
T_INT:
CLR EA
MOV R4,#250
L0: CLR DQ
MOV R2,#200
L1: CLR DQ
DJNZ R2,L1
SETB DQ
MOV R2,#30
DJNZ R2,$
CLR C
ORL C,DQ ;judge the sensor weather be in working or not.
JNC L_NXT
DJNZ R4,L0
SETB TMP_F ;if abnormal,stop detecting.
SJMP INT_END
L_NXT: MOV R6,#80
L5: ORL C,DQ
JC L3
DJNZ R6,L5
SJMP L0
L3: MOV R2,#240
DJNZ R2,$
INT_END:
NOP
RET
T_WRITE:
CLR EA
MOV R3,#8
WR1: SETB DQ
MOV R4,#8
RRC A
CLR DQ
DJNZ R4,$
MOV DQ,C
MOV R4,#20
DJNZ R4,$
DJNZ R3,WR1
SETB DQ
RET
T_READ:
CLR EA
MOV R6,#8
RE1: CLR DQ
MOV R4,#4
NOP
SETB DQ
DJNZ R4,$
MOV C,DQ
RRC A
MOV R5,#30
DJNZ R5,$
DJNZ R6,RE1
SETB DQ
RET
T_JUG: ;transfer the temperature value
MOV A,TEMP_H
ANL A,#07H
MOV R7,#4
T_LP1: RL A
DJNZ R7,T_LP1
MOV TEMP_H,A
MOV A,TEMP_L
ANL A,#0F0H
RR A
RR A
RR A
RR A
ORL A,TEMP_H
MOV TEMP_H,A
MOV A,TEMP_L
ANL A,#0FH
MOV B,#10
MUL AB
MOV TEMP_L,A
RET
很遗憾,我只有说一句:只有自己才能看懂自己写的程序。程序中存在的问题只有靠自己解决了。
你最好还是用一下软件调试工具来看看他的流程吧,代码逻辑性这样是很难发现的,也不好回答。汇编不像c那样直观,所以软件调试是你的最好解决方法。
把把你编译的错误提示打出来,看看是那行那错了,纠正错误就可以。
如果编译通过,但功能不能实现,可以先逐个调试子程序和中断处理程序,若有误则改。若无误则是主程序的问题。
可以在主程序关键段插入如cpl p1.0 ,检查p1.0,从而判断主程序是否工作正常。
汇编程序再是成手看别人的程序也看不懂,跳来跳去的,一会就晕了。有时时间长了,自己写过的程序都看不懂了。慢慢调吧。
你要的东西太多,太详细,有找枪手的嫌疑。