18b20测温(数码管显示)
很久就做过18B20的测温程序了,后来又写过18B20的多点测温,但看到论坛里,各位版主,特别是鱼版主的很多例程,感觉发多了也没必要。
不过,没有交流就不能知道缺陷,也就不能在原有的基础上进步。本着交流的原则,我在不同的帖子里把前一段时间里做过的一些小程序传上来,供有兴趣的朋友参考。当然,能看出问题,并指出来,或者能够给出改进建议,则我在此不胜感激了。呵呵。
我的18b20测温来咯。
声明:本程序在CEPARK实验板上通过。如有问题,请留言。
;18b20单点测温程序
;18b20变量部分
TEMPL EQU 0030H ;温度值低字节
TEMPH EQU 0031H ;温度值高字节
TH EQU 0032H ;高温上限
TL EQU 0 ;低温下限
TDOT EQU 100 ;温度小数位
TGE EQU 0035H ;温度个位
TSHI EQU 0036H ;温度十位
TBAI EQU 0037H ;温度百位
TEMP EQU 0038H ;暂存值
TSIGNAL EQU F0 ;符号标志
DAT1 EQU P1.6 ;数据线
CONFIG12 EQU 7FH ;12位精度
ORG 0030H
MAIN: MOV P1,#0FFH
ACALL INIT ;DS18B20初始化 改动过,next
NEXT: ACALL RDTEMP ;读温度值
ACALL DATPRO ;数据处理
ACALL DISPLAY ;显示
SJMP NEXT
;初始化ds1820子程序
INIT: ACALL RESET
MOV A,#0CCH
ACALL WRITE ;写入SKIP ROM指令
MOV A,#4EH
ACALL WRITE ;写入暂存存储器指令
MOV A,#TH ;报警温度上限
ACALL WRITE
MOV A,#TL ;报警温度下限
ACALL WRITE
MOV A,#CONFIG12 ;写入精度配置值
ACALL WRITE
RET
;18b20复位子程序
RESET: CLR EA ;关中断,18b20操作必须关中断
L0: CLR DAT1 ;ds1820总线为低电平复位
MOV R2,#200
L1: CLR DAT1
DJNZ R2,L1 ;总线复位电平保持600us
SETB DAT1 ;释放ds1820总线
MOV R2,#30
L4: DJNZ R2,L4 ;释放ds1820总线保持40us
CLR C ;清存在信号
ORL C,DAT1 ;读入总线信号和C或
JC L0 ;存在吗?不存在则重新来
MOV R6,#80 ;存在,
L5: ORL C,DAT1 ;检测存在信号是否结束
JC L3 ;存在信号结束
DJNZ R6,L5 ;存在信号可能保持320us(240-420)
SJMP L0 ;过了320US,存在信号没结束,重新复位
L3: MOV R2,#240 ;存在信号结束
L2: DJNZ R2,L2 ;延时480US
RET
;读温度子程序
RDTEMP: ACALL RESET
MOV A,#0CCH ;跳过ROM
ACALL WRITE
MOV A,#44H ;启动温度转换
ACALL WRITE
ACALL DELAY ;延时500ms
ACALL RESET ;重新复位 改动1,读取失败于此
MOV A,#0CCH
ACALL WRITE ;跳过ROM
MOV A,#0BEH
ACALL WRITE
ACALL READ ;读温度低字节
MOV TEMPL,A
ACALL READ ;读温度高字节
MOV TEMPH,A
ACALL READ
RET
;向ds1820写操作命令子程序
WRITE: CLR EA ;关中断,18b20操作都要关中断
MOV R3,#8 ;写入ds1820的bit数,一个字节8个bit
WR1: SETB DAT1 ;写之前,总线置高电平
MOV R4,#8
RRC A ;把一个字节data(A)分成8个bit循环移给 C
CLR DAT1 ;开始写入ds1820总线要处于低状态
WR2: DJNZ R4,WR2 ;ds1820总线低电平保持16us? 15us内写到总线上
MOV DAT1,C ;写入一个bit
MOV R4,#30
WR3: DJNZ R4,WR3 ;等待60us
DJNZ R3,WR1 ;写入下一个bit,连续写两位间的间隔大于1us
SETB DAT1 ;重新释放ds1820总线
RET
;从ds18b20读操作命令子程序
READ: CLR EA ;关中断,18b20操作都要关中断
MOV R6,#8 ;连续读8个bit
RE1: CLR DAT1 ;读前总线保持为低
MOV R4,#6
NOP
SETB DAT1 ;开始读总线释放
RE2: DJNZ R4,RE2 ;持续12us
MOV C,DAT1 ;从ds1820总线读得一个bit
RRC A ;把读得的位值环移给 A
MOV R5,#30
RE3: DJNZ R5,RE3 ;持续60us
DJNZ R6,RE1 ;读下一个bit
SETB DAT1 ;重新释放ds1820总线
RET
DELAY: MOV R7,#240
DJNZ R7,$
RET
;数据处理子程序
;12精度,对高低两字节数据取补,
;然后分别求出小数位,个位,十位,百位
DATPRO: CLR TSIGNAL
MOV A,TEMPH
JNB ACC.7,POSIT ;正数,补数是其本身
SETB TSIGNAL ;负数,TSIGNAL=1
XRL A,#07 ;温度高位与00000111异或
MOV TEMPH,A
MOV A,TEMPL
XRL A,#0FFH ;温度低位与11111111异或
ADD A,#01 ;加1
MOV TEMPL,A
MOV A,TEMPH
ADDC A,#0
MOV TEMPH,A ;负数求补运算完成
POSIT: MOV A,TEMPL ;温度低字节
MOV B,#16
DIV AB ;除以16
MOV TDOT,B ;小数位值保存
MOV TEMP,A ;低位值先保存
MOV A,TEMPH ;温度高字节
ANL A,#07H ;只保留低3位 修改2
MOV B,#16
MUL AB ;权重为16,乘以16
ADD A,TEMP ;加上低位值
MOV B,#10
DIV AB ;除以10,余数为个位值
MOV TGE,B ;个位值保存
MOV B,#10
DIV AB
MOV TSHI,B ;十位值保存
MOV TBAI,A ;百位值保存
RET
;*****************显示子程序**********************
;;四位数码管显示 动态扫描
;;注意事项:CEPARK的试验板是共阳极的板子,三极管
;;基极送低电平点亮数码管 *****重要
DISPLAY:MOV R5,#100
DISP: MOV DPTR,#TAB2
MOV A,#0AH ;负号
JB TSIGNAL,NEGT
MOV A,TBAI
JNZ NEGT
MOV A,#0BH ;百位为0时,不显示百位
NEGT: MOVC A,@A+DPTR
MOV P0,A
CLR P1.0
ACALL DELAY2
MOV A,TSHI
MOVC A,@A+DPTR
SETB P1.0
MOV P0,A ;显示十位
CLR P1.1
ACALL DELAY2
MOV A,TGE
MOVC A,@A+DPTR
SETB P1.1
MOV P0,A ;显示个位
SETB P0.7
CLR P1.2
ACALL DELAY2
CLR P0.7
MOV DPTR,#TAB1
MOV A,TDOT
MOVC A,@A+DPTR
MOV DPTR,#TAB2
MOVC A,@A+DPTR
SETB P1.2
MOV P0,A
CLR P1.3
ACALL DELAY2
SETB P1.3
DJNZ R5,DISP
RET
DELAY2: MOV R7,#2
D01: MOV R6,#10
DJNZ R6,$
DJNZ R7,D01
RET
TAB1: DB 0,0,1,2,2,3,4,4,5,6,6,7,7,8,8,9
TAB2: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0BFH,0FFH
TAB3: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,40H,0
END
不过,没有交流就不能知道缺陷,也就不能在原有的基础上进步。本着交流的原则,我在不同的帖子里把前一段时间里做过的一些小程序传上来,供有兴趣的朋友参考。当然,能看出问题,并指出来,或者能够给出改进建议,则我在此不胜感激了。呵呵。
我的18b20测温来咯。
声明:本程序在CEPARK实验板上通过。如有问题,请留言。
;18b20单点测温程序
;18b20变量部分
TEMPL EQU 0030H ;温度值低字节
TEMPH EQU 0031H ;温度值高字节
TH EQU 0032H ;高温上限
TL EQU 0 ;低温下限
TDOT EQU 100 ;温度小数位
TGE EQU 0035H ;温度个位
TSHI EQU 0036H ;温度十位
TBAI EQU 0037H ;温度百位
TEMP EQU 0038H ;暂存值
TSIGNAL EQU F0 ;符号标志
DAT1 EQU P1.6 ;数据线
CONFIG12 EQU 7FH ;12位精度
ORG 0030H
MAIN: MOV P1,#0FFH
ACALL INIT ;DS18B20初始化 改动过,next
NEXT: ACALL RDTEMP ;读温度值
ACALL DATPRO ;数据处理
ACALL DISPLAY ;显示
SJMP NEXT
;初始化ds1820子程序
INIT: ACALL RESET
MOV A,#0CCH
ACALL WRITE ;写入SKIP ROM指令
MOV A,#4EH
ACALL WRITE ;写入暂存存储器指令
MOV A,#TH ;报警温度上限
ACALL WRITE
MOV A,#TL ;报警温度下限
ACALL WRITE
MOV A,#CONFIG12 ;写入精度配置值
ACALL WRITE
RET
;18b20复位子程序
RESET: CLR EA ;关中断,18b20操作必须关中断
L0: CLR DAT1 ;ds1820总线为低电平复位
MOV R2,#200
L1: CLR DAT1
DJNZ R2,L1 ;总线复位电平保持600us
SETB DAT1 ;释放ds1820总线
MOV R2,#30
L4: DJNZ R2,L4 ;释放ds1820总线保持40us
CLR C ;清存在信号
ORL C,DAT1 ;读入总线信号和C或
JC L0 ;存在吗?不存在则重新来
MOV R6,#80 ;存在,
L5: ORL C,DAT1 ;检测存在信号是否结束
JC L3 ;存在信号结束
DJNZ R6,L5 ;存在信号可能保持320us(240-420)
SJMP L0 ;过了320US,存在信号没结束,重新复位
L3: MOV R2,#240 ;存在信号结束
L2: DJNZ R2,L2 ;延时480US
RET
;读温度子程序
RDTEMP: ACALL RESET
MOV A,#0CCH ;跳过ROM
ACALL WRITE
MOV A,#44H ;启动温度转换
ACALL WRITE
ACALL DELAY ;延时500ms
ACALL RESET ;重新复位 改动1,读取失败于此
MOV A,#0CCH
ACALL WRITE ;跳过ROM
MOV A,#0BEH
ACALL WRITE
ACALL READ ;读温度低字节
MOV TEMPL,A
ACALL READ ;读温度高字节
MOV TEMPH,A
ACALL READ
RET
;向ds1820写操作命令子程序
WRITE: CLR EA ;关中断,18b20操作都要关中断
MOV R3,#8 ;写入ds1820的bit数,一个字节8个bit
WR1: SETB DAT1 ;写之前,总线置高电平
MOV R4,#8
RRC A ;把一个字节data(A)分成8个bit循环移给 C
CLR DAT1 ;开始写入ds1820总线要处于低状态
WR2: DJNZ R4,WR2 ;ds1820总线低电平保持16us? 15us内写到总线上
MOV DAT1,C ;写入一个bit
MOV R4,#30
WR3: DJNZ R4,WR3 ;等待60us
DJNZ R3,WR1 ;写入下一个bit,连续写两位间的间隔大于1us
SETB DAT1 ;重新释放ds1820总线
RET
;从ds18b20读操作命令子程序
READ: CLR EA ;关中断,18b20操作都要关中断
MOV R6,#8 ;连续读8个bit
RE1: CLR DAT1 ;读前总线保持为低
MOV R4,#6
NOP
SETB DAT1 ;开始读总线释放
RE2: DJNZ R4,RE2 ;持续12us
MOV C,DAT1 ;从ds1820总线读得一个bit
RRC A ;把读得的位值环移给 A
MOV R5,#30
RE3: DJNZ R5,RE3 ;持续60us
DJNZ R6,RE1 ;读下一个bit
SETB DAT1 ;重新释放ds1820总线
RET
DELAY: MOV R7,#240
DJNZ R7,$
RET
;数据处理子程序
;12精度,对高低两字节数据取补,
;然后分别求出小数位,个位,十位,百位
DATPRO: CLR TSIGNAL
MOV A,TEMPH
JNB ACC.7,POSIT ;正数,补数是其本身
SETB TSIGNAL ;负数,TSIGNAL=1
XRL A,#07 ;温度高位与00000111异或
MOV TEMPH,A
MOV A,TEMPL
XRL A,#0FFH ;温度低位与11111111异或
ADD A,#01 ;加1
MOV TEMPL,A
MOV A,TEMPH
ADDC A,#0
MOV TEMPH,A ;负数求补运算完成
POSIT: MOV A,TEMPL ;温度低字节
MOV B,#16
DIV AB ;除以16
MOV TDOT,B ;小数位值保存
MOV TEMP,A ;低位值先保存
MOV A,TEMPH ;温度高字节
ANL A,#07H ;只保留低3位 修改2
MOV B,#16
MUL AB ;权重为16,乘以16
ADD A,TEMP ;加上低位值
MOV B,#10
DIV AB ;除以10,余数为个位值
MOV TGE,B ;个位值保存
MOV B,#10
DIV AB
MOV TSHI,B ;十位值保存
MOV TBAI,A ;百位值保存
RET
;*****************显示子程序**********************
;;四位数码管显示 动态扫描
;;注意事项:CEPARK的试验板是共阳极的板子,三极管
;;基极送低电平点亮数码管 *****重要
DISPLAY:MOV R5,#100
DISP: MOV DPTR,#TAB2
MOV A,#0AH ;负号
JB TSIGNAL,NEGT
MOV A,TBAI
JNZ NEGT
MOV A,#0BH ;百位为0时,不显示百位
NEGT: MOVC A,@A+DPTR
MOV P0,A
CLR P1.0
ACALL DELAY2
MOV A,TSHI
MOVC A,@A+DPTR
SETB P1.0
MOV P0,A ;显示十位
CLR P1.1
ACALL DELAY2
MOV A,TGE
MOVC A,@A+DPTR
SETB P1.1
MOV P0,A ;显示个位
SETB P0.7
CLR P1.2
ACALL DELAY2
CLR P0.7
MOV DPTR,#TAB1
MOV A,TDOT
MOVC A,@A+DPTR
MOV DPTR,#TAB2
MOVC A,@A+DPTR
SETB P1.2
MOV P0,A
CLR P1.3
ACALL DELAY2
SETB P1.3
DJNZ R5,DISP
RET
DELAY2: MOV R7,#2
D01: MOV R6,#10
DJNZ R6,$
DJNZ R7,D01
RET
TAB1: DB 0,0,1,2,2,3,4,4,5,6,6,7,7,8,8,9
TAB2: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0BFH,0FFH
TAB3: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,40H,0
END





