DS18B20温度检测程序(汇编)

2020-02-04 09:29发布

DS18B20连P3.7,温度值保留2位小数驱动4位共阴数码管,段连P1,位连P2。通过串口上传原始温度值。

;=========================================
;DS18B20温度显示程序
;晶振频率12MHz/11.0592MHz
;=========================================

;DS18B20的指令----------------------------
Skip_Rom        equ 0cch
Convert_T       equ 44h
Read_Scratchpad        equ 0beh
;-----------------------------------------


;外设I/O定义------------------------------
DQ      bit  0b0h.7         ;51的P3.7接DS18B20的DQ端
LED_SEG data 90h         ;LED数码管段驱动连接P1
LED_BIT data 0a0h    ;LED数码管位驱动连接P2
;-----------------------------------------


;寄存器使用分配---------------------------
;2fh ----- 堆栈基地址
;R0、R1 -- 指针寄存器
;R7、R6 -- 循环用计数器
;R5、R4 -- 临时数据寄存器
;-----------------------------------------


;变量定义---------------------------
ConvertDone  bit  2fh.7  ;温度转换中清0,转换完毕置1
Temp_MSByte         data 21h         ;温度值高字节(从DS18B20获得的原始数据)
Temp_LSByte         data 20h         ;温度值低字节
Figure_bit1  data 7ch         ;数码管十位数字
Figure_bit0  data 7dh         ;数码管个位数字
Figure_bitm1 data 7eh         ;数码管十分位数字
Figure_bitm2 data 7fh         ;数码管百分位数字
Scan_Mask    data 7bh    ;扫描LED用位码
Send_Offset  data 7ah    ;串行口发送的字节偏移数
;-----------------------------------------


;复位与中断程序定位-----------------------------
org   0000h
ljmp  MAIN
org   000bh
ljmp  T0_ISR
org   0023h
ljmp  USART_ISR


;主程序-----------------------------------------
org   002bh
MAIN:
mov   sp, #2fh                    ;移动堆栈位置
mov   Scan_Mask, #0eeh        ;扫描的位码
mov   Send_Offset, #00h
setb  ConvertDone
;定时器
mov   tmod, #20h
mov   th0, #63h
mov   tl0, #18h
setb  tr0
;串行口
setb  sm1         ;串行口模式1
mov   th1, #0fdh  ;波特率9600
setb  tr1
;使能中断
setb  et0
setb  es
setb  ea
LOOP:
;判断ConvertDone,完毕的话更新温度值并启动新的转换;未完毕的话继续判断,判断到了读取温度值
jb    ConvertDone, CONVERT_OK
lcall READ_SLOT           ;判断是否转换完毕
mov   ConvertDone, c
jnc   LOOP
lcall READ_TEMPERATURE        ;读取温度值
sjmp  LOOP
CONVERT_OK:
lcall START_T     ;启动新的温度转换
clr   ConvertDone
lcall Temp2Figure ;更新温度数字
mov   a, Send_Offset
jnz   LOOP
mov   sbuf, Temp_LSByte  ;通过串口发送温度
sjmp  LOOP


;T0中断子程序-------------------------------------------
T0_ISR:
mov   th0, #63h
mov   tl0, #18h
push  acc          
;LED位右移
mov   a, Scan_Mask
rr    a
mov   Scan_Mask, a
;获得段值
clr   f0
cjne  a, #77h, CMP_BBH
mov   a, Figure_bit1
sjmp  KINDLE
CMP_BBH:
cjne  a, #0bbh, CMP_DDH
mov   a, Figure_bit0
setb  f0
sjmp  KINDLE
CMP_DDH:
cjne  a, #0ddh, CMP_EEH
mov   a, Figure_bitm1
sjmp  KINDLE
CMP_EEH:
mov   a, Figure_bitm2
mov   LED_BIT, #0ffh   ;LED全熄灭
;点亮扫描位的LED
KINDLE:
mov   dptr, #LED_SEGMENT
movc  a, @a+dptr
mov   c, f0
mov   acc.7, c   ;个位加小数点
mov   LED_SEG, a
mov   a, Scan_Mask
orl   a, #0f0h
mov   LED_BIT, a
pop   acc
reti


;串行口中断子程序
USART_ISR:
jbc   ti, SEND_NEXT
reti
SEND_NEXT:
inc   Send_Offset
mov   r1, Send_Offset
cjne  r1, #1, IS2
mov   sbuf, Temp_MSByte
reti
IS2:
cjne  r1, #2, IS3
mov   sbuf, #0ffh    ;结束标志字节
reti
IS3:  ;发送完毕
mov   Send_Offset, #00h
reti


;DS18B20的原始温度数据转换为各位的数字(xx.xx)--------------------------------
Temp2Figure:
mov   b, Temp_MSByte
mov   a, Temp_LSByte
jnb   Temp_MSByte.7, PLUS_TEMP
;负数,先转化为绝对值
clr   a
clr   c
subb  a, Temp_LSByte
mov   b, a
clr   a
subb  a, Temp_MSByte
xch   a, b
;获得小数数字
PLUS_TEMP:
push  acc
anl   a, #0fh   ;保留小数点位
push  acc
mov   dptr, #TEMP_BITm1
movc  a, @a+dptr
mov   Figure_bitm1, a
pop   acc
mov   dptr, #TEMP_BITm2
movc  a, @a+dptr
mov   Figure_bitm2, a
pop   acc
;获得整数数字
anl   b, #07h
anl   a, #0f0h
orl   a, b
swap  a                    ;以上4行将整数部分组合到a里面
mov   b, #10
div   ab        ;a是十位,b是个位
mov   Figure_bit1, a
mov   Figure_bit0, b
ret


;启动温度转换
START_T:
acall RESET_PULSE
mov   r6, #50   ;延时100us
djnz  r6, $
mov   c, DQ
mov   r6, #250  ;延时500us
djnz  r6, $
jc    START_T
mov   a, #Skip_Rom        ;发送Skip ROM指令
acall SEND_INS
mov   a, #Convert_T ;发送Convert T指令
acall SEND_INS
ret


;读取温度值------------------------------------------------------
READ_TEMPERATURE:
acall RESET_PULSE
mov   r6, #50   ;延时100us
djnz  r6, $
mov   c, DQ
mov   r6, #250  ;延时500us
djnz  r6, $
jc    READ_TEMPERATURE
mov   a, #Skip_Rom              ;发送Skip ROM指令
acall SEND_INS
mov   a, #Read_Scratchpad ;发送Read Scratchpad指令
acall SEND_INS
mov   r6, #8
READ_LSB:       
acall READ_SLOT
rrc   a
djnz  r6, READ_LSB
mov   Temp_LSByte, a
mov   r6, #8
READ_MSB:       
acall READ_SLOT
rrc   a
djnz  r6, READ_MSB
mov   Temp_MSByte, a
acall RESET_PULSE    ;复位,停止接收
ret


;DS18B20复位脉冲
RESET_PULSE:
clr   c
mov   DQ, c
mov   r6, #250  ;延时500us
djnz  r6, $
setb  c
mov   DQ, c
ret


;向DS18B20发送指令(A存放待发送指令)
SEND_INS:
mov   r6, #8
NEXT_BIT:       
rrc   a
jnc   ZERO
acall WRITE_SLOT1
djnz  r6, NEXT_BIT
ret
ZERO:
acall WRITE_SLOT0
djnz  r6, NEXT_BIT
ret


;DS18B20写'0'
WRITE_SLOT0:
clr   c
mov   DQ, c
mov   r7, #45  ;延时90us
djnz  r7, $
setb  c
mov   DQ, c
ret


;DS18B20写'1'
WRITE_SLOT1:
clr   c
mov   DQ, c
nop
setb  c
mov   DQ, c
mov   r7, #45  ;延时90us
djnz  r7, $
ret


;DS18B20读bit
READ_SLOT:
clr   c
mov   DQ, c
nop
setb  c
mov   DQ, c
nop
nop
mov   c, DQ
mov   r7, #35  ;延时60us
djnz  r7, $
ret


;LED数码管显示0~9的段数据(共阴)
LED_SEGMENT:
db 3fh, 06h, 5bh, 4fh, 66h
db 6dh, 7dh, 07h, 7fh, 6fh


;温度值十分位数表
TEMP_BITm1:
db 0, 0, 1, 1, 2, 3, 3, 4
db 5, 5, 6, 6, 7, 8, 8, 9


;温度值百分位数表
TEMP_BITm2:
db 0, 6, 3, 9, 5, 1, 8, 4
db 0, 6, 3, 9, 5, 1, 8, 4

end
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
3条回答
highter
1楼-- · 2020-02-04 15:26
有没有18s20格式的?
xiaodian2008
2楼-- · 2020-02-04 20:37
 精彩回答 2  元偷偷看……
yangjl2010
3楼-- · 2020-02-05 00:38
汇编代码可以精确的控制时序,也有优势,谢谢共享

一周热门 更多>