📄 text1.asm
字号:
;********************************************************
;name:测温传感器DS18B20的应用
;bye :zxinfeng
;dat :05.08.05
;功能:数字温度计测温范围为-50-125度,精度误差在0.1度之内
;LED直接读显示温度.
;********************************************************
dat equ p3.0
temph equ 30h
templ equ 31h
bcd_0 equ 32h
bcd_1 equ 33h
bcd_10 equ 34h
bcd_100 equ 35h
tempzheng equ 36h
;------程序开始-----------
org 0000h
ajmp main
main: nop
mov sp,#55h
lcall proinit
start:
lcall get_temper ;调用得到温度程序
lcall read_temper ;调用读温度程序
lcall display
ajmp start
;----------------程序初始化程序---------------------
proinit:
clr f0
mov p3,#0
mov templ,#0
mov temph,#0
mov bcd_0,#0
mov bcd_1,#0
mov bcd_10,#0
mov bcd_100,#0
ret
;--------------------取得温度程序段--------------------------
get_temper:
lcall ds18b20init ;发ds18b20复位和存在脉冲
jnb f0,get_end
mov a,#0cch ;总线上只有一个18B20,使用跳过ROM就可以了
lcall writebyte ;写一个字节程序段
mov a,#44h ;发温度转换命令
lcall writebyte
get_end:
ret
;-------------------读出温度程序段---------------------------
read_temper:
lcall ds18b20init
mov a,#0cch
lcall writebyte ;再次跳过ROM
mov a,#0beh ;读暂存器内部命令
lcall writebyte
lcall readtemp ;调用读RAM程序
;把1820中的温度值计到CPU中的程序段
lcall temp_cov ;把读出的温度值进行调整(因为整数部分在TH的低四位和TL的高四位
;要把它们调整到一个寄存器里面)
lcall p16_bcd ;把得到的整数进行BCD码转换
read_end:
ret
;-----------------ds18b20复位和存在脉冲-------------------
ds18b20init:
clr ea
int10: setb dat
nop
mov r2,#200
int11: clr dat ;p3.0作为在DS18B20的单线接口
djnz r2,int11 ;主机复位脉冲是3us*200=600us,(18B20停在低电平超过480us会发生复位)
setb dat ;释放总线
mov r2,#30 ;延时60us,等待状态稳定
int12: djnz r2,int12
clr c
orl c,dat ;看总线有没有变低(即有没有存在脉冲)
jc endint ;C中的数=1,表示DAT是高电平,没有存在脉冲,返回主程序
setb f0 ;有DS18B02存在,建立存在标志位。
mov p1,#0feh ;存在DS18B20,使P1.0口的灯亮
mov r2,#120
int13: djnz r2,int13 ;延时240us,这是存在脉冲的时间
clr c
orl c,dat
jnc int13
ret
endint:
clr f0
mov p1,#7fh ;不存在,使p1.1口的LED亮
ret
;----------写一个字节子程序--------
writebyte:
clr ea
mov r4,#8 ;要写入的字节数
setb dat
nop
nop
wr10: clr dat
mov r2,#8
wr11: djnz r2,wr11 ;等待16us
rrc a
mov dat,c
mov r2,#40
wr12: djnz r2,wr12
setb dat
djnz r4,wr10
ret
;---------------把1820中的温度值读到CPU中的程序段--------
readtemp:
mov r5,#2 ;将温度高位和低位都读出
mov r0,#31h ;将低位存入templ(31H),(高位存入30H)
rd10: clr ea
clr c
mov r4,#8
setb dat
nop
nop
rd11:
clr dat
nop
nop
nop
setb dat ;上述几条指令,是为了产生读时间隙
mov r2,#8
rd12: djnz r2,rd12 ;等待状态稳定,delay16us
mov c,dat ;依次读入DS18B20的数据
rrc a
mov r2,#30
rd13: djnz r2,rd13 ;延时60us
djnz r4,rd11 ;判断8位读出完没有?
mov @r0,a ;把读出的数送出
dec r0
djnz r5,rd10 ;判断16位是否全读出,没有的话反回继续读
setb dat
ret
;-----------------------温度调整程序---------------------
temp_cov:
mov a,temph
anl a,#80h
jz tempz ;最高位是0,跳到正数处理
ajmp tempf ;最高位是1,跳到负数处理
ret
tempf:
clr c
mov a,templ
cpl a
add a,#01h ;取反后的结果加1,这是补码的形式
mov templ,a
mov a,temph
cpl a
addc a,#00h
mov temph,a
tempz:
mov a,templ
anl a,#0fh ;屏蔽掉高四位,只保留小数部分
mov dptr,#temptab
movc a,@a+dptr
mov bcd_0,a ;把小数部分BCD码送入bcd_0
mov a,templ ;整数部分
anl a,#0f0h
swap a
mov templ,a
mov a,temph
anl a,#0fh
swap a
orl a,templ ;把整数部分在高低两个寄存器里的值,合到一个寄存器里
mov tempzheng,a ;把整合到一起的整数放在整数寄存器里
ret
;-----------BCD码转换程序段---------------
p16_bcd:
mov a,tempzheng
mov b,#100
div ab
mov bcd_100,a ;把百位数存放在R7中
mov a,b ;把低位再次取到A中
mov b,#10
div ab
mov bcd_10,a ;十位数入BCD_10
mov bcd_1,b ;个位数入bcd_1
ret
;---------------------------显示子程序--------------------
display:
mov a,bcd_0 ;小数位显示程序
anl a,#0fh ;把其中的整数部分屏蔽掉.
orl a,#70h
mov p0,a
lcall delay8ms
mov a,bcd_1
orl a,#60h ;打开相应的位选(第二位)
mov p0,a
lcall delay8ms
mov a,bcd_10
orl a,#50h
mov p0,a
lcall delay8ms
mov a,bcd_100
orl a,#40h
mov p0,a
lcall delay8ms
ret
;---------------------------------------------------------
delay8ms:
mov r6,#2h
d: mov r7,#20h
d0: djnz r7,d0
djnz r6,d
ret
;--------------小数部分表----------------------------
temptab:
db 00h,00h,01h,01h,02h,03h,03h,04h,05h,05h,06h
db 06h,07h,08h,08h,09h,09h
;----------------------------------------------------
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -