📄 at89c51---temperature-control.txt
字号:
TEMPH EQU 20H ;温度的高8位
TEMPL EQU 21H ;温度的低8位
TEMP_HEX EQU 22H ;十六进制温度值
TEMP_BCD EQU 23H ;十进制温度值
TEMP_DOT EQU 24H
FLAG EQU 25H ;是否检测到DS18B20标志位
;===================================
SET_VAL EQU 26H ;设定的温度值
KP EQU 27H ;设为200/ET
KI EQU 28H
KD EQU 29H
ET EQU 2AH
ET_1 EQU 2BH
ET_2 EQU 2CH
KPPH EQU 2DH
KPPL EQU 2EH
KPIH EQU 2FH
KPIL EQU 30H
KPDH EQU 31H
KPDL EQU 32H
PDLTH EQU 33H
PDLTL EQU 34H
PNH EQU 35H
PNL EQU 36H
;==================================
DQ EQU P3.5
PWM_HEAT EQU P3.3
PWM_COLD EQU P3.4
;==================================
ORG 0030H
;==================================
MAIN:
MOV SP,#60H
CLSMEM:
MOV R0,#20H
MOV R1,#60H
CLSMEM1:
MOV @R0,#00H
INC R0
DJNZ R1,CLSMEM1
MOV KP,#10
MOV KI,#3
MOV KD,#200
MOV SET_VAL,#30
CLR EA
SJMP START
;=====================================
;*主程序*;
;=====================================
START:
; LCALL GET_VAL
LCALL CLIMBER
LCALL CONVTEMP
LCALL DISP1
LCALL PID_CONTROL
LJMP START
;=======================================
DELAY: MOV R6,#06H
D1: DJNZ R6,D1 ;延时=R7*15MS
DJNZ R7,DELAY
RET
;=======================================
;***测温显示部分***;
;======================================
;初始化子程序
;======================================
INIT:
SETB DQ
NOP
CLR DQ
MOV R7,#34 ;延时510us,(应为480--960us之间)
LCALL DELAY
SETB DQ
MOV R7,#06 ;延时60us(应大于15us--60us之后)
LCALL DELAY
CLR FLAG
JB DQ,BACK ;若数据线为高,则返回。
SETB FLAG
MOV R7,#28 ;延时420us
LCALL DELAY
SETB DQ ;然后拉高数据线
BACK:RET
;======================================
;读出转换后的温度值;
;======================================
CLIMBER:
SETB DQ
LCALL INIT ;先复位DS18B20
JB FLAG,TSS2
RET ;判断DS1820是否存在?若DS18B20不存在则返回
TSS2:
MOV A,#0CCH ;跳过ROM匹配
LCALL WRITE
MOV A,#44H ;发出温度转换命令
LCALL WRITE
MOV R7,#50 ;延时750us转换时间
LCALL DELAY
LCALL INIT ;准备读温度前先复位
MOV A,#0CCH ;跳过ROM匹配
LCALL WRITE
MOV A,#0BEH ;发出读温度命令
LCALL WRITE
LCALL READ
RET
;======================================
;写DS18B20的子程序(注意时序)
;======================================
WRITE:
CLR C
MOV R2,#8 ;一共8位数据
WR1:
CLR DQ
MOV R7,#1 ;在数据变低的15us到60us之间采样。
LCALL DELAY
RRC A
MOV DQ,C
MOV R7,#1
LCALL DELAY
SETB DQ
NOP
DJNZ R2,WR1
SETB DQ
RET
;======================================
;读DS18B20的程序;
;======================================
READ:
MOV R4,#2 ;将温度高位和低位从DS18B20中读出
MOV R1,#TEMPL ;低位存入22H(TEMPL),高位存入21H(TEMPH)
WIN00:
MOV R2,#8 ;数据一共有8位
WIN01:
CLR C
SETB DQ
NOP
NOP
CLR DQ
NOP
NOP
NOP
SETB DQ
MOV R7,#01
LCALL DELAY
MOV C,DQ
MOV R7,#03
LCALL DELAY
RRC A
DJNZ R2,WIN01
MOV @R1,A
DEC R1
DJNZ R4,WIN00
RET
;=========================
;处理温度BCD码子程序
;========================
CONVTEMP:
;取小数部分
MOV A,TEMPL
ANL A,#0FH
MOV DPTR,#TEMPDOTTAB
MOVC A,@A+DPTR
MOV TEMP_DOT,A
;取温度的个位
MOV A,TEMPL
ANL A,#0F0H
SWAP A
MOV TEMP_HEX,A
;取温度的十位
MOV A,TEMPH
ANL A,#0FH
SWAP A
CLR C
ADDC A,TEMP_HEX
MOV TEMP_HEX,A
MOV DPTR,#TEMP_TAB
MOVC A,@A+DPTR
MOV TEMP_BCD,A
RET
TEMP_TAB:
DB 00H,01H,02H,03H,04H,05H,06H,07H
DB 08H,09H,10H,11H,12H,13H,14H,15H
DB 16H,17H,18H,19H,20H,21H,22H,23H
DB 24H,25H,26H,27H,28H,29H,30H,31H
DB 32H,33H,34H,35H,36H,37H,38H,39H
DB 40H,41H,42H,43H,44H,45H,46H,47H
DB 48H,49H,50H,51H,52H,53H,54H,55H
DB 56H,57H,58H,59H,60H,61H,62H,63H
DB 64H,65H,66H,67H,68H,69H,70H,71H
DB 72H,73H,74H,75H,76H,77H,78H,79H
DB 80H,81H,82H,83H,84H,85H,86H,87H
DB 88H,89H,90H,91H,92H,93H,94H,95H
TEMPDOTTAB:
DB 00H,01H,01H,02H,03H,03H,04H,04H
DB 05H,06H,06H,07H,08H,08H,09H,09H
;===========================
;显示子程序
;===========================
KEYLED_C EQU 0A001H
KEYLED_D EQU 0A000H
DISP1:
NOP
MOV DPTR,#KEYLED_C
MOV A,#0D3H ; CLEAR DISPLAY AND BUFFER
MOVX @DPTR,A
MOV R7,#00H
ST010:
DJNZ R7,ST010
MOV A,#00H ; SET KEY/LED MODE
ST031:
MOV DPTR,#KEYLED_C
MOV A,#90H ; SET WRITE LED MODE
MOVX @DPTR,A
MOV DPTR,#KEYLED_D
MOV A,#00H
MOVX @DPTR,A
MOVX @DPTR,A
MOVX @DPTR,A
MOVX @DPTR,A
MOV A,TEMP_BCD
ANL A,#0F0H
SWAP A
MOV DPTR,#LEDTB
MOVC A,@A+DPTR
MOV DPTR,#KEYLED_D
MOVX @DPTR,A
MOV A,TEMP_BCD
ANL A,#0FH
MOV DPTR,#LEDTB
MOVC A,@A+DPTR
ADD A,#80H
MOV DPTR,#KEYLED_D
MOVX @DPTR,A
MOV A,TEMP_DOT
MOV DPTR,#LEDTB
MOVC A,@A+DPTR
MOV DPTR,#KEYLED_D
MOVX @DPTR,A
MOV A,#00
MOVX @DPTR,A
MOVX @DPTR,A
RET
LEDTB: DB 3FH, 06H, 5BH, 4FH, 66H, 6DH, 7DH, 07H
DB 7FH, 6FH, 77H, 7CH, 39H, 5EH, 79H, 71H
;===========================================================
;*PID控制部分*
;===========================================================
PID_CONTROL:
;赋初值
MOV ET,#00H
MOV ET_1,#00H
MOV ET_2,#00H
MOV PNH,#00H
MOV PNL,#00H
;第一次测温值SET_VAL-TEMP_HEX
MOV A,SET_VAL
DEC A
CLR C
SUBB A,TEMP_HEX
MOV ET,A
JNC PID_HEAT ;C=0则加热
LJMP PID_FAN ;C=1则风扇
;========================================================
PID_HEAT:
;均用补码表示(判断最高位,为1则为负数,为零则为正数)
MOV R3,ET_1
LCALL CPL8
MOV R2,ET
LCALL ADD8 ;ET-ET_1=R3
;Kp*[e(t)-e(t-1)]
MOV A,R3
MOV R5,A
MOV R4,KP
LCALL MULT1
MOV KPPH,R7
MOV KPPL,R6
;Ki*e(t)
MOV R5,KI
MOV R4,ET
LCALL MULT1
MOV KPIH,R7
MOV KPIL,R6
;Kd*[e(t)-2*e(t-1)+e(t-2)]
MOV R3,ET_1
LCALL CPL8
MOV R2,ET
LCALL ADD8 ;ET-ET_1=R3
MOV A,R3
MOV R2,A ;转存与R2
MOV R3,ET_2
LCALL CPL8
MOV R2,ET_1
LCALL ADD8 ;ET_1-ET_2=R3
LCALL CPL8
LCALL ADD8 ;[e(t)-2*e(t-1)+e(t-2)]
MOV A,R3
MOV R5,A
MOV R4,KD
LCALL MULT1
MOV KPDH,R7
MOV KPDL,R6
;加起来
MOV R3,KPPH
MOV R2,KPPL
MOV R1,KPIH
MOV R0,KPIL
LCALL ADD16
MOV R1,KPDH
MOV R0,KPDL
LCALL ADD16
MOV PDLTH,R3
MOV PDLTL,R2
;PN=PN_1+PDLT
MOV R1,PNH
MOV R0,PNL
LCALL ADD16
MOV PNH,R3
MOV PNL,R2
MOV ET_2,ET_1
MOV ET_1,ET
;*PWM控制部分*
;======================================
;PWM控制
;共2s,分200份
;ET--20°C
;目标温度40°C
;令KP=10
;令KI=3
;令KD=8
;======================================
PWMHEAT:;若>50则算50
;高电平
CLR C
MOV A,#30
MOV R6,PNL
SUBB A,PNL
JNC SKIP1
MOV R6,#30
SKIP1:
SETB PWM_HEAT
LCALL TIME_10MS
;低电平
CLR C
MOV A,#30
SUBB A,PNL
MOV R6,A
JNC SKIP2
MOV R6,#1
SKIP2:
CLR PWM_HEAT
LCALL TIME_10MS
RET
;===========================================================
PID_FAN:
CLR PWM_HEAT
SETB PWM_COLD
RET
;========================================================
;增量式PID
;Pdlt=Kp*[e(t)-e(t-1)]+Ki*e(t)+Kd*[e(t)-2*e(t-1)+e(t-2)]
;PN=PN_1+Pdlt
;=========================================================
;=======================================
;==========================
TIME_10MS:;入口R6
DL0: MOV R1,#10
DL1: MOV R0,#246
DJNZ R0,$
DJNZ R1,DL1
DJNZ R6,DL0
RET
;=========================
;*数学子程序*
;============================
;8位加法
;R3+R2->R3
;=============================
ADD8:
MOV A,R3
ADD A,R2
MOV R3,A
RET
;=============================
; 16位加法
; R3R2 + R1R0 -> R3R2
;=============================
ADD16:
MOV A,R0
ADD A,R2
MOV R2,A
MOV A,R1
ADDC A,R3
MOV R3,A
RET
;======================
; 8位求补
; -R3 -> R3
;======================
CPL8:
MOV A,R3
CPL A
ADD A,#01H
MOV R3,A
RET
;======================
; 16位求补
; -R3R2 -> R3R2
;======================
CPL16:
MOV A,R2
CPL A
ADD A,#01H
MOV R2,A
MOV A,R3
CPL A
ADDC A,#00H
MOV R3,A
RET
;======================================================
;单字节有符号数乘法:
;R5*R4-->R7,R6
;=======================================================
MULT1:
MOV A,R5
RLC A
MOV 5CH,C ;被乘数符号C1-->5CH位
JNC POS1 ;为正数则转
MOV A,R5 ;为负数则求补
CPL A
ADD A,#01H
MOV R5,A
POS1:
MOV A,R4 ;取乘数
RLC A ;乘数符号C2-->5DH位
MOV 5DH,C
JNC POS2 ;为正数则转
MOV A,R4
CPL A
ADD A,#01H
MOV R4,A
POS2:
LCALL MULT ;调双字节无符号数乘法子程序
MOV C,5CH
ANL C,5DH
JC TPL ;负负相乘则转
MOV C,5CH
ORL C,5DH
JNC TPL ;正正相乘则转
;结果为负
MOV A,R6
CPL A
ADD A,#01H
MOV R6,A
MOV A,R7
CPL A
ADDC A,#00H
MOV R7,A
TPL:
RET
;===============================================
;无符号数乘法子程序,结果存于R5*R4->R7,R6
;===============================================
MULT:
MOV A,R5
MOV B,R4 ;取低位相乘
MUL AB ;A存低位,B存高位
MOV R6,A ;低位存于R6
MOV R7,B ;高位存于R7
RET
;====================================================
;==============================================================================;
END
;==============================================================================;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -