📄 main.asm
字号:
;程序:LCD2402.ASM
; ―――――――――――――――――――――――――――――――
; 温度值存放单元
TEMP_ZH EQU 24H ;实时温度值存放单元
TEMPL EQU 25H ;低温度值存放单元
TEMPH EQU 26H ;高温度值存放单元
TEMP_TH EQU 27H ;高温报警值存放单元
TEMP_TL EQU 28H ;低温报警值存放单元
TEMPHC EQU 29H ;存十位数 BCD码
TEMPLC EQU 2AH ;存个位数 BCD码
KEYBUF EQU 2BH ;存放键值
KEYMODE EQU 2CH ;状态模式,显示当前温度0、设置报警最高温度1和最低温度2
COUNT EQU 2DH ;存放循环计数值
;―――――――――――――
;按键输入引脚定义
KK EQU P2
;―――――――――――――
SPK EQU P3.4 ;蜂鸣器引脚
RELAY EQU P3.1 ;继电器引脚
X EQU 2FH ;LCD 地址变量
;―――――――――――――
;LCD控制引脚
RS EQU P3.5
RW EQU P3.6
E EQU P3.7
;―――――――――――――
FLAG EQU 20H.0 ;DS18B20是否存在标记
BUFFLAG EQU 20H.2
KEYFULL EQU 20H.3 ;
DQ EQU P3.0
;============= 主程序 ==============
ORG 0000H
AJMP MAIN
ORG 0030H
MAIN:
ACALL SET_LCD ;LCD初始化设置子程序
ACALL WR_THL ;将报警上下线写入暂存寄存器子程序
TOOP: ACALL RESET_1820 ;调用18B20复位子程序
JNB FLAG,TOOP1 ;DS1820不存在转移TOOP1处
ACALL MEU_OK ;调用显示"OK"信息子程序
ACALL RE_THL ;把EEROM里温度报警值拷贝回暂存器
ACALL TEMP_BJ ;显示温度标记"℃"
MOV KEYMODE,#00H
MOV KEYBUF,#50 ;设一个初始温度值 50
CLR BUFFLAG
CLR KEYFULL
CLR SPK
JMP TOOP2
TOOP1: ACALL MEU_ERROR ;显示"ERROR"信息
ACALL TEMP_BJ ;显示温度标记
JMP $ ;等待
;――――――――――――――
TOOP2:
ACALL RE_TEMP ;调用读取温度数据子程序
ACALL SET_DATA ;调用处理显示温度数据子程序
ACALL TEMP_COMP ;实际温度值与标记温度值比较子程序
MOV COUNT,#100
TOOP3:
ACALL KEYSCAN ;调用按键扫描子程序
DJNZ COUNT,TOOP3
MOV P0,#0A0H
JMP TOOP2 ;循环
;--------―― 读取温度数据子程序 --------――
RE_TEMP:
ACALL RESET_1820 ;18B20复位子程序
JNB FLAG,TOOP1 ;DS1820不存在
MOV A,#0CCH ;跳过ROM匹配
ACALL WRITE_1820 ;写入子程序
MOV A,#44H ;发出温度转换命令
ACALL WRITE_1820 ;调写入子程序
ACALL RESET_1820 ;调复位子程序
MOV A,#0CCH ;跳过ROM匹配
ACALL WRITE_1820 ;写入子程序
MOV A,#0BEH ;发出读温度命令
ACALL WRITE_1820 ;写入子程序
ACALL READ_1820 ;调用读取子程序
RET
;----------- 按键键扫描子程序 ----------
KEYSCAN:
MOV KK,#0FH ;大致扫描按键
NOP
NOP
MOV A,KK
ANL A,#07H
CJNE A,#07H,KEYSCAN1 ;如有按键按下则作精确扫描跑到 KEYSCAN1
RET
AJMP KEYSCAN
KEYSCAN1:
MOV B,#00H
SETB C
MOV R3,#0EFH
KEYSCAN2:
MOV A,R3
JNB ACC.0, KEYSCAN8 ;一次循环结束
MOV KK,A
RL A
MOV R3,A
NOP
MOV A,KK
ANL A,#07H
CJNE A,#07H,KEYSCAN4 ;检测到按键按下则转KEYSCAN4
INC B
INC B
INC B
AJMP KEYSCAN2
KEYSCAN4:
MOV R4,#03H ;移位超过3次就出错返回
KEYSCAN5:
RRC A
JNC KEYSCAN6
INC B
DJNZ R4,KEYSCAN5 ;计数达到4次则出错返回
AJMP KEYSCAN8
KEYSCAN6:
INC B
ACALL C_BUF
ACALL SHOW_DATA ;显示按键的数值
KEYSCAN8:
ACALL SPK_BZ ;K1键按下,一声鸣响
KEYSCAN9:
MOV KK,#07H ;判断按键是否释放
NOP
NOP
MOV A,KK
ANL A,#07H
CJNE A,#07H,KEYSCAN9
RET
;-------------更新显示存储单元
;-------------设定报警值 TH、TL子程序
C_BUF:
MOV A,B
CJNE A,#0AH,C_BUF1 ;判断是否是 '*'
CLR BUFFLAG
CLR KEYFULL
MOV B,#00H
INC KEYMODE ;状态加1
MOV A,KEYMODE
CJNE A,#03H,C_BUF8
MOV KEYMODE,#00H
RET
C_BUF1:
CJNE A,#0BH,C_BUF2 ;判断是否是 '0'
MOV B,#00H
AJMP C_BUF3
C_BUF2: CJNE A,#0CH,C_BUF3 ;判断是否是 '#'
MOV A,KEYMODE
CJNE A,#02H,C_BUF4 ;'#'号(确定键)按下
MOV A,KEYBUF
MOV TEMP_TL,A ;将设定的温值设置为最低温值
AJMP C_BUF5 ;
C_BUF4: MOV A,KEYMODE
CJNE A,#01H,C_BUF8
MOV A,KEYBUF ;将设定的温值设置为最高温值
MOV TEMP_TH,A
C_BUF5: CLR BUFFLAG
CLR KEYFULL
RET
C_BUF3: MOV A,KEYMODE
CJNE A,#00H,C_BUF6 ;处理按键值
RET
C_BUF6: JB KEYFULL,C_BUF8 ;超过两位数不做处理
JB BUFFLAG,C_BUF7
MOV KEYBUF,#00H
MOV KEYBUF,B
SETB BUFFLAG
RET
C_BUF7: MOV A,KEYBUF
ANL A,#0FH
PUSH B ;将上一个数值*10加上这个数值
MOV B,#0AH
MUL AB
POP B
ADD A,B
MOV KEYBUF,A
CLR BUFFLAG
SETB KEYFULL
C_BUF8:
RET
;-------- 温度数据处理显示子程序----------
SET_DATA:
ACALL CONV_TEMP ;处理温度 BCD 码子程序
ACALL DISP_BCD ;显示区 BCD 码温度值刷新子程序
ACALL CONV ;LCD显示子程序
RET
;------------------------------------------------------------
SHOW_DATA:
MOV R5,KEYMODE
CJNE R5,#00H,SHOW_DATA1
ACALL MEU_OK ;显示"OK"信息子程序
ACALL TEMP_BJ ;显示温度标记子程序
RET
SHOW_DATA1:
CJNE R5,#01H,SHOW_DATA2
MOV DPTR,#M_ALAXTH ;存M_ALAX1表
MOV A,#1
ACALL LCD_PRINT ;显示字符
MOV DPTR,#SET_TH
MOV A,#2
ACALL LCD_PRINT
MOV X,#3 ;设置位置
MOV A,TEMP_TH ;加载TH数据
ACALL SHOW_LINE2H ;显示数据
ACALL TEMP_BJ1 ;调用显示温度标记子程序
AJMP SHOW_DATA3
SHOW_DATA2:
MOV DPTR,#M_ALAXTL ;存M_ALAX1表
MOV A,#1
ACALL LCD_PRINT ;显示字符
MOV DPTR,#SET_TL
MOV A,#2
ACALL LCD_PRINT
MOV X,#3
MOV A,TEMP_TL
ACALL SHOW_LINE2H
ACALL TEMP_BJ1 ;调用显示温度标记子程序
SHOW_DATA3:
ACALL WR_THL ;将设定的TH,TL值写入DS18B20内
ACALL WRITE_E2 ;调用报警值拷贝EEROM子程序
RET
M_ALAXTH:
DB " RESET ALARM TH",0
M_ALAXTL:
DB " RESET ALARM TL",0
SET_TH:
DB " TH: ",0
SET_TL:
DB " TL: ",0
;---------- 显示信息区子程序 -----------
;――――――显示温度标记子程序――――――
TEMP_BJ1:
MOV A,#0C7H
ACALL WR_COMM ;调用写指令子程序
MOV DPTR,#BJ2 ;存代码表
MOV R1,#0 ;使指针指到表中第一个码
MOV R0,#2 ;取码次数
B0: MOV A,R1 ;A为0
MOVC A,@A+DPTR ;读取码
ACALL WR_DATA ;调用写数据子程序
INC R1 ;R1值加1
DJNZ R0,B0 ;判断是否将代码读取完?
RET
;―――――――――――――
BJ2: ;代码表
DB 00H,"C"
;―――――――――――――
;―――――在 LCD 的第二行显示高温数字――――
SHOW_LINE2H:
MOV B,#0AH ;A赋值10
DIV AB ;除法运算,结果A存商数,B存余数
ADD A,#30H ;转换为字符
INC X ;LCD显示位位置加1
PUSH B ;B放入堆栈暂存起来
MOV B,X ;设置LCD显示的位置
ACALL LCDP2 ;由LCD显示出来
;―――――――――――――
POP B ;B由堆栈取出来
INC X ;LCD显示位位置加1
MOV A,B ;B为个位数
MOV B,X ;设置LCD显示的位置
ADD A,#30H ;转换为字符
ACALL LCDP2 ;由LCD显示出来
RET
;―――――在 LCD 的第二行显示低温数字―――――
SHOW_LINE2L:
MOV B,#100 ;设置被除数
DIV AB ;除法运算,结果A存商数,B存余数
MOV A,#0AH ;A赋值10
XCH A,B ;A、B数据互换,B为十位数
DIV AB ;除法运算,结果A存商数,B存余数
ADD A,#30H ;转换为字符
PUSH B ;B放入堆栈暂存起来
MOV B,X ;设置LCD显示的位置
CALL LCDP2 ;由LCD显示出来
;――――――――――――――
POP B ;B由堆栈取出来
INC X ;LCD显示位位置加1
MOV A,B ;B为个位数
MOV B,X ;设置LCD显示的位置
ADD A,#30H ;转换为字符
ACALL LCDP2 ;由LCD显示出来
RET
;----------- 温度值比较子程序------------
;实际温度值与标记温度值比较
TEMP_COMP:
MOV A,TEMP_TH ;高温报警值送入A
SUBB A,TEMP_ZH ;减数>被减数,则
JC TCL1 ;借位标志位C=1,转TCL1
MOV A,TEMP_ZH ;实时温度送入A
SUBB A,TEMP_TL ;减数>被减数,则
JC TCL2 ;借位标志位C=1,转TCL2
MOV DPTR,#BJ5 ;存表BJ5
ACALL TEMP_BJ3 ;调用显示高、低温度及加热标记子程序
CLR RELAY ;继电器吸合
RET
;―――――――――――――
TCL1: ;实时温度>高温报警值的处理程序
MOV DPTR,#BJ3 ;存入#BJ3表
ACALL TEMP_BJ3 ;调用显示高、低温度及加热标记子程序
SETB RELAY ;继电器关闭
ACALL SPK_BZ ;调用鸣响子程序
RET
;―――――――――――――-
TCL2: ;实时温度<低温报警值的处理程序
MOV DPTR,#BJ4 ;存入#BJ4表
ACALL TEMP_BJ3 ;调用显示高、低温度及加标记子程序
ACALL SPK_BZ ;调用鸣响子程序
RET
;--- 显示高、低温度及加热标记程序----
TEMP_BJ3:
MOV A,#0CEH ;设定显示位置
ACALL WR_COMM ;调用写指令子程序
MOV R1,#0 ;使指针指到表中第一个码
MOV R0,#2 ;取码次数
BJJ: MOV A,R1 ;A为0
MOVC A,@A+DPTR ;读取码
ACALL WR_DATA ;调用写数据子程序
INC R1 ;R1值加1
DJNZ R0,BJJ ;判断是否将代码读取完?
RET
;―――――――――――――
BJ3:
DB ">H"
BJ4:
DB "<L"
BJ5:
DB " !"
;―――――――――――――
;--------- 报警上下线写入暂存器子程序 --------
WR_THL:
JB FLAG,WR_T ;FLAG=1,表示DS18B20存在,转WR_T 处
RET
;―――――――――――――
WR_T:
ACALL RESET_1820 ;调用18B20复位子程序
MOV A,#0CCH ;跳过ROM匹配
LCALL WRITE_1820 ;调用写入子程序
MOV A,#4EH ;写暂存寄存器
LCALL WRITE_1820 ;调用写入子程序
MOV A,TEMP_TH ;TH(报警上限)
LCALL WRITE_1820 ;调用写入子程序
MOV A,TEMP_TL ;TL(报警下限)
LCALL WRITE_1820 ;调用写入子程序
MOV A,#7FH ;12位精确度
LCALL WRITE_1820 ;调用写入子程序
RET
;--------- 报警值拷贝到EEROM子程序 -----------
WRITE_E2:
ACALL RESET_1820 ;调用18B20复位子程序
MOV A,#0CCH ;跳过ROM匹配
LCALL WRITE_1820 ;调用写入子程序
MOV A,#48H ;[48H]为拷贝到EEROM的指令代码
LCALL WRITE_1820 ;调用写入子程序
RET
;---------- 报警值拷贝回暂存器子程序 ----------
RE_THL:
ACALL RESET_1820 ;调用18B20复位子程序
MOV A,#0CCH ;跳过ROM匹配
LCALL WRITE_1820 ;调用写入子程序
MOV A,#0B8H ;把EEROM里的温度报警值拷贝回暂存器
ACALL WRITE_1820 ;调用写入子程序
RET
;---------- 处理温度 BCD 码子程序 ----------
CONV_TEMP:
MOV A,TEMPH ;判温度是否零下
ANL A,#80H
JZ TC1 ;温度零转TC1处
CLR C ;C=0
MOV A,TEMPL ;二进制数求补(双字节)
CPL A ;取反加1
ADD A,#01H
MOV TEMPL,A
MOV A,TEMPH
CPL A
ADDC A,#00H
MOV TEMPH,A
JMP TC2
;―――――――――――――
TC1: MOV TEMPHC,#0AH
TC2: MOV A,TEMPHC
SWAP A ;高、低位交换
MOV TEMPHC,A
MOV A,TEMPL
ANL A,#0FH ;乘0.0625
MOV DPTR,#DOTTAB
MOVC A,@A+DPTR
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -