返回列表 发帖

求助 ~~~DS18B20 问题希望高手帮我解答

本帖最后由 hnrain 于 2009-6-26 18:55 编辑 在cepark的实验板上测温功能基本实现了,但是我想加一个温度报警程序,设定在30度,(超过了的话,就通过单片机p1.7控制蜂鸣器响)不知道在那加上。

所以希望能帮我看看 ,嘿嘿 ,对于我这个菜鸟来说太难了,还是请老鸟多多指教把!!呵呵

还有可不可帮我把注释写全 ,这样以便于我学习程序的执行过程,谢谢了!!!!

源程序
  bw   bit p1.0 ;百位数码管
  sw   bit p1.1 ;十位数码管
  gw   bit p1.2 ;个位数码管
  xs   bit p1.3 ;小数位数码管
  led_bus  equ p0  ;led数码管 数据总线
  ds1820_dat bit p1.6 ;温度传感器18B20数据口
  buzzer  bit p1.7 ;蜂鸣器控制口
  ds1820_tl equ 30h  ;18B20温度保存低8位
  ds1820_th equ 31h  ;18B20温度保存高8位
  bw_buf  equ 3ah  ;百位数码管显示缓冲区
  sw_buf  equ 3bh  ;十位数码管显示缓冲区
  gw_buf  equ 3ch  ;个位数码管显示缓冲区
  xs_buf  equ 3dh  ;小数位数码管显示缓冲区

  ds1820_flag equ 40h  ;18B20存在标志,1为存在
  delay1  equ 41h  ;延时用
  delay2  equ 42h  ;延时用
  delay3  equ 43h  ;延时用
  org  0000h
  ljmp main
  org  0100h
main:  
  lcall ds1820_reset
  jb  ds1820_flag,ds1820ok
  ljmp ds1820err   
m1:  ljmp m1

ds1820ok:
  lcall buzz    ;DS1820检测到,蜂鸣器短暂响一下作为提示
buzzok2:lcall ds1820_readtemp ;调用ds1820读取温度子程序
  lcall ds1820_cov  ;调用ds1820转换温度子程序
  lcall ds1820_tempdisp ;调用ds1820温度显示子程序
  ljmp buzzok2   ;反复读取温度并显示

ds1820err:      ;没检测到ds1820
  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,ds1820_th
  jnb  acc.7,ds1820_cov1  ;判断是正温度还是负温度,其中acc.7~acc.3为1表示是负温度,0是正温度
  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:
  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   ;取百位
  mov  dptr,#ledtab1
  movc a,@a+dptr
  mov  bw_buf,a  ;将百位数字送到百位显示缓冲区
ds1820_cov4: ;十位
  mov  a,b
  mov  b,#10;取十位
  div  ab
  mov  dptr,#ledtab1
  movc a,@a+dptr
  mov  sw_buf,a  ;将十位数字送到十位显示缓冲区
ds1820_cov5:  ;个位
  mov  a,b
  mov  dptr,#ledtab2
  movc a,@a+dptr
  mov  gw_buf,a  ;将个位数字送到个位显示缓冲区
 
;-----------------------------------------
  mov  a,ds1820_tl
  anl  a,#0fh
  mov  b,#10
  mul  ab
  mov  b,#16
  div  ab
  mov  dptr,#ledtab1
  movc a,@a+dptr
  mov  xs_buf,a  ;将小数送到小数位显示缓冲区
  ret

ds1820_tempdisp:     ;ds1820温度显示在1602上
  mov  led_bus,bw_buf
  clr  bw
  lcall dnms
  setb bw
  mov  led_bus,sw_buf
  clr  sw
  lcall dnms
  setb sw
  mov  led_bus,gw_buf
  clr  gw
  lcall dnms
  setb gw
  mov  led_bus,xs_buf
  clr  xs
  lcall dnms
  setb xs
  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

;蜂鸣器提示音
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

;约nms延时
dnms:
dnms0: mov  delay1,#05h
dnms1: mov  delay2,#0a0h
dnms2: djnz delay2,dnms2
  djnz delay1,dnms1
  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

ledtab1: db 0c0h,0f9h,0a4h,0b0h,99h,92h,82h,0f8h,80h,90h
ledtab2: db 040h,079h,024h,030h,19h,12h,02h,078h,00h,10h
  end

 

 

电子园商城推荐:


在线等待解答~~~~

TOP

那位做过的指点下呀,这个不难哟,只是我没做过18B20的试验,不敢乱发言,
你能显示出温度应该只是加一个标志检测位的问题吧,

TOP

关键是 我是菜鸟 基本上学的不咋样 所以不知道 该怎么样写
现在很迷茫 而且很着急 ~~

TOP

汇编不懂,正在学C
无能力两全其美,那就只能独善其身!

TOP

我没做过18B20,但是给你个思路,你把从18B20读过来的数据加一判断,刚好是温度30的那个值你就让蜂鸣器报警不就行了吗?

TOP

我也是这个思路 但是 我单片机学的不好 程序基本上都不怎么会
不知道怎么写 …………贴别晕

TOP

可以把你读出来的温度值转成一个整数...
然后在和你设置的进行判断...这样就可以了...

TOP

div  ab   ;取百位
  mov  dptr,#ledtab1
  movc a,@a+dptr
  mov  bw_buf,a  ;将百位数字送到百位显示缓冲区
ds1820_cov4: ;十位
  mov  a,b
  mov  b,#10;取十位
  div  ab
  mov  dptr,#ledtab1
  movc a,@a+dptr
  mov  sw_buf,a  ;将十位数字送到十位显示缓冲区
ds1820_cov5:  ;个位


在这里面取,好久没用ASM忘了.

TOP

我用CJNE 这个判断行吗?转换后的数存在哪里?
说来很惭愧……我给的那个源程序 我还没有全看懂。……

TOP

我用CJNE 这个判断行吗?转换后的数存在哪里?说来很惭愧……我给的那个源程序 我还没有全看懂。…… lh0427 发表于 2009-6-26 20:29

 

既然学习了,就多花时间去看懂他.如果你是一知半解,又不去花时间了解.那样是对自己发展很不利的...

呵呵.

TOP

这我也知道 所以这个星期一直在看这个程序 无奈底子太薄……也就看懂了点皮毛……我也很想给他搞清楚……
所以到这里来 请各位老人帮帮我这个新手……

TOP

要多看资料学习呀,如果不懂,别人说了也没用呀,花上几天时间好好研究下,等你通过努加研究明白5个问题的时候你就会发现学单片机并不难了

TOP

可是这个是我星期二要交的作业……不然这学期都挂着了
现在发现以前没有好好学 是个错误啊~~~虽然现在醒悟还算不晚 可是时间太紧了 不得已才到这来求索
要是时间足够的话 我肯定能自己研究出来

TOP

星期二,还有三天够了.好坏你也是个大学生,基础好呀,像我这些小学都没读完的,都不怕.努力吧.

TOP

那你指点下 汇编程序得判断句怎么写??这个会了 可能对我来说就好写一点程序了
这个我不太会

TOP

有人能指点我下吗????

TOP

CJNE是可以的,判断数是不是相等,光说这一句是没用的呀,转换后的数据你要自己定一个地址来存储呀,希望对你有用

TOP

没有看程序过程,一个思路,

TOP

用cjne判断是否相等,相等则跳转到报警程序。下面紧接着用jc或者jnc判断C位是否为1来判断大于 or 小于,之后处理

TOP

返回列表

站长推荐 关闭


“AVR事无巨细系列”PDF版正式发布!欢迎下载支持(更新)

花了1个月时间,终于把这个系列写完了,在此留念一下。CEPARK AVR也准备要出售了,这个系列就是为之量身打造的,希望大家多多支持论坛发展。 之前也没有玩过AVR ...


查看