玩转CEPARK51实验板DS18B20之一
;使用11.0592MH晶振,每个机器周期为1.085us
;1.0版本
lcd_rs bit p1.0 ;LCD1602 RS控制端
lcd_rw bit p1.1 ;LCD1602 RW控制端
lcd_en bit p1.2 ;LCD1602 EN控制端
lcd_bus equ p0 ;LCD1602 数据总线
ds1820_dat bit p1.6 ;温度传感器18B20数据口
buzzer bit p1.7 ;蜂鸣器控制口
ds1820_tl equ 20h ;18B20温度保存低8位
ds1820_th equ 21h ;18B20温度保存高8位
ds1820_flag equ 30h ;18B20存在标志,1为存在
delay1 equ 31h ;延时用
delay2 equ 32h ;延时用
delay3 equ 33h ;延时用
org 0000h
ljmp main
org 0040h
main: mov sp,#60h ;将读取到的1820数据送串口查看用
mov scon,#50h
mov tmod,#20h
mov th1,#0f3h
mov tl1,#0f3h
setb tr1
lcall lcd_init
mov a,#80h
lcall lcd_wcmd
mov dptr,#lcdline1
lcall lcd_disp
mov a,#0c0h
lcall lcd_wcmd
mov dptr,#lcdline2
lcall lcd_disp
mov r5,#20
menu2: lcall d50ms
djnz r5,menu2
lcall ds1820_reset
jb ds1820_flag,ds1820ok
ljmp ds1820err
m1: ljmp m1
ds1820ok:
mov a,#80h
lcall lcd_wcmd
mov dptr,#ds1820ok1
lcall lcd_disp
mov a,#0c0h
lcall lcd_wcmd
mov dptr,#ds1820ok2
lcall lcd_disp
buzzok: lcall buzz ;DS1820检测到,蜂鸣器短暂响一下作为提示
buzzok2:lcall ds1820_readtemp ;调用ds1820读取温度子程序
lcall ds1820_cov ;调用ds1820转换温度子程序
ljmp buzzok2 ;反复读取温度并显示
ds1820err: ;没检测到ds1820
mov a,#80h
lcall lcd_wcmd
mov dptr,#ds1820err1
lcall lcd_disp
mov a,#0c0h
lcall lcd_wcmd
mov dptr,#ds1820err2
lcall lcd_disp
mov r2,#10
buzzerr:lcall buzz ;DS1820出错蜂鸣器响长响作为提示
djnz r2,buzzerr
m3: ljmp m3
ds1820_readtemp: ;ds1820获取温度
lcall ds1820_reset ;ds1820复位
mov a,#0cch ;跳过rom
lcall ds1820_write
mov a,#44h
lcall ds1820_write ;启动温度转换
; lcall d800ms
lcall ds1820_reset
mov a,#0cch
lcall ds1820_write
mov a,#0beh ;读暂存器
lcall ds1820_write
mov r4,#9 ;读ds1820寄存器,共9个,第一和第二个字节是温度的低8位和高8位
mov r0,#ds1820_tl ;从ds1820_tl开始保存
read_loop:
lcall ds1820_read
mov @r0,a
inc r0
djnz r4,read_loop
lcall ds1820_reset
ret
ds1820_cov: ;ds1820转换温度
mov a,#0c0h ;1602第二行第一个位置开始显示温度
lcall lcd_wcmd
mov a,ds1820_th
jnb acc.7,ds1820_cov1 ;判断是正温度还是负温度,其中acc.7~acc.3为1表示是负温度,0是正温度
mov a,#"-" ;如果是负温度则写"-"
lcall lcd_wdata
clr c
mov a,ds1820_tl ;将低8位取反加1后再送回保存位置
cpl a
add a,#1
mov ds1820_tl,a
mov a,ds1820_th ;将高8位取反,加低8位的进位位后送回保存位置
cpl a
addc a,#0
mov ds1820_th,a
ljmp ds1820_cov3
ds1820_cov1:
jc ds1820_cov2
ds1820_cov2:
mov a,#"+"
lcall lcd_wdata
clr c
ds1820_cov3: ;把高8位和低8位的整数部分合并在一起
mov r1,#50h
mov a,ds1820_tl
swap a
anl a,#0fh
mov @r1,a
mov a,ds1820_th
swap a
anl a,#0f0h
xchd a,@r1 ;a和r1的低4位互换并存于a中,此时a中保存的位温度的整数部分
;-------------------------------------------
mov b,#100
div ab ;取百位
lcall ds1820_tempdisp ;显示百位
ds1820_cov4: ;十位
mov a,b
mov b,#10;取十位
div ab
lcall ds1820_tempdisp ;显示十位
ds1820_cov5: ;个位
mov a,b
lcall ds1820_tempdisp ;显示个位
;-----------------------------------------
mov a,#".";显示小数点
lcall lcd_wdata
mov a,ds1820_tl
anl a,#0fh
mov b,#10
mul ab
mov b,#16
div ab
lcall ds1820_tempdisp ;显示小数点的个位
mov a,#0dfh
lcall lcd_wdata
mov a,#"C"
lcall lcd_wdata
ret
;=====================================================
ds1820_tempdisp: ;ds1820温度显示在1602上
mov dptr,#ds1820_temptab
movc a,@a+dptr
lcall lcd_wdata
ret
ds1820_temptab: db "0123456789"
lcd_disp:
mov r1,#16
lcd_disp1:
mov a,#00h
movc a,@a+dptr
lcall lcd_wdata
inc dptr
djnz r1,lcd_disp1
ret
;======================================================
;将ds1820复位并判ds1820是否存在,存在则将标志ds1820_flag置1,否则置0
ds1820_reset:
clr ds1820_flag
clr ds1820_dat ;拉低总线
lcall d480us
setb ds1820_dat ;释放总线后等待ds1820返回存在脉冲(存在脉冲低电平)
lcall d15us
lcall d15us
mov c,ds1820_dat
jc ds1820_err ;没有返回存在脉冲
lcall d480us
ds1820_1:
setb ds1820_flag ;置标志位,说明DS1820存在
ljmp ds1820_2
ds1820_err:
clr ds1820_flag ;清标志位,说明DS1820不存在
; ljmp ds1820_reset
ds1820_2:
setb ds1820_dat ;释放总线
ret
;======================================================
;======================================================
;ds1820写子程序,入口为a(要写入的数据)
ds1820_write:
mov r2,#8 ;写8次(一个字节8个bit)
ds1820_wbit: ;写1个bit
clr ds1820_dat ;拉低总线,产生写时间隙
lcall d15us
rrc a ;从最低位开始,将acc.0移到c里
mov ds1820_dat,c
lcall d60us
setb ds1820_dat ;释放总线
nop ;延时约2us,时序图上要求大于1us
nop
djnz r2,ds1820_wbit ;写完8bit(一个字节)后返回,否则继续写
ret
;======================================================
;======================================================
;ds1820读一字节子程序,出口为A(读出的数据)
ds1820_read:
mov r2,#8 ;读8次(一个字节8个bit)
ds1820_rbit:
clr ds1820_dat ;拉低总线
nop
nop
nop
nop
setb ds1820_dat ;释放总线,产生读时间隙
lcall d8us
mov c,ds1820_dat;读入总线状态到c
rrc a ;移到a中
lcall d60us
setb ds1820_dat ;释放总线
nop ;延时约2us,时序图上要求大于1us
nop
djnz r2,ds1820_rbit ;读完8bit(一个字节)后返回,否则继续读
; mov sbuf,a ;将每次读的数据通过串口发给PC,2400bps
ret
;======================================================
;======================================================
;lcd初始化
lcd_init:
lcall d5ms
lcall d5ms
lcall d5ms
mov a,#38h
lcall lcd_wcmd
lcall d5ms
mov a,#38h
lcall lcd_wcmd
lcall d5ms
mov a,#38h
lcall lcd_wcmd
mov a,#38h
lcall lcd_wcmd
mov a,#08h
lcall lcd_wcmd
mov a,#01h
lcall lcd_wcmd
mov a,#06h
lcall lcd_wcmd
mov a,#0ch
lcall lcd_wcmd
ret
;======================================================
;======================================================
;写数据,入口寄存器acc
lcd_wdata:
mov lcd_bus,a
setb lcd_rs
clr lcd_rw
clr lcd_en
lcall d3ms
setb lcd_en
ret
;======================================================
;======================================================
;写指令,入口寄存器acc
lcd_wcmd:
mov lcd_bus,a
clr lcd_rs
clr lcd_rw
clr lcd_en
lcall d3ms
setb lcd_en
ret
;======================================================
;======================================================
;蜂鸣器提示音
buzz:
mov delay3,#250
buzz0: cpl buzzer
lcall d480us
djnz delay3,buzz0
ret
;======================================================
;======================================================
;程序中用到的延时子程序合集
;8us延时
d8us:
mov delay1,#3
d8us1: djnz delay1,d8us1
ret
;15us延时
d15us:
mov delay1,#6
nop
d15us1: djnz delay1,d15us1
ret
;60us延时
d60us:
mov delay1,#27
d60us1: djnz delay1,d60us1
ret
;480us延时
d480us:
mov delay1,#221
d480us1:djnz delay1,d480us1
ret
;约3ms延时
d3ms:
d3ms0: mov delay1,#10
d3ms1: mov delay2,#150
d3ms2: djnz delay2,d3ms2
djnz delay1,d3ms1
ret
;约5ms延时
d5ms:
d5ms0: mov delay1,#10
d5ms1: mov delay2,#250
d5ms2: djnz delay2,d5ms2
djnz delay1,d5ms1
ret
;约50ms延时
d50ms:
d50ms0: mov delay1,#255
d50ms1: mov delay2,#255
d50ms2: djnz delay2,d50ms2
djnz delay1,d50ms1
ret
lcdline1: db "Temperature Test"
lcdline2: db "Please Waiting.."
ds1820ok1: db " www.cepark.com "
ds1820ok2: db " Ver:1.0"
ds1820err1: db " DS18B20 Error "
ds1820err2: db "Temp: --------- "
end






