📄 ds18b20-lcd.asm
字号:
JB FLAG1,RE_18B20A
RET
RE_18B20A:
CALL RESET
MOV A,#0CCH ;跳过ROM匹配
LCALL WRITE
MOV A,#4EH ;写暂存寄存器
LCALL WRITE
MOV A,TEMP_TH ;TH(报警上限)
LCALL WRITE
MOV A,TEMP_TL ;TL(报警下限)
LCALL WRITE
MOV A,#7FH ;12位精确度
LCALL WRITE
RET
;------------------------------------------------------------
WRITE_E2:
CALL RESET
MOV A,#0CCH ;跳过ROM匹配
LCALL WRITE
MOV A,#48H ;把暂存器里的温度报警值拷贝到EEROM
LCALL WRITE
RET
;--------------------------------------------------------------
READ_E2:
CALL RESET
MOV A,#0CCH ;跳过ROM匹配
LCALL WRITE
MOV A,#0B8H ;把EEROM里的温度报警值拷贝回暂存器
CALL WRITE
RET
;--------------------------------------------------------------
;将自定义字符写入LCD1602的CGRAM中
;--------------------------------------------------------------
STORE_DATA:
MOV A,#40H
CALL WCOM
MOV R2,#08H
MOV DPTR,#D_DATA
MOV R3,#00H
S_DATA:
MOV A,R3
MOVC A,@A+DPTR
CALL WDATA ;写入数据
INC R3
DJNZ R2,S_DATA
RET
D_DATA:
DB 0CH,12H,12H,0CH,00H,00H,00H,00H
;==============================================================
write: mov r2,#8 ;一共8位数据
CLR C
wr1:
clr date_line ;开始写入DS18B20总线要处于复位(低)状态
mov r3,#07
djnz r3,$ ;总线复位保持16微妙以上
rrc a ;把一个字节DATA 分成8个BIT环移给C
mov date_line,c ;写入一个BIT
mov r3,#3CH
djnz r3,$ ;等待100微妙
setb date_line ;重新释放总线
nop
djnz r2,wr1 ;写入下一个BIT
setb date_line
ret
;--------------------------------------------------------------------
read: mov r4,#4 ; 将温度低位、高位、TH、TL从DS18B20中读出
mov r1,#TEMPL ; 存入25H、26H、27H、28H
re00: mov r2,#8
re01: clr cy
setb date_line
nop
nop
clr date_line ;读前总线保持为低
nop
nop
nop
setb date_line ;开始读总线释放
mov r3,#09 ;延时18微妙
djnz r3,$
mov c,date_line ;从DS18B20总线读得一个BIT
mov r3,#3CH
djnz r3,$ ;等待100微妙
rrc a ;把读得的位值环移给A
djnz r2,re01 ;读下一个BIT
mov @r1,a
inc r1
djnz r4,re00
ret
CONVTEMP: MOV A,TEMPH ;判温度是否零下
ANL A,#80H
JZ TEMPC1 ;温度零上转
CLR C
MOV A,TEMPL ;二进制数求补(双字节)
CPL A ;取反加1
ADD A,#01H
MOV TEMPL,A
MOV A,TEMPH
CPL A
ADDC A,#00H ;判断是否有进位 加一有可能进位
MOV TEMPH,A
SJMP TEMPC11
TEMPC1: MOV TEMPHC,#0AH ;+
TEMPC11: MOV A,TEMPHC
SWAP A
MOV TEMPHC,A
MOV A,TEMPL
ANL A,#0FH
MOV TEMPPOINT,A;乘0.0625
MOV DPTR,#TEMPDOTTAB
MOVC A,@A+DPTR
MOV TEMPLC,A ;TEMPLC LOW=小数部分 BCD
MOV A,TEMPL ;整数部分
ANL A,#0F0H ;取出高四位
SWAP A
MOV TEMPL,A
MOV A,TEMPH ;取出低四位
ANL A,#0FH
SWAP A
ORL A,TEMPL ;重新组合
MOV TEMP_ZH,A
LCALL HEX2BCD1
MOV TEMPL,A
ANL A,#0F0H
SWAP A
ORL A,TEMPHC ;TEMPHC LOW = 十位数 BCD
MOV TEMPHC,A
MOV A,TEMPL
ANL A,#0FH
SWAP A ;TEMPLC HI = 个位数 BCD
ORL A,TEMPLC
MOV TEMPLC,A
MOV A,R4
JZ TEMPC12
ANL A,#0FH
SWAP A
MOV R4,A
MOV A,TEMPHC ;TEMPHC HI = 百位数 BCD
ANL A,#0FH
ORL A,R4
MOV TEMPHC,A
TEMPC12: RET
;---------------------------------------------------------------
HEX2BCD1:
MOV B,#064H ;十六进制-> BCD
DIV AB ;B= A % 100
MOV R4,A ;R7 = 百位数
MOV A,#0AH
XCH A,B
DIV AB ;B = A % B
SWAP A
ORL A,B
RET
TEMPDOTTAB:
DB 00H,00H,01H,01H,02H,03H,03H,04H
DB 05H,05H,06H,06H,07H,08H,08H,09H
;=====================================================
LOOK_ALARM:
MOV DPTR,#M_ALAX2 ;指针指到显示信息区
MOV A,#2 ;显示在第二行
CALL LCD_PRINT
MOV A,#0C6H
CALL TEMP_BJ1
MOV A,TEMP_TH ;加载TH数据
MOV LCD_X,#3 ;设置位置
CALL SHOW_DIG2H ;显示数据
MOV A,#0CEH
CALL TEMP_BJ1
MOV A,TEMP_TL ;加载TL数据
MOV LCD_X,#12 ;设置位置
CALL SHOW_DIG2L ;显示数据
RET
;--------------------------------------------
M_ALAX1:
DB " LOOK ALERT CODE",0
M_ALAX2:
DB "TH: TL: ",0
;--------------------------------------------
TEMP_BJ1:
CALL WCOM
MOV DPTR,#BJ2 ;指针指到显示信息区
MOV R1,#0
MOV R0,#2
BBJJ2: MOV A,R1
MOVC A,@A+DPTR
CALL WDATA
INC R1
DJNZ R0,BBJJ2
RET
BJ2:
DB 00H,"C"
;---------------------------------------------------
SHOW_DIG2H: ;在 LCD 的第二行显示数字
MOV B,#100
DIV AB
ADD A,#30H
PUSH B
MOV B,LCD_X
CALL LCDP2
POP B
MOV A,#0AH
XCH A,B
DIV AB
ADD A,#30H
INC LCD_X
PUSH B
MOV B,LCD_X
CALL LCDP2
POP B
INC LCD_X
MOV A,B
MOV B,LCD_X
ADD A,#30H
CALL LCDP2
RET
SHOW_DIG2L: ;在 LCD 的第二行显示数字
MOV B,#100
DIV AB
MOV A,#0AH
XCH A,B
DIV AB
ADD A,#30H
PUSH B
MOV B,LCD_X
CALL LCDP2
POP B
INC LCD_X
MOV A,B
MOV B,LCD_X
ADD A,#30H
CALL LCDP2
RET
DISPBCD:
MOV A,TEMPLC
ANL A,#0FH
MOV 70H,A ;小数位
MOV A,TEMPLC
SWAP A
ANL A,#0FH
MOV 71H,A ;个位
MOV A,TEMPHC
ANL A,#0FH
MOV 72H,A ;十位
MOV A,TEMPHC
SWAP A
ANL A,#0FH
MOV 73H,A ;百位
MOV A,TEMPHC
ANL A,#0F0H
CJNE A,#010H,DISPBCD0
SJMP DISPBCD2
DISPBCD0: MOV A,TEMPHC
ANL A,#0FH
JNZ DISPBCD2 ;十位数是0
MOV A,TEMPHC
SWAP A
ANL A,#0FH
MOV 73H,#0AH ;符号位不显示
MOV 72H,A ;十位数显示符号
DISPBCD2: RET
CONV:
MOV A,73H ;加载百位数据
MOV LCD_X,#6 ;设置位置
CJNE A,#1,CONV1
JMP CONV2
CONV1: MOV A,#" "
MOV B,LCD_X
CALL LCDP2
JMP CONV3
CONV2: CALL SHOW_DIG2 ;显示数据
CONV3: INC LCD_X ;
mov a,72h ;十位
CALL SHOW_DIG2
inc LCD_X
mov a,71h ;个位
CALL SHOW_DIG2
inc LCD_X
MOV A,#'.'
MOV B,LCD_X
CALL LCDP2
MOV A,70h ;加载小数点位
INC LCD_X ;设置位置
CALL SHOW_DIG2 ;显示数据
RET
;-------------------------------------------------------
SHOW_DIG2: ;在 LCD 的第二行显示数字
ADD A,#30H
MOV B,LCD_X
CALL LCDP2
RET
;---------------------------------------------------------
LCDP2: ;在LCD的第二行显示字符
PUSH ACC ;
MOV A,B ;设置显示地址
ADD A,#0C0H ;设置LCD的第二行地址
CALL WCOM ;写入命令
POP ACC ;由堆栈取出A
CALL WDATA ;写入数据
RET
;---------------------------------------------------------
SET_LCD: ;对 LCD 做初始化设置及测试
CLR LCD_EN
CALL INIT_LCD ;初始化 LCD
CALL STORE_DATA ;将自定义字符存入LCD的CGRAM
RET
INIT_LCD: ;8位I/O控制 LCD 接口初始化
MOV A,#38H ;双列显示,字形5*7点阵
CALL WCOM
call delay1
MOV A,#38H
CALL WCOM
call delay1
MOV A,#38H
CALL WCOM
call delay1
MOV A,#0CH ;开显示,显示光标,光标不闪烁
CALL WCOM
call delay1
MOV A,#01H ;清除 LCD 显示屏
CALL WCOM
call delay1
RET
;==================================================
CLR_LINE1: ;清除LCD的第一行字符
MOV A,#80H ;设置 LCD 的第一行地址
CALL WCOM ;
MOV R0,#24 ;设置计数值
C1: MOV A,#' ' ;载入空格符至LCD
CALL WDATA ;输出字符至LCD
DJNZ R0,C1 ;计数结束
RET
;==================================================
LCD_PRINT: ;在LCD的第一行或第二行显示字符
CJNE A,#1,LINE2 ;判断是否为第一行
LINE1: MOV A,#80H ;设置 LCD 的第一行地址
CALL WCOM ;写入命令
CALL CLR_LINE ;清除该行字符数据
MOV A,#80H ;设置 LCD 的第一行地址
CALL WCOM ;写入命令
JMP FILL
LINE2: MOV A,#0C0H ;设置 LCD 的第二行地址
CALL WCOM ;写入命令
CALL CLR_LINE ;清除该行字符数据
MOV A,#0C0H ;设置 LCD 的第二行地址
CALL WCOM
FILL: CLR A ;填入字符
MOVC A,@A+DPTR ;由消息区取出字符
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -