📄 lcd2402.asm
字号:
SWAP A ;TEMPLC HI = 个位数 BCD
ORL A,TEMPLC
MOV TEMPLC,A
MOV A,R4
JZ TC3
ANL A,#0FH
SWAP A
MOV R4,A
MOV A,TEMPHC ;TEMPHC HI = 百位数 BCD
ANL A,#0FH
ORL A,R4
MOV TEMPHC,A
TC3: 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
;-------------------------
; 小数部分码表
DOTTAB:
DB 00H,00H,01H,01H,02H,03H,03H,04H
DB 05H,05H,06H,06H,07H,08H,08H,09H
;-------------------------
;--------- 显示区BCD 码温度值刷新子程序 ----------
;显示区 BCD 码温度值刷新
DISP_BCD:
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,DI0
SJMP DI2
DI0: MOV A,TEMPHC
ANL A,#0FH
JNZ DI2 ;十位数是0
MOV A,TEMPHC
SWAP A
ANL A,#0FH
MOV 73H,#0AH ;符号位不显示
MOV 72H,A ;十位数显示符号
DI2: RET
;------------------- DS18B20复位初始化子程序 ----------------------
RESET_1820: ;复位(有具体的时序要求)
SETB DQ
NOP
CLR DQ
;――――――――――――
;主机发出延时537微秒的复位低脉冲
MOV R1,#3
DLY: MOV R0,#107
DJNZ R0,$
DJNZ R1,DLY
;――――――――――――
;然后拉高数据线
SETB DQ
NOP
NOP
NOP
;――――――――――――
MOV R0,#25H
T2: JNB DQ ,T3 ;等待DS18B20回应
DJNZ R0, T2
JMP T4
;――――――――――――
T3: SETB FLAG ;置标志位,表示DS1820存在
JMP T5
;――――――――――――
T4: CLR FLAG ;清标志位,表示DS1820不存在
JMP T7
;――――――――――――
T5: MOV R0,#117
T6: DJNZ R0,T6 ;时序要求延时一段时间
;――――――――――――
T7: SETB DQ
RET ;复位子程序
;------------------- 写入DS18B20子程序 -----------------------
WRITE_1820: ;写入DS18B20(有具体的时序要求)
MOV R2,#8 ;一共8位数据
CLR C
WR1:
CLR DQ ;总线低位,开始写入
MOV R3,#6
DJNZ R3,$ ;保持16微秒以上
RRC A ;把字节DATA分成8个BIT环移给C
MOV DQ, C ;写入一个BIT
MOV R3,#23
DJNZ R3,$ ;等待
SETB DQ ;重新释放总线
NOP
DJNZ R2,WR1 ;写入下一个BIT
SETB DQ
RET ;写入子程序
;--------------------- 读出DS18B20子程序 --------------------
READ_1820: ;; 将温度低位、高位、TH、TL从DS18B20中读出
MOV R4,#4 ;mov r4,#4
MOV R1,#TEMPL ; 存入25H、26H、27H、28H
RE0:
MOV R2,#8 ;数据一共有8位
RE1:
CLR C
SETB DQ
NOP
NOP
CLR DQ ;读前总线保持为低
NOP
NOP
NOP
SETB DQ ;开始读总线释放
MOV R3,#9
DJNZ R3,$ ;延时18微妙
MOV C, DQ ;从总线读到一个BIT
MOV R3,#23 ;
DJNZ R3,$ ;等待50微秒
RRC A ;把读得的位价值环移给A
DJNZ R2,RE1 ;读下一个BIT
MOV @R1,A
INC R1 ; R1内数据递增
DJNZ R4,RE0
RET ;读出子程序
;=================== LCD 1602 显示程序 ======================
;初始化设置
SET_LCD: ;对 LCD 做初始化设置及测试
CLR E
CALL INIT_LCD ;初始化 LCD
CALL STORE_DATA ;将自定义字符存入LCD的CGRAM
RET
;----------- LCD 初始化子程序 -----------
INIT_LCD: ;8位I/O控制 LCD 接口初始化
MOV A,#38H
CALL WR_COMM
call delay1
MOV A,#0CH ;开显示,显示光标,光标不闪烁
CALL WR_COMM
call delay1
MOV A,#01H ;清除 LCD 显示屏
CALL WR_COMM
call delay1
RET
;----------- 显示温度标记子程序 ------------
;显示温度标记子程序
TEMP_BJ:
MOV A, #0CBH
ACALL WR_COMM
MOV DPTR,#BJ ;指针指到显示消息
MOV R1 ,#0
MOV R0 ,#2
TP1: MOV A,R1
MOVC A,@A+DPTR
ACALL WR_DATA
INC R1
DJNZ R0,TP1
RET
BJ:
DB 00H,"C"
;----------- 自定义字符子程序 ------------
;将自定义字符写入LCD1602的CGRAM中
STORE_DATA:
MOV A,#40H
ACALL WR_COMM
MOV R2,#08H
MOV DPTR,#D_DATA
MOV R3,#00H
S_DATA:
MOV A,R3
MOVC A,@A+DPTR
ACALL WR_DATA ;写入数据
INC R3
DJNZ R2,S_DATA
RET
;---------------------------
D_DATA:
DB 0CH,12H,12H,0CH,00H,00H,00H,00H
;--------------
;----------- 显示“OK”信息子程序 ---------
MEU_OK:
MOV DPTR,#M_OK1 ;指针指到显示消息
MOV A,#1 ;显示在第一行
CALL LCD_PRINT
MOV DPTR,#M_OK2 ;指针指到显示消息
MOV A,#2 ;显示在第一行
CALL LCD_PRINT
RET
M_OK1:
DB " DS18B20 OK ",0
M_OK2:
DB " TEMP: ",0
;----------显示“ERROR”信息子程序-------
MEU_ERROR:
MOV DPTR,#M_ERROR1 ;指针指到显示消息1
MOV A,#1 ;显示在第一行
ACALL LCD_PRINT
MOV DPTR,#M_ERROR2 ;指针指到显示消息1
MOV A,#2 ;显示在第一行
ACALL LCD_PRINT
RET
;---------------
M_ERROR1:
DB " DS18B20 ERROR ",0
M_ERROR2:
DB " TEMP: ---- ",0
;---------------
;-------显示菜单 ------
LCD_PRINT: ;在LCD的第一行或第二行显示字符
CJNE A,#1,LINE2 ;判断是否为第一行
LINE1:
ACALL CLR_LINE ;清除该行字符数据
MOV A,#80H ;设置 LCD 的第一行地址
ACALL WR_COMM ;写入命令
JMP FILL
LINE2:
ACALL CLR_LINE ;清除该行字符数据
MOV A,#0C0H ;设置 LCD 的第二行地址
ACALL WR_COMM
FILL: CLR A ;填入字符
MOVC A,@A+DPTR ;由消息区取出字符
CJNE A,#0,LC1 ;判断是否为结束码
RET
LC1: ACALL WR_DATA ;写入数据
INC DPTR ;指针加1
JMP FILL ;继续填入字符
RET
;---------- 数据转换 --------------
CONV:
MOV A,73H ;加载百位数据
MOV X,#6 ;设置位置
CJNE A,#1,CO1
JMP CO2
CO1: MOV A,#" "
MOV B,X
ACALL LCDP2
JMP CO3
CO2: ACALL SHOW_LINE2 ;显示数据
CO3: INC X ;
MOV A,72H ;mov a,72h ;十位
ACALL SHOW_LINE2
INC X ;inc X
MOV A, 71H ;mov a,71h ;个位
ACALL SHOW_LINE2
INC X ;inc X
MOV A,#'.'
MOV B,X
ACALL LCDP2
MOV A,70H ;h ;加载小数点位
INC X ;设置位置
ACALL SHOW_LINE2 ;显示数据
RET
;------显示第二行 ------
SHOW_LINE2: ;在 LCD 的第二行显示数字
ADD A,#30H
MOV B,X
ACALL LCDP2
RET
;-----------------------
LCDP2: ;在LCD的第二行显示字符
PUSH ACC ;
MOV A,B ;设置显示地址
ADD A,#0C0H ;设置LCD的第二行地址
ACALL WR_COMM ;写入命令
POP ACC ;由堆栈取出A
ACALL WR_DATA ;写入数据
RET
;------ 写指令程序-----
WR_COMM: ;以8位控制方式将命令写至LCD
MOV P1,A ;写入命令
CLR RS ;RS=L,RW=L,D0-D7=指令码,E=高脉冲
CLR RW
SETB E
ACALL DELAY1
CLR E
RET
;----------写数据程序 --------------
WR_DATA: ;以8位控制方式将数据写至LCD
MOV P1,A ;写入数据
SETB RS
CLR RW
SETB E
CALL DE
CLR E
CALL DE
RET
;---------- 清除LCD 的字符-------------
CLR_LINE: ;清除该行 LCD 的字符
MOV R0,#24
CL1: MOV A,#' '
ACALL WR_DATA
DJNZ R0,CL1
RET
;--------------
CLR_LINE1: ;清除LCD的第一行字符
MOV A,#80H ;设置 LCD 的第一行地址
ACALL WR_COMM ;
MOV R0,#24 ;设置计数值
C1: MOV A,#' ' ;载入空格符至LCD
CALL WR_DATA ;输出字符至LCD
DJNZ R0,C1 ;计数结束
RET
;------------- 鸣响子程序------------
SPK_BZ:
MOV R6,#100
BZ2: ACALL DEX1
CPL SPK
DJNZ R6,BZ2
MOV R5,#10
ACALL DELAY
RET
DEX1: MOV R7,#180
DE2: NOP
DJNZ R7,DE2
RET
;-------------延时子程序-------------
DELAY: ;(R5)*延时10MS
MOV R6,#50
DL1: MOV R7,#100
DJNZ R7,$
DJNZ R6,DL1
DJNZ R5,DELAY
RET
DELAY1: ;延时5MS
MOV R6,#25
DL2: MOV R7,#100
DJNZ R7,$
DJNZ R6,DL2
RET
DE:
MOV R7,#250
DJNZ R7,$
RET
;---------------------------
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -