热卖开发板:
  • 51单片机开发板
  • USB开发板
  • AVR单片机开发板
  • 玩转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

       

    声明:CEPARK已尽力确保内容的准确性,但因业务发展和技术服务的需要,有关内容可能会根据实际情况随时更新或者修改,恕不另行通知,不便之处敬请谅解!
      商城推荐
      社区指南
    CEPARK电子园-电子工程师自己的网络家园!
      迷你博客,轻松完成日志发布,管理相册;展示个性自我
      兴趣小组,热点话题,加入您感兴趣的话题讨论小组,一起交流吧
      最新资讯,热门话题与好友一起分享信息,他评论感兴趣的话题
      实名认证,真实交友,还可以轻松快捷的了解好友动态
      邀请您身边的好友,朋友,同事一起加入欢乐圈