📄 all.asm
字号:
TEMPDIN EQU P1.4
;****************
;时间常数定义
;****************
TIMEL EQU 0E0H
TIMEH EQU 0B1H
BITST EQU 20H
TIME1SOK BIT BITST.1
TEMPH EQU 21H ;从温度传感器得到的数据暂存
TEMPL EQU 22H
TEMPL_ZAN EQU 57H ;上一次测得数据暂存
TEMPH_ZAN EQU 56H
TEMPL1 EQU 50H ;供存储三次测得的数据的差值
TEMPH1 EQU 51H
TEMPL2 EQU 52H
TEMPH2 EQU 53H
TEMPL3 EQU 54H
TEMPH3 EQU 55H
TEMP_HH EQU 23H ;BCD转换后的温度数据,百位+十位压缩,当百位为零时,存的是符号位正:A 负:B
TEMP_HL EQU 24H ;高位为个位,低位为无用数据
TEMP_LH EQU 25H ;小数压缩
TEMP_LL EQU 26H
TSET EQU 37H
COM EQU 3DH ;指令寄存器
DAT EQU 3EH ;数据寄存器
TGETD EQU 3FH
BUFFER EQU 40H
CW_ADD EQU 0000H ;指令口写地址
DW_ADD EQU 0001H ;数据口写地址
CR_ADD EQU 0002H ;指令口读地址
KEY_ADD EQU P1
COL EQU 28H
KEYCODE EQU 29H
TEMP_RD_H EQU 41H
TEMP_RD_L EQU 42H
TEMP_RD_H1 EQU 43H ;键盘值暂存
TEMP_RD_L1 EQU 44H
PMWCON EQU 5FH ;脉宽调制控制寄存器
pid equ 5eh
ORG 0000H
LJMP STARTMEASURE
ORG 0003H
LJMP PRG_INT0 ;键盘中断服务程序
ORG 000BH
LJMP TOIT
ORG 0100H
STARTMEASURE:
MOV SP,#61H
mov pid,#02h ;kip预置为2
MOV TEMP_RD_H #02H
MOV TEMP_RD_H #80H
CLSMEM: MOV R0,#30H
MOV R1,#60H
CLSMEM1:MOV @R0,#00H
INC R0
DJNZ R1,CLSMEM1
MOV TMOD,#01H
MOV TH0,#TIMEL
MOV TL0,#TIMEH
LCALL KEYINI ;准备键盘中断
MOV IP,#01H ;INT0优先级最高
MOV IE,#00000001B ;设定INT0
SJMP INIT
ERROR: NOP
LJMP STARTMEASURE
NOP
INIT: NOP
SETB ET0
SETB TR0
SETB EA
MOV PSW,#00H
JMP START
;****************
;准备键盘中断
;****************
KEYINI: MOV A,#0FH ;准备键盘中断
MOVX KEY_ADD,A
RET
;****************
;键盘中断服务程序
;****************
PRG_INT0:LCALL KEYSCAN ;键盘中断服务程序
JNC NEXT
AJMP SKIP4
NEXT: MOV A,KEYCODE ;温度增10度
CJNE A,#0EEH,NEXT1
MOV A,TEMP_RD_L1
CLR C
ADD A,#0A0H
MOV TEMP_RD_L1,A
MOV A,TEMP_RD_H1
ADDC A,00H
MOV TEMP_RD_H1,A
JMP SKIP4
NEXT1: CJNE A,#0EDH,NEXT2 ;温度减10度
MOV A,TEMP_RD_L1
CLR C
SUBB A,#0A0H
MOV TEMP_RD_L,A
MOV A,TEMP_RD_H1
SUBB A,00H
MOV TEMP_RD_H1,A
JMP SKIP4
NEXT2: CJNE A,#0EBH,NEXT3 ;确认键
mov TEMP_RD_H,TEMP_RD_H1
mov TEMP_RD_L,TEMP_RD_L1
JMP SKIP4
NEXT3: CJNE A,#0BEH,SKIP4 ;200HZ
;MOV FREQ,#02H
; LCALL DIS2
SKIP4: MOV A,#0FH
MOV A,#KEY_ADD
RETI
;*****************************************************
;键盘扫描程序
;R1 列值暂存,R2 循环次数计数,R3 行扫描码,A 返回键值
;键扫描程序
;*****************************************************
KEYSCAN:
MOV A,KEY_ADD ;读入列值
ANL A,#0FH ;清高四位
MOV COL,A ;列信息保存在COL
LCALL DELAY20MS ;延时20ms
MOV R2,#04H
MOV R3,#0EFH ;使第0行输出低电平
MOV A,R3 ;行扫描
AGAIN: MOV A,KEY_ADD ;读入列值
anl a,#0fh
MOV R1,A ;列值暂存R1
XRL A,#0FH ;异或,有键按下输出Z=0,无键按下Z=1
JNZ KEYIN ;A!=0F,表示找到键
MOV A,R3 ;否则扫描下一行
SETB C
RLC A
MOV R3,A ;扫描下一行
DJNZ R2,AGAIN
JMP NOKEY ;四行扫描完,未找到对应行置A=00H
KEYIN: mov a,r1
cjne a,COL,NOKEY1 ;延迟20ms后看是否和之前一样,如不是,则判无键输入
LCALL DELAY20MS ;消除键抖动
LOOP :MOV A,KEY_ADD
ANL A,#0FH
XRL A,#0FH
JNZ LOOP ;等待键放开z=0继续循环,不全零说明键还没放开
MOV A,R3
ANL A,#0F0H
ORL A,R1 ;得到行列码
MOV KEYCODE,A
CLR C
JMP RETURN
nokey1:MOV A,KEY_ADD
ANL A,#0FH
XRL A,#0FH
JNZ nokey1
NOKEY:SETB C
RETURN: RET
DELAY20MS: MOV R7,#20 ;延时10ms
D2 : MOV R6,#00
DJNZ R6,$
DJNZ R7,D2
RET
START: LCALL LCD_INIT
LCALL DISPLAY1
AGAIN: JNB TIME1SOK,$
CLR TIME1SOK
LCALL JUDGE
LCALL RDTEMP
LCALL CONVTEMP
LCALL DISPLAY2
LJMP AGAIN
JUDGE: PUSH PSW
PUSH ACC
MOV R1,TEMP_RD_H
MOV R2,TEMP_RD_L
MOV R3,TEMPH ;判断温差>5度,采用模糊控制
MOV R4,TEMPL
MOV A,R2
CLR C
SUBB A,R4
MOV R5,A ;低位之差暂存
MOV A,R1
SUBB A,R3
JNC PLUS
CPL A
MOV R6,A
CLR C
MOV A,R5
CPL A
ADD A,#01H
MOV R5,A
PLUS: MOV A,R6
JNZ MOHU
CLR C
MOV A,R5
SUBB A,50H
JC MOHU
SJMP PIDCON
POP ACC
POP PSW
RET
;*****************
;采用模糊控制
;******************
MONU: MOV 58H,53H
MOV 57H,52H
MOV 5AH,51H
MOV 59H,50H
LACALL QUCHA
MOV A,51H
CLR C
SUBB A,#0A0H
JNC MINUS1
MOV A,5CH
CLR C
SUBB A,#0A0H
JNC M_P
MOV PMWCON,32H ;大火加热
JMP MOHURET
MINUS1: MOV A,5CH
CLR C
SUBB A,#0A0H
JC M_P
MOV PMWCON,#0DH ;小火加热
JMP MOHURET
M_P: MOV PMWCON,#19H ;中火加热
MOHURET: RET
;*****************
;采用PID控制
;******************
PIDCON: PUSH PSW
PUSH ACC
MOV A,50H
mov b,#02h
div ab
mov b,#05h
mul ab
mov R1,a ;将En乘以2.5
MOV A,52H
mov b,#02h
div ab
mov b,#07h
mul ab
mov R2,a ;将En-1乘以3.5
mov a,r1
add a,54h ;2.5En+En-2
clr c
subb a,r2 ;2.5En+(En-2)-3.5(En-1)
mov b,pid
mul ab
mov pmwcon,a
ret
;*****************
;定时器0中断服务程序
;******************
TOIT: PUSH PSW
MOV PSW,#10H
MOV TH0,#TIMEH
MOV TL0,#TIMEL
SETB P1.0
CONT1: INC 5DH
MOV A,5DH
CJNE A,PMWCON,CONT1
CLR P1.0
MOV R7,5DH
CJNE R7,#32H,TOIT1
MOV 5DH,#00H
SETB TIME1SOK
TOIT1: POP PSW
RETI
;***************
;LCD初始化
;**************
LCD_INIT: MOV A,#30H ;工作方式设置指令代码
MOV DPTR,#CW_ADD ;指令口地址设置
MOV R2,#03H ;循环量=3
MOVX @DPTR, A ;写指令代码
INIT1: LCALL DELAY
DJNZ R2,INIT1
MOV A,#38H ;设置8位总线工作方式
MOVX @DPTR, A
MOV COM,#01H ;请屏
LCALL PR1
MOV COM,#06H ;设置输入方式
LCALL PR1
MOV COM,#0CH ;设置显示方式
LCALL PR1
RET
;延迟
DELAY: MOV R6,#01H
DELAY2: MOV R5,#00H
DELAY1: NOP
DJNZ R5,DELAY1
DJNZ R6,DELAY2
RET
;写指令代码
PR1: PUSH DPH
PUSH DPL
PUSH ACC
MOV DPTR,#CR_ADD
PR11: MOVX A,@DPTR ;查询是否忙
JB ACC.7,PR11
MOV A,COM
MOV DPTR,#CW_ADD
MOVX @DPTR,A
POP ACC
POP DPL
POP DPH
RET
;写显示数据
PR2: PUSH DPH
PUSH DPL
PUSH ACC
MOV DPTR,#CR_ADD
PR21: MOVX A,@DPTR
JB ACC.7,PR21
MOV A,DAT
MOV DPTR,#DW_ADD
MOVX @DPTR,A
POP ACC
POP DPL
POP DPH
RET
;*************
;DS18B20复位
;*************
RESET1820:
LA: SETB TEMPDIN
MOV R2,#200
LB: CLR TEMPDIN
DJNZ R2,LB ;等待600us
SETB TEMPDIN
MOV R2,#30
LC: DJNZ R2,LC ;等待60us
CLR C
ORL C,TEMPDIN ;读ds18b20,存在脉冲低电平
JC LB
MOV R6,#80 ;
LD: ORL C,TEMPDIN
JC LP
DJNZ R6,LD
SJMP LA
LP: MOV R2,#250
LF: DJNZ R2,LF
RET
;*****************
;DS18B20写时序
;****************
WRITE1820:
MOV R3,#8
WR1A: SETB TEMPDIN
MOV R4,#8
RRC A
CLR TEMPDIN
WR2A: DJNZ R4,WR2A ;将总线控制拉低16us后对I/O线采样
MOV TEMPDIN,C
MOV R4,#30
WR3A: DJNZ R4,WR3A ;写时间保持60us
DJNZ R3,WR1A
SETB TEMPDIN
RET
;******************
;DS18B20读时序
;********************
READ1820:
CLR EA
MOV R6,#8
RD1A: CLR TEMPDIN ;将总线控制拉低2us后,再拉高,以读取I/O线数据
MOV R4,#6
NOP
SETB TEMPDIN
RD2A: DJNZ R4,RD2A
MOV C,TEMPDIN
RRC A
MOV R5,#30
RD3A: DJNZ R5,RD3A ;读时间保持60us
DJNZ R6,RD1A
SETB TEMPDIN ;对I/O采样的结尾,将I/O引脚上拉
SETB EA
RET
;***************
;DS18B20温度转换
;***************
RDTEMP: LCALL RESET1820
MOV A,#0CCH
LCALL WRITE1820
MOV A,#44H
LCALL WRITE1820
LCALL DDELAY
LCALL RESET1820
MOV A,#0CCH
LCALL WRITE1820
MOV A,#0BEH
LCALL WRITE1820
LCALL READ1820
MOV TEMPL,A
LCALL READ1820
MOV TEMPH,A
MOV 58H,TEMPH
MOV 57H,TEMPL
MOV 5AH,TEMPH_ZAN
MOV 59H,TEMPL_ZAN
LCALL QUCHA ;取差En
MOV 55H,53H ;差值转存
MOV 54H,52H
MOV 53H,51H
MOV 52H,50H
MOV 51H,5CH
MOV 50H,5BH
MOV TEMPL_ZAN,TEMPL
MOV TEMPH_ZAN,TEMPH
RET
;***************
;取差En
;***************
QUCHA: pUSH ACC
PUSH PSW
MOV R1,58H
MOV R2,57H
MOV R3,5AH
MOV R4,59H
MOV A,R2
CLR C
SUBB A,R4
MOV 5BH,A
MOV A,R1
SUBB A,R3
MOV 5CH,A
POP PSW
POP ACC
RET
;********************
;处理温度BCD码字程序
;********************
CONVTEMP: MOV A,TEMPH ;比较高位温度值的符号位
ANL A,#80H ;如果是正的,符号为零;负的,符号为1
JZ TEMPC1
CLR C
MOV A,TEMPL
CPL A
ADD A,#01H
MOV TEMPL,A
MOV A,TEMPH
CPL A
ADDC A,#00H
MOV TEMPH,A
MOV TEMP_HH,#0BH
SJMP TEMPC11
TEMPC1: MOV TEMP_HH,#0AH ;测的是正温
TEMPC11: MOV A,TEMP_HH
SWAP A
MOV TEMP_HH,A
MOV A,TEMPL
ANL A,#0FH
RL A
MOV R5,A
MOV DPTR,#TEMPDOTTAB
MOVC A,@A+DPTR
MOV TEMP_LH,A
MOV A,R5
INC A
MOVC A,@A+DPTR
MOV TEMP_LL,A
MOV A,TEMPL
ANL A,#0F0H
SWAP A
MOV TEMPL,A
MOV A,TEMPH
ANL A,#0FH
SWAP A
ORL A,TEMPL
LCALL HEX2BCD1
MOV TEMPL,A
ANL A,#0F0H
SWAP A
ORL A,TEMP_HH
MOV TEMP_HH,A ;A2
MOV A,TEMPL
ANL A,#0FH
SWAP A
MOV TEMP_HL,#00H
ORL A,TEMP_HL
MOV TEMP_HL,A
MOV A,R7
JZ TEMPC12
ANL A,#0FH
SWAP A
MOV R7,A
MOV A,TEMP_HH
ANL A,#0FH
ORL A,R7
MOV TEMP_HH,A
TEMPC12: RET
;*******************
;小数分码表
;********************
TEMPDOTTAB: DB 00H,00H
DB 06H,25H
DB 12H,50H
DB 18H,75H
DB 25H,00H
DB 31H,25H
DB 37H,50H
DB 43H,75H
DB 50H,00H
DB 56H,25H
DB 62H,50H
DB 68H,75H
DB 75H,00H
DB 81H,25H
DB 87H,50H
DB 93H,75H
;********************
;单字节十六进制转BCD
;*********************
HEX2BCD1: MOV B,#064H
DIV AB
MOV R7,A
MOV A,#0AH
XCH A,B
DIV AB
SWAP A
ORL A,B
RET
;***************************
;温度值解码子程序
;解码后放在数据缓冲区40H开始
;***************************
UNCODE: MOV A,TEMP_LL ;小数四位最低位
ANL A,#0FH
MOV 46H,A
MOV A,TEMP_LL ;小数四位次低位
SWAP A
ANL A,#0FH
MOV 45H,A
MOV A,TEMP_LH
ANL A,#0FH
MOV 44H,A
MOV A,TEMP_LH
SWAP A
ANL A,#0FH
MOV 43H,A
MOV A,TEMP_HL ;个位
SWAP A
ANL A,#0FH
MOV 42H,A
MOV A,TEMP_HH ;十位
ANL A,#0FH
MOV 41H,A
MOV A,TEMP_HH ;百位
SWAP A
ANL A,#0FH
MOV BUFFER,A
RET
;************************
;LCD显示子程序
;************************
DISPLAY1: MOV COM,#06H ;设置输入方式
LCALL PR1
MOV COM,#83H ;设置DDRAM地址
LCALL PR1
MOV DPTR,#TABCR ;设置字表首地址
MOV R2,#0BH ;循环量设置
MOV R3,#00H
CR_1: MOV A,R3
MOVC A,@A+DPTR
MOV DAT,A
LCALL PR2
INC R3
LCALL DELAY
LCALL DELAY
LCALL DELAY
DJNZ R2,CR_1
RET
TABCR: DB "TEMPERATURE"
DISPLAY2: MOV COM,#06H ;设置输入方式
LCALL PR1 ;设置第二行DDRAM地址
MOV COM,#0C5H
LCALL PR1
MOV R1,#BUFFER
MOV A,@R1
CJNE A,#01H,DISLOOP
ADD A,#30H
JMP DISNEXT
DISLOOP:ADD A,#20H
DISNEXT:MOV DAT,A
LCALL PR2
INC R1
MOV A,@R1
ADD A,#30H
MOV DAT,A
LCALL PR2
INC R1
MOV A,@R1
ADD A,#30H
MOV DAT,A
LCALL PR2
MOV A,#2EH
MOV DAT,A
LCALL PR2
INC R1
MOV A,@R1
ADD A,#30H
MOV DAT,A
LCALL PR2
INC R1
MOV A,@R1
ADD A,#30H
MOV DAT,A
LCALL PR2
INC R1
MOV A,@R1
ADD A,#30H
MOV DAT,A
LCALL PR2
INC R1
MOV A,@R1
ADD A,#30H
MOV DAT,A
LCALL PR2
RET
DDELAY: MOV R7,#5
DL2: MOV R6,#100
DL1: MOV R5,#250
DL0: DJNZ R5,DL0
DJNZ R6,DL1
DJNZ R7,DL2
RET
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -