shiriusu 发表于 2011-12-26 21:30:38

DS18B20温度检测程序(汇编)

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      bit0b0h.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 -- 临时数据寄存器
;-----------------------------------------


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


;复位与中断程序定位-----------------------------
org   0000h
ljmpMAIN
org   000bh
ljmpT0_ISR
org   0023h
ljmpUSART_ISR


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


;T0中断子程序-------------------------------------------
T0_ISR:
mov   th0, #63h
mov   tl0, #18h
pushacc          
;LED位右移
mov   a, Scan_Mask
rr    a
mov   Scan_Mask, a
;获得段值
clr   f0
cjnea, #77h, CMP_BBH
mov   a, Figure_bit1
sjmpKINDLE
CMP_BBH:
cjnea, #0bbh, CMP_DDH
mov   a, Figure_bit0
setbf0
sjmpKINDLE
CMP_DDH:
cjnea, #0ddh, CMP_EEH
mov   a, Figure_bitm1
sjmpKINDLE
CMP_EEH:
mov   a, Figure_bitm2
mov   LED_BIT, #0ffh   ;LED全熄灭
;点亮扫描位的LED
KINDLE:
mov   dptr, #LED_SEGMENT
movca, @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
cjner1, #1, IS2
mov   sbuf, Temp_MSByte
reti
IS2:
cjner1, #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
subba, Temp_LSByte
mov   b, a
clr   a
subba, Temp_MSByte
xch   a, b
;获得小数数字
PLUS_TEMP:
pushacc
anl   a, #0fh   ;保留小数点位
pushacc
mov   dptr, #TEMP_BITm1
movca, @a+dptr
mov   Figure_bitm1, a
pop   acc
mov   dptr, #TEMP_BITm2
movca, @a+dptr
mov   Figure_bitm2, a
pop   acc
;获得整数数字
anl   b, #07h
anl   a, #0f0h
orl   a, b
swapa                  ;以上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
djnzr6, $
mov   c, DQ
mov   r6, #250;延时500us
djnzr6, $
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
djnzr6, $
mov   c, DQ
mov   r6, #250;延时500us
djnzr6, $
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
djnzr6, READ_LSB
mov   Temp_LSByte, a
mov   r6, #8
READ_MSB:       
acall READ_SLOT
rrc   a
djnzr6, READ_MSB
mov   Temp_MSByte, a
acall RESET_PULSE    ;复位,停止接收
ret


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


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


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


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


;DS18B20读bit
READ_SLOT:
clr   c
mov   DQ, c
nop
setbc
mov   DQ, c
nop
nop
mov   c, DQ
mov   r7, #35;延时60us
djnzr7, $
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

highter 发表于 2011-12-28 14:51:41

有没有18s20格式的?

xiaodian2008 发表于 2011-12-29 22:02:35

唔~现在除非有人刻意去看汇编,一般都是直接用C写程序,所以这段代码作用不大。。

yangjl2010 发表于 2012-3-5 17:54:44

汇编代码可以精确的控制时序,也有优势,谢谢共享
页: [1]
查看完整版本: DS18B20温度检测程序(汇编)