DS18B20 是温度检测器件,具有单总线、数字化的特点。
它的外形结构还比较脆弱,一般来说,它只是适合于检测室温的场合,环境条件稍稍恶劣一些,它就抗不住了。
在工业场合,做而论道一般还是使用 PT100,这个东西抗造。
做而论道用 18B20 和单片机制作了数字温度计,在办公室里放了 N 多年。
它和酒精温度计显示的温度,还是有些差异,也不知道谁测量的准。
做而论道编写程序,基本上以汇编为主,一般也不想拿出来,因为很少有人看汇编的程序。
用汇编语言编写程序,思维要跟着计算机、存储器、二进制、逻辑运算、...、来走。
多数人的思维,还是停留在中小学阶段,还是以十进制来分析问题,弄不了计算机本身的东西,所以都不愿意看汇编的程序。
做而论道编写的关于 DS18B20 的程序,在 PROTEUS 软件中,仿真的效果图如下:
图片链接:http://xiangce.baidu.com/picture/detail/544db91e604402c24acc7adc30294a86c41227d6
http://hi.baidu.com/%D7%F6%B6%F8%C2%DB%B5%C0/album/item/40138fd88d1001e971fe7fa9b80e7bec56e797b3.html#
仿真实验时,可以断开 DS18B20 支路,数码管将会显示:Error。
图中的 DS18B20,可以用“属性”来设置小数。
小数的范围是:0、1/16 ~ 15/16,即十进制的:0、0.0625 ~ 0.9375。
小数共有四位,是 0.0625 的整数倍,但是它的器件上,只能显示 1 位小数。
在 18B20 的温度数据中,最低四位:0001 ~ 1111,就代表了十进制的:0.0625 ~ 0.9375。
看到过很多的文章,都谈到了,怎样才能从这四位数中求出十进制的小数。
呵呵,好多的方法,都是笨的真可以!
很有一些人,都知难而退了,就用查表来解决小数的问题。其实也就是查出一位小数,就都很满足了。
做而论道用了十余条指令吧,很简单的,就求出了两位小数,并且把第三位小数按照四舍五入,进到了前一位。
想要把四位小数都求出来,也不过20条指令而已,约 30us,就能解决问题。
程序中,使用了模块化的设计方法,相当规范。
模块中的转移指令,都已经设计好了偏移量,省去了好多的标号。这样,每个模块,仅有一个标号,看起来极为清晰。
不多说了,程序如下:
;=================================
DQ EQU P3.7 ;18B20 接口
NO_18 BIT 20H ;20H.0 存在标志位
D_BUF EQU 30H ;30H ~ 37H 显示空间
TEMP EQU 38H ;38H ~ 39H 温度数据
S_BOTT EQU 3AH ;栈底位置
;=================================
ORG 0000H
START:
MOV SP, #S_BOTT
CALL GET_T
CALL T_PROC
CALL DISPLAY
JMP $ - 6
;=================================
GET_T:
CALL INIT_18B20
JB NO_18, $ + 25
MOV A, #0CCH
CALL W_18B20
MOV A, #44H
CALL W_18B20
CALL DISPLAY
CALL INIT_18B20
MOV A, #0CCH
CALL W_18B20
MOV A, #0BEH
CALL W_18B20
CALL R_18B20
RET
;=================================
INIT_18B20: ;初始化
CLR DQ ;复位
MOV R3, #20 ;540us
DJNZ R3, $
DJNZ R3, $
SETB DQ
MOV R3, #30
DJNZ R3, $
MOV C, DQ ;读状态
MOV NO_18, C
MOV R3, #150
DJNZ R3, $ ;300us
RET
;=================================
W_18B20:
MOV R2, #8 ;写入8位数
CLR DQ
MOV R3, #6
DJNZ R3, $
RRC A
MOV DQ, C
MOV R3, #23
DJNZ R3, $
SETB DQ
DJNZ R2, $ - 15
RET
;=================================
R_18B20: ;读出温度
MOV R0, #TEMP
MOV R4, #2 ;读出两字节
MOV R2, #8 ;读出8位数
CLR DQ
NOP
NOP
NOP
SETB DQ
MOV R3, #9
DJNZ R3, $
MOV C, DQ
RRC A
MOV R3, #23
DJNZ R3, $
DJNZ R2, $ - 18;读出8位数
MOV @R0, A ;先存放到 TEMP
INC R0 ;后读出存 TEMP+1
DJNZ R4, $ - 24
RET
;=================================
T_PROC:
JNB NO_18, $ + 22
;-------------------下面是显示Err
MOV 30H, #26
MOV 31H, #14 ;这些地址,如果是高128的地址,
MOV 32H, #32 ;就应该使用间接寻址。
MOV 33H, #32 ;
MOV 34H, #31 ;现在,就用直接寻址吧。
MOV 35H, #32
RET
;-------------------下面是数据处理
MOV 30H, #0
MOV 31H, #0
MOV 32H, #0
CLR F0
MOV A, TEMP + 1
JNB ACC.7, $ + 16
;-------------------下面是求补
CLR C
CLR A
SUBB A, TEMP
MOV TEMP, A
CLR A
SUBB A, TEMP + 1
MOV TEMP + 1, A
SETB F0 ;负号标志
;-------------------下面处理整数
MOV A, TEMP
SWAP A
ANL A, #15
MOV B, A
MOV A, TEMP + 1
ANL A, #15
SWAP A
ADD A, B
MOV B, #100
DIV AB
MOV 31H, A ;百位
MOV A, #10
XCH A, B
DIV AB
MOV 32H, A ;十位
XCH A, B
ADD A, #16
MOV 33H, A
;-------------------下面处理两位小数
MOV A, TEMP ;
ANL A, #15 ;0001~1111=0.0625~0.9375
MOV B, #10
MUL AB ;乘以10
MOV B, A ;暂存
SWAP A ;交换到低四位,就是除以16
ANL A, #15 ;低四位就是十分位小数
MOV 34H, A ;写入显示位置
MOV A, #10 ;再乘以10,将求出百分位小数
XCH A, B
ANL A, #15 ;这是刚才除以16的余数
MUL AB ;乘以10
MOV C, ACC.3 ;低四位中的最高位
SWAP A ;交换,就是除以16
ANL A, #15 ;下面是进行四舍五入
ADDC A, #0 ;加上低四位中的最高位即可
MOV 35H, A ;写入百分位小数
;-------------------下面消除无效零
MOV R0, #D_BUF
MOV A, @R0
JNZ $ + 8
MOV @R0, #26 ;' '
INC R0
CJNE R0, #D_BUF + 3, $ - 6
;-------------------下面处理负号
JNB F0, $ + 6
DEC R0
MOV @R0, #28 ;'-'
RET ;约用100us
;=================================
DISPLAY:
MOV R1, #34
CALL DIS_ALL
DJNZ R1, $ - 2
RET ;占用时间约为200ms
;-----------------------
DIS_ALL: ;共阳数码管, P0:段, P2:反相位
MOV R2, #254 ;位选, 低电平有效
MOV R0, #D_BUF
MOV A, @R0
ADD A, #(TAB - $ - 3)
MOVC A, @A + PC
MOV P2, #255
MOV P0, A
MOV P2, R2
DJNZ R7, $ ;显示1ms
DJNZ R7, $
MOV A, R2
RL A
MOV R2, A
INC R0
CJNE R0, #D_BUF + 6, $ - 19 ;显示6位
MOV P2, #255
RET ;占用时间约为6.2ms
;-----------------------
TAB: ;共阳段码
DB 0C0H, 0F9H, 0A4H, 0B0H, 099H, 092H, 082H, 0F8H;0~7
DB 080H, 090H, 088H, 083H, 0C6H, 0A1H, 086H, 08EH;8~F
DB 040H, 079H, 024H, 030H, 019H, 012H, 002H, 078H
DB 000H, 010H, 0FFH ;0.~9. ' '
DB 08CH, 0BFH, 089H, 0C7H, 0A3H, 0AFH ;P,-,H,L,o,r
;=================================
END
;=================================
;欢迎转载,但是要注明出处--做而论道。