小弟用的Proteus仿真DS18B20,但从DS18B20读出转换好的温度数据不对,估计是读写时序的问题,求大虾帮忙
;启动转换并读出温度(16进制补码)READ_TEMP:LCALLRESET_PULSE;复位MOVA,#0CCH;跳过ROMLCALLWRITEMOVA,#44H;启动...
;启动转换并读出温度(16进制补码)
READ_TEMP:LCALL RESET_PULSE ;复位
MOV A,#0CCH ;跳过ROM
LCALL WRITE
MOV A,#44H ;启动温度转换
LCALL WRITE
LCALL DELAY250MS
LCALL DELAY250MS
LCALL DELAY250MS ;延时750MS等待转换结束
LCALL RESET_PULSE ;复位
MOV A,#0CCH
LCALL WRITE
MOV A,#0BEH ;读出温度命令
LCALL WRITE
LCALL READ ;读出温度
RET
;DS18B20初始化(复位)
RESET_PULSE: NOP
SETB DATA_BUS
R_AGAIN:NOP
NOP
CLR DATA_BUS ;拉低总线
MOV R7,#200 ;延时600us
DZ600: NOP
DJNZ R7,DZ600
SETB DATA_BUS ;拉高总线(此时产生复位脉冲)
MOV R7,#37 ;延时75us
DJNZ R7,$
MOV R7,#60
DZ240: JNB DATA_BUS,R_NEXT ;等待DS18B20的应答脉冲(240us内)
DJNZ R7,DZ240
CLR RESET_FLAG ;DS18B20不存在
LJMP DZ500
R_NEXT: SETB RESET_FLAG ;DS18B20存在
DZ500: MOV R7,#250 ;等待DS18B20释放总线(500us)
DJNZ R7,$
SETB DATA_BUS ;拉高总线
JNB RESET_FLAG,R_AGAIN
RET
;读出温度数据(读出的温度数据存到TEMP_L和TEMP_H单元中)
READ: MOV R0,#TEMP_L
CLR A
SETB DATA_BUS
MOV R6,#8
MOV R5,#2
READING:CLR DATA_BUS ;拉低总线
NOP
NOP
NOP
SETB DATA_BUS ;拉高总线
MOV R7,#7
DJNZ R7,$
MOV C,DATA_BUS ;从总线上读取数据
MOV R7,#30 ;延时60us保证读取数据的有效性
DJNZ R7,$
RRC A ;把刚刚读取的一位数据暂存到A中
SETB DATA_BUS
NOP
DJNZ R6,READING ;循环8次完成一个字节的读取
MOV @R0,A ;把温度数据的低8位存到TEMP_L地址单元
INC R0 ;地址单元+1
MOV R6,#8
SETB DATA_BUS
NOP
DJNZ R5,READING ;再来一次把温度数据的高8位存到TEMP_H单元
RET
小弟初步检测了哈,例如:设置DS18B20为1度(温度低8位应该是10H),但从我的程序读出的却是02H;设置为2度(低8位应该是20H),读出的却是04H。。。估计是读时序不对,但不晓得该怎么修改了,望懂的大虾指导哈,不甚感激。 展开
READ_TEMP:LCALL RESET_PULSE ;复位
MOV A,#0CCH ;跳过ROM
LCALL WRITE
MOV A,#44H ;启动温度转换
LCALL WRITE
LCALL DELAY250MS
LCALL DELAY250MS
LCALL DELAY250MS ;延时750MS等待转换结束
LCALL RESET_PULSE ;复位
MOV A,#0CCH
LCALL WRITE
MOV A,#0BEH ;读出温度命令
LCALL WRITE
LCALL READ ;读出温度
RET
;DS18B20初始化(复位)
RESET_PULSE: NOP
SETB DATA_BUS
R_AGAIN:NOP
NOP
CLR DATA_BUS ;拉低总线
MOV R7,#200 ;延时600us
DZ600: NOP
DJNZ R7,DZ600
SETB DATA_BUS ;拉高总线(此时产生复位脉冲)
MOV R7,#37 ;延时75us
DJNZ R7,$
MOV R7,#60
DZ240: JNB DATA_BUS,R_NEXT ;等待DS18B20的应答脉冲(240us内)
DJNZ R7,DZ240
CLR RESET_FLAG ;DS18B20不存在
LJMP DZ500
R_NEXT: SETB RESET_FLAG ;DS18B20存在
DZ500: MOV R7,#250 ;等待DS18B20释放总线(500us)
DJNZ R7,$
SETB DATA_BUS ;拉高总线
JNB RESET_FLAG,R_AGAIN
RET
;读出温度数据(读出的温度数据存到TEMP_L和TEMP_H单元中)
READ: MOV R0,#TEMP_L
CLR A
SETB DATA_BUS
MOV R6,#8
MOV R5,#2
READING:CLR DATA_BUS ;拉低总线
NOP
NOP
NOP
SETB DATA_BUS ;拉高总线
MOV R7,#7
DJNZ R7,$
MOV C,DATA_BUS ;从总线上读取数据
MOV R7,#30 ;延时60us保证读取数据的有效性
DJNZ R7,$
RRC A ;把刚刚读取的一位数据暂存到A中
SETB DATA_BUS
NOP
DJNZ R6,READING ;循环8次完成一个字节的读取
MOV @R0,A ;把温度数据的低8位存到TEMP_L地址单元
INC R0 ;地址单元+1
MOV R6,#8
SETB DATA_BUS
NOP
DJNZ R5,READING ;再来一次把温度数据的高8位存到TEMP_H单元
RET
小弟初步检测了哈,例如:设置DS18B20为1度(温度低8位应该是10H),但从我的程序读出的却是02H;设置为2度(低8位应该是20H),读出的却是04H。。。估计是读时序不对,但不晓得该怎么修改了,望懂的大虾指导哈,不甚感激。 展开
2个回答
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询