单片机汇编编程
时间:10-02
整理:3721RD
点击:
大家好,我是新手,也是菜鸟,下面是我写的关于DS18B20测温,LCD1602显示温度的程序,但是无法正常显示温度,希望大家帮忙看看哪里错了,应该怎么改。不胜感激。
RS EQU P2.1
RW EQU P2.2
E EQU P2.3
DQ EQU P2.4;DS18B20数据线口
LCD EQU P0;LCD1602与单片机的接口
ORG 0000H
AJMP MAIN
ORG 0020H
MAIN:
MOV SP,#60H
MOV 30H,#00H
MOV 31H,#00H
MOV 32H,#00H
LCALL GET_TEMP;获得温度
LCALL CON_TEMP;将读出的温度进行计算获得温度值,便于显示
LCALL LCD1602;初始化等显示温度的处理
SJMP MAIN
;------------------------读温度数据----------------------
GET_TEMP:
CLR PSW.4
SETB PSW.3 ;设置工作寄存器当前所在的区域
CLR EA ;使用ds1820一定要禁止任何中断产生
LCALL INT ;调用初使化子程序
MOV A,#0CCH
LCALL WRITE ;送入跳过ROM命令
MOV A, #44H
LCALL WRITE ;送入温度转换命令
LCALL INT ;温度转换完全,再次初使化ds1820
MOV A,#0CCH
LCALL WRITE ;送入跳过ROM命令
MOV A,#0BEH ;发出读温度命令
LCALL WRITE ;送入读温度暂存器命令
LCALL READ
MOV R7,A ;读出温度值低字节存入R7
LCALL READ
MOV R6,A ;读出谩度值高字节存入R6
SETB EA
RET
;---------------读出的温度数据进行计算,便于显示-----------
CON_TEMP:
CLR C
MOV R5,#04H;循环次数
EX2:MOV A,R6
RRC A
MOV R6,A
MOV A,R7
RRC A
MOV R7,A
DJNZ R5,EX2
MOV A,R6
RLC A
RLC A
RLC A
RLC A
ANL A,#0FH
MOV DPTR,#TAB_TEMP
MOVC A,@A+DPTR
MOV 30H,A
MOV A,R7
CLR C
MOV B,#0AH
div AB
MOV 32H,A
MOV A,B
ADD A,#10H
MOV 31H,A
RET
;---------------------初始化ds1820子程序-------------------
INT: ;初始化ds1820子程序
CLR EA
L0:CLR DQ ;ds1820总线为低复位电平
MOV R2,#200
L1:CLR DQ
DJNZ R2,L1 ;总线复位电平保持400us
SETB DQ ;释放ds1820总线
MOV R2,#30
L4:DJNZ R2,L4 ;释放ds1820总线保持60us
CLR C ;清存在信号
ORL C,DQ
JC L0 ;存在吗?不存在则重新来
MOV R6,#80
L5:ORL C,DQ
JC L3
DJNZ R6,L5
SJMP L0
L3:MOV R2,#240
L2:DJNZ R2,L2
RET
;---------------------向ds1820写操作命令子程序-------------------
WRITE: ;向ds1820写操作命令子程序
CLR EA
MOV R3,#8 ;写入ds1820的bit数,一个字节8个bit
WR1:SETB DQ
MOV R4,#8
RRC A ;把一个字节data(A)分成8个bit环移给 C
CLR P2.4 ;开始写入ds1820总线要处于复位(低)状态
WR2:DJNZ R4,WR2 ;ds1820总线复位保持16us
MOV P2.4,C ;写入一个bit
MOV R4,#20
WR3:DJNZ R4,WR3 ;等待40us
DJNZ R3,WR1 ;写入下一个bit
SETB P2.4 ;重新释放ds1820总线
RET
;---------------------从ds1820读温度数据子程序-------------------
READ:
CLR EA
MOV R6,#8 ;连续读8个bit
RE1:CLR DQ ;读前总线保持为低
MOV R4,#4
NOP
SETB DQ ;开始读总线释放
RE2:DJNZ R4,RE2 ;持续8us
MOV C,DQ ;从ds1820总线读得一个bit
RRC A ;把读得的位值环移给 A
MOV R5,#30
RE3:DJNZ R5,RE3 ;持续60us
DJNZ R6,RE1 ;读下一个bit
SETB DQ ;重新释放ds1820总线
RET
;---------------------LCD1602的操作-------------------
LCD1602:
MOV SP,#60H
ACALL DD1 ;DD1是LCD初始化
ACALL DD2;DD2是LCD第2行显示TABLE1
RET
;---------------------初始化LCD1602的子程序-------------------
DD1: MOV LCD,#01H ;清屏
CALL ENABLE
MOV LCD,#38H ;显示功能
CALL ENABLE
MOV LCD,#0CH ;显示开关控制
CALL ENABLE
MOV LCD,#06H ;
CALL ENABLE
RET
DD2: MOV LCD,#80H;第1行的开始位置
CALL ENABLE
CALL WRITE1;
RET
;---------------------LCD1602送命令子程序-------------------
ENABLE: CLR RS
CLR RW
CLR E
CALL DELAY
SETB E
RET
WRITE1:
MOV R0,#03H ;显示table中的值
MOV R1,#33H
WRITE2:
DEC R1
MOV A,@R1
;JMP WRITE3
;WRITE4: MOV A,31H
;---------------------LCD1602显示子程序-------------------
WRITE3:
MOV P0,A ;显示
SETB RS
CLR RW
CLR E
CALL DELAY
SETB E
DEC R0
CJNE R0,#00H,WRITE2
RET
DELAY: PUSH ACC
MOV A,R4
MOV R4,#05
D1: MOV R5,#0FFH
DJNZ R5,$
DJNZ R4,D1
MOV R4,A
POP ACC
RET
TAB_TEMP: DB 03FH,06H,06H,5BH,4FH//显示数值
DB 4FH,66H,66H,6DH,7DH
DB 7DH,07H,7FH,7FH,6FH,6FH
END
RS EQU P2.1
RW EQU P2.2
E EQU P2.3
DQ EQU P2.4;DS18B20数据线口
LCD EQU P0;LCD1602与单片机的接口
ORG 0000H
AJMP MAIN
ORG 0020H
MAIN:
MOV SP,#60H
MOV 30H,#00H
MOV 31H,#00H
MOV 32H,#00H
LCALL GET_TEMP;获得温度
LCALL CON_TEMP;将读出的温度进行计算获得温度值,便于显示
LCALL LCD1602;初始化等显示温度的处理
SJMP MAIN
;------------------------读温度数据----------------------
GET_TEMP:
CLR PSW.4
SETB PSW.3 ;设置工作寄存器当前所在的区域
CLR EA ;使用ds1820一定要禁止任何中断产生
LCALL INT ;调用初使化子程序
MOV A,#0CCH
LCALL WRITE ;送入跳过ROM命令
MOV A, #44H
LCALL WRITE ;送入温度转换命令
LCALL INT ;温度转换完全,再次初使化ds1820
MOV A,#0CCH
LCALL WRITE ;送入跳过ROM命令
MOV A,#0BEH ;发出读温度命令
LCALL WRITE ;送入读温度暂存器命令
LCALL READ
MOV R7,A ;读出温度值低字节存入R7
LCALL READ
MOV R6,A ;读出谩度值高字节存入R6
SETB EA
RET
;---------------读出的温度数据进行计算,便于显示-----------
CON_TEMP:
CLR C
MOV R5,#04H;循环次数
EX2:MOV A,R6
RRC A
MOV R6,A
MOV A,R7
RRC A
MOV R7,A
DJNZ R5,EX2
MOV A,R6
RLC A
RLC A
RLC A
RLC A
ANL A,#0FH
MOV DPTR,#TAB_TEMP
MOVC A,@A+DPTR
MOV 30H,A
MOV A,R7
CLR C
MOV B,#0AH
div AB
MOV 32H,A
MOV A,B
ADD A,#10H
MOV 31H,A
RET
;---------------------初始化ds1820子程序-------------------
INT: ;初始化ds1820子程序
CLR EA
L0:CLR DQ ;ds1820总线为低复位电平
MOV R2,#200
L1:CLR DQ
DJNZ R2,L1 ;总线复位电平保持400us
SETB DQ ;释放ds1820总线
MOV R2,#30
L4:DJNZ R2,L4 ;释放ds1820总线保持60us
CLR C ;清存在信号
ORL C,DQ
JC L0 ;存在吗?不存在则重新来
MOV R6,#80
L5:ORL C,DQ
JC L3
DJNZ R6,L5
SJMP L0
L3:MOV R2,#240
L2:DJNZ R2,L2
RET
;---------------------向ds1820写操作命令子程序-------------------
WRITE: ;向ds1820写操作命令子程序
CLR EA
MOV R3,#8 ;写入ds1820的bit数,一个字节8个bit
WR1:SETB DQ
MOV R4,#8
RRC A ;把一个字节data(A)分成8个bit环移给 C
CLR P2.4 ;开始写入ds1820总线要处于复位(低)状态
WR2:DJNZ R4,WR2 ;ds1820总线复位保持16us
MOV P2.4,C ;写入一个bit
MOV R4,#20
WR3:DJNZ R4,WR3 ;等待40us
DJNZ R3,WR1 ;写入下一个bit
SETB P2.4 ;重新释放ds1820总线
RET
;---------------------从ds1820读温度数据子程序-------------------
READ:
CLR EA
MOV R6,#8 ;连续读8个bit
RE1:CLR DQ ;读前总线保持为低
MOV R4,#4
NOP
SETB DQ ;开始读总线释放
RE2:DJNZ R4,RE2 ;持续8us
MOV C,DQ ;从ds1820总线读得一个bit
RRC A ;把读得的位值环移给 A
MOV R5,#30
RE3:DJNZ R5,RE3 ;持续60us
DJNZ R6,RE1 ;读下一个bit
SETB DQ ;重新释放ds1820总线
RET
;---------------------LCD1602的操作-------------------
LCD1602:
MOV SP,#60H
ACALL DD1 ;DD1是LCD初始化
ACALL DD2;DD2是LCD第2行显示TABLE1
RET
;---------------------初始化LCD1602的子程序-------------------
DD1: MOV LCD,#01H ;清屏
CALL ENABLE
MOV LCD,#38H ;显示功能
CALL ENABLE
MOV LCD,#0CH ;显示开关控制
CALL ENABLE
MOV LCD,#06H ;
CALL ENABLE
RET
DD2: MOV LCD,#80H;第1行的开始位置
CALL ENABLE
CALL WRITE1;
RET
;---------------------LCD1602送命令子程序-------------------
ENABLE: CLR RS
CLR RW
CLR E
CALL DELAY
SETB E
RET
WRITE1:
MOV R0,#03H ;显示table中的值
MOV R1,#33H
WRITE2:
DEC R1
MOV A,@R1
;JMP WRITE3
;WRITE4: MOV A,31H
;---------------------LCD1602显示子程序-------------------
WRITE3:
MOV P0,A ;显示
SETB RS
CLR RW
CLR E
CALL DELAY
SETB E
DEC R0
CJNE R0,#00H,WRITE2
RET
DELAY: PUSH ACC
MOV A,R4
MOV R4,#05
D1: MOV R5,#0FFH
DJNZ R5,$
DJNZ R4,D1
MOV R4,A
POP ACC
RET
TAB_TEMP: DB 03FH,06H,06H,5BH,4FH//显示数值
DB 4FH,66H,66H,6DH,7DH
DB 7DH,07H,7FH,7FH,6FH,6FH
END