📄 单片机温度控制.txt
字号:
;本程序通过P1.3口控制继电器
;通断时间的长短来控制温度
;数码管采用动态显示
;P3.0口接DS18B20数据通讯口
;P3.2,P3.3接按键,来调整设定温度值
KEYOK BIT 08H ;按键标志位
GF BIT 0AH
DAT BIT P3.0 ;数据通信口
SIGN1 BIT 0CH
SIGN2 BIT 0DH
SETVAL EQU 22H ;设置值
KEYVAL EQU 25H
WDLSB EQU 27H ;读出的温度低字节
WDMSB EQU 26H ;读出的温度高字节
COUNTER EQU 57H ;计数器,显示程序通过它得知现正显示哪个数码管
FIRST EQU P2.2
SECOND EQU P2.3
THIRD EQU P2.4
FOUR EQU P2.5
FIVE EQU P2.6
SIX EQU P2.7
DISPBUF EQU 50H
;***************************************************************
ORG 0000H
LJMP MAIN
ORG 000BH
SJMP DISP ;定时显示
ORG 001BH
LJMP INT
;****************************************************************
;定时显示子程序,采用循环扫描方式
ORG 0030H
DISP: ;定时器T0的中断响应程序
PUSH ACC ;ACC入栈
PUSH PSW ;PSW入栈
MOV TH0,#HIGH(65536-500)
MOV TL0,#LOW(65536-500)
MOV P2,#0FFH
MOV A,#DISPBUF ;显示缓冲区首地址
ADD A,Counter
MOV R0,A
MOV A,@R0 ;根据计数器的值取相应的显示缓冲区的值
MOV DPTR,#DISPTAB ;字形表首地址
MOVC A,@A+DPTR ;取字形码
MOV P0,A ;将字形码送P0位(段口)
MOV A,Counter ;取计数器的值
JZ DISPFIRST ;如果是0则显示第一位
AJMP DISPSECOND
DISPFIRST:
CLR P2.2 ;显示第一位
INC COUNTER
JMP DISPEXIT
DISPSECOND:
CJNE A,#1,DISPTHIRD
CLR P2.3
INC COUNTER
JMP DISPEXIT
DISPTHIRD:
CJNE A,#2,DISPFOUR
CLR P2.4
INC COUNTER
JMP DISPEXIT
DISPFOUR:
CJNE A,#3,DISPFIVE
CLR P2.5
INC COUNTER
JMP DISPEXIT
DISPFIVE:
CJNE A,#4,DISPSIX
CLR P2.6
INC COUNTER
JMP DISPEXIT
DISPSIX:
CLR P2.7
MOV COUNTER,#0
AJMP DISPEXIT
DISPEXIT:
POP PSW
POP ACC
RETI
DISPTAB:DB 28H,7EH,0A2H,62H,74H,61H,21H,7AH,20H,60H
DB 08H,5EH,82H,42H,54H,41H,01H,5AH,00H,40H
;T1中断服务程序
INT:
PUSH ACC
PUSH PSW
MOV A,45H
JZ LOOPB1
DEC A
MOV 45H,A
CLR P1.3 ;开继电器
SJMP LOOPB2
LOOPB1:
SETB P1.3 ;关短继电器
LOOPB2:
INC 20H
MOV A,20H
CJNE A,#150,LOOPB3
MOV 20H,#00H ;3秒计数时间到,清零计时单元
CLR TR1
SETB GF ;置3秒计时标志
LOOPB3:
MOV TH1,#0B8H
MOV TL1,#00H
POP PSW
POP ACC
RETI
;*********************************************************
;主程序:
MAIN:
MOV SP,#5FH ;设置堆栈
MOV P0,#0FFH
MOV P2,#0FFH ;初始化,所显示器,LED灭
MOV SETVAL,#45
CLR GF
CLR A
MOV 20H,A ;3
MOV 2FH,A ;Un
MOV 30H,A ;
MOV 3BH,A ;En-1
MOV 3CH,A ;
MOV 3DH,A ;En-2
MOV 3EH,A ;
MOV 45H,A ;控制值存储单元
MOV 33H,#100 ; KP
MOV 34H,#00
MOV 35H,#20 ; KI
MOV 36H,#00
MOV 37H,#125 ; KD
MOV 38H,#00
MOV TMOD,#00010001B ;定时器T0、T1工作于模式1(16位定时/计数模式)
MOV TH0,#HIGH(65536-500)
MOV TL0,#LOW(65536-500)
MOV TH1,#0B8H ;T1定时周期为20ms
MOV TL1,#00H
SETB EA
SETB ET0
SETB TR0
SETB ET1
SETB TR1
CLR KEYOK
MOV COUNTER,#0
LOOP:
LCALL DSWD ;调用温度采集程序
MOV A,SETVAL ;获得设定值,并送显示缓冲区
MOV B,#10
DIV AB ;十位送显示缓冲区
MOV DISPBUF,A
MOV DISPBUF+1,B ;个位送显示缓冲区
LCALL KEY ;调用键盘处理程序
JB KEYOK,KEYPROC
LOOPA:
JB GF,NEXT ;GF值位,则执行NEXT
LJMP LOOP
NEXT:
MOV A,SETVAL
ADD A,#2
MOV 40H,A
MOV A,SETVAL
CLR C
SUBB A,#2
MOV 41H,A ;计算上限值
LCALL TRAN ;调用温度采集二进制值
MOV A,2AH
CJNE A,40H,TPL
WL:
MOV C,0EH ;集温度值等于上限值的处理,置位越限标志
MOV 0FH,C
CLR 0EH
MOV 45H,#00H ;设定加热时间为0
AJMP OUT
TPL:
JNC TPL1
CLR 0FH
CJNE A ,41H,MTPL
HAT: ;采集值等于下限值,开始PID处理
LCALL DSWD
LCALL PID
AJMP OUT
MTPL: ;采集值小于下限值,全速加热
JNC HAT
MOV 45H,#150
JMP OUT
TPL1: ;温度越限处理
SETB 0EH
JNB 5FH,WL
SETB P1.3
CLR P1.2 ;开报警灯
CLR 0EH
CLR 0FH
OUT:
CLR GF
SETB TR1
LJMP LOOP
;键值处理程序
KEYPROC:
MOV A,KEYVAL ;取得键值
JZ KEYUP ;如果键值是2
JMP KEYDOWN ;键值是3,转
KEYUP:
INC DISPBUF+1
MOV A,DISPBUF
MOV B,#10
MUL AB
ADDC A,DISPBUF+1
CJNE A,#100,KEYGOON
MOV A,#40
KEYGOON:
MOV SETVAL,A
JMP LOOP
KEYDOWN:
MOV A,DISPBUF
MOV B,#10
MUL AB
ADD A,DISPBUF+1
DEC A
CJNE A,#00,KEYGOON1
MOV A,#40
KEYGOON1:
MOV SETVAL,A
MOV A,#00
JMP LOOP
;键盘程序
KEY:
MOV P3,#0FFH
CLR KEYOK
MOV A,P3
ORL A,#11110011B
CPL A
JZ KEY_RET
CALL DELAY
MOV A,P3
ORL A,#11110011B
CPL A
JZ KEY_RET
SETB KEYOK
JNB ACC.2,KEY_1 ;S1没有按下,转
MOV KEYVAL,#0
JMP KEY_RET
KEY_1:
MOV KEYVAL,#1
KEY_RET:
MOV A,P3
ORL A,#11110011B
CPL A
JNZ KEY_RET
RET
DELAY:
PUSH PSW
SETB RS0
MOV R7,#50
D1: MOV R6,#50
D2: DJNZ R6,D2
DJNZ R7,D1
POP PSW
RET
;读出DS18B20温度程序
DSWD:
CLR EA
LCALL RST
JNB F0,KEND ;如果没有应答,返回主程序
MOV R0,#0CCH
LCALL SEND_BYTE ;跳过ROM匹配
MOV R0,#44H ;发出温度转换命令
LCALL SEND_BYTE
SETB EA
MOV 58H,#1 ;廷时75ms以上准备读
SS2: MOV 59H,#255
SS1: MOV 5AH,#255
SS0: DJNZ 5AH,SS0
DJNZ 59H,SS1
DJNZ 58H,SS2
CLR EA
LCALL RST
JNB F0,KEND
MOV R0,#0CCH ;跳过ROM匹配
LCALL SEND_BYTE
MOV R0,#0BEH ;发出读温度命令
LCALL SEND_BYTE
LCALL READ_BYTE
MOV WDLSB,A
LCALL READ_BYTE
MOV WDMSB,A
LCALL TRANS12
KEND:
SETB EA
RET
;**********************************************************
;温度转换程序:精确到:0.06 ;
TRANS12:
MOV A,27H
ANL A,#0F0H
MOV 28H,A
MOV A,26H
ANL A,#0FH
ORL A,28H
SWAP A
MOV B,#10
DIV AB
MOV 52H,A
MOV A,B
ADD A,#10
MOV 53H,A ;
MOV DPTR,#TABB
MOV A,27H
ANL A,#0FH
MOV B,#2
MUL AB
MOVC A,@A+DPTR
MOV 54H,A
MOV A,27H
ANL A,#0FH
MOV B,#2
MUL AB
INC A
MOVC A,@A+DPTR
MOV 55H,A
RET
TABB: DB 0,0,0,6,1,2,1,8,2,5,3,1,3,7,4,3,5,0
DB 5,6,6,2,6,8,7,5,8,1,8,7,9,3
;*************************************************
SEND_BYTE: ;发送一个字节程序
MOV A,R0
MOV R5,#8
SEN3: CLR C
RRC A
JC SEN1
LCALL WRITE_0
SJMP SEN2
SEN1: LCALL WRITE_1
SEN2: DJNZ R5,SEN3 ; 循环8次,写一个字节
RET
READ_BYTE: ;读一个字节程序
MOV R5,#8
READ1: LCALL READ
RRC A
DJNZ R5,READ1 ; 循环8次,读一个字节
MOV R0,A
RET
;复位程序,如果复位置位F0,没有就复位F0
RST: SETB DAT
NOP
NOP
CLR DAT
MOV R6,#250 ;主机发复位脉冲持续3μs×200=600μs
DJNZ R6,$
MOV R6,#50
DJNZ R6,$
SETB DAT ;主机释放总线,口线改为输入
MOV R6,#15
DJNZ R6,$
CALL CHCK ;调用应答检查程序
MOV R6,#60
DJNZ R6,$
SETB DAT
RET
CHCK: MOV C,DAT
JC RST0
SETB F0 ;检测到信号,置位F0
SJMP CHCK0
RST0: CLR F0 ;未准备好F0复位
CHCK0: RET
WRITE_0: ;写0
CLR DAT
MOV R6,#30
DJNZ R6,$
SETB DAT
RET
WRITE_1:CLR DAT ;写1
NOP
NOP
NOP
NOP
NOP
SETB DAT
MOV R6,#30
DJNZ R6,$
RET
;读一位数据程序
READ: SETB DAT ;先复位至少1US产生读起始信号
NOP
NOP
CLR DAT
NOP
NOP
SETB DAT ;置位DAT准备接收数据
NOP
NOP
NOP
NOP
NOP
NOP
NOP
MOV C,DAT
MOV R6,#23
DJNZ R6,$
RET
TRAN: ;采集温度值调整,供PID调用
MOV A,27H
ANL A,#0F0H
MOV 23H,A
MOV A,26H
ANL A,#0FH
ORL A,23H
SWAP A
MOV 2AH,A
MOV A,27H
ANL A,#0FH
SWAP A
MOV 2BH,A
RET
;PID计算程序
PID:
MOV 31H,SETVAL ; 取给定值Rn
MOV 32H,#00
LCALL TRAN
MOV R5,31H ;采样值Cn
MOV R4,32H
MOV R3,2AH
MOV R2,2BH
LCALL CPL1 ;取采样值-Cn的补码
LCALL DSUM ;计算En=Rn-Cn
MOV 39H,R7 ;存En
MOV 3AH,R6
MOV R5,35H ;取KI
MOV R4,36H
MOV R0,#4AH
LCALL MULT1 ;计算Pi=KI*En并存于4AH-4DH单元
MOV R5,39H ;取En
MOV R4,3AH
MOV R3,3BH ;取En-1
MOV R2,3CH
LCALL CPL1 ;求En-1的补码
LCALL DSUM ;求En-En-1
MOV R5,33H ;取KP
MOV R4,34H
MOV R0,#46H
LCALL MULT1 ;求Pp=KP(En-En-1),并存于46H-49H单元
MOV R5,49H ;取Pp
MOV R4,48H
MOV R3,4DH ;取Pi
MOV R2,4CH
LCALL DSUM ;求Pp+ Pi
MOV 4AH,R7 ;保存和Pp+Pi到4AH,4BH中
MOV 4BH,R6
MOV R5,39H ;取Ev
MOV R4,3AH
MOV R3,3DH ;取En-2
MOV R2,3EH
LCALL DSUM ;计算En+En-2
MOV A,R7
MOV R5,A
MOV A,R6
MOV R4,A
MOV R3,3BH ;取En-1
MOV R2,3CH
LCALL CPL1 ;计算En-1的补码
LCALL DSUM ;计算En+En-2-En-1
MOV A,R7
MOV R5,A
MOV A,R6
MOV R4,A
MOV R3,3BH ;取En-1
MOV R2,3CH
LCALL CPL1
LCALL DSUM
MOV R5,37H ;计算En+En-2-2*En-1
MOV R4,38H
MOV R0,#46H
LCALL MULT1 ;计算Pd=KD*(En+En-2-En-1)
MOV R5,49H ;取Pd
MOV R4,48H
MOV R3,4AH ;取Pp+Pi
MOV R2,4BH
LCALL DSUM ;计算Pp+Pi+Pd
MOV A,R7
MOV R3,A
MOV A,R6
MOV R2,A
MOV R5,2FH ;取Un-1
MOV R4,30H
LCALL DSUM ;计算Un-1+Pp+Pi+Pd
MOV 2FH,R7 ;用Un取代Un-1
MOV 30H,R6
MOV 3DH,3BH ;用En-1取代En-2
MOV 3EH,3CH
MOV 3BH,39H ;用En取代En-1
MOV 3CH,3AH
MOV A,2FH ;Un限幅处理
JNB ACC.7,CONT1
MOV 45H,#00H ;Un为负值,则取为0
RET
CONT1:
MOV A,30H
RLC A
MOV A,2FH
RLC A
MOV R2,A ;继电器控制取高8位
SUBB A,#150
JNC CONT2
MOV 45H,R2
RET
CONT2:
MOV 45H,#150
RET
;负数双字节-(R3R2)求补,结果仍存放R3R2中
CPL1:
MOV A,R2
CPL A
ADD A,#01H
MOV R2,A
MOV A,R3
CPL A
ADDC A,#00H
MOV R3,A
RET
;双字节加法(R5R4)+(R3R2)存放于(R6R7)中
DSUM:
MOV A,R4
ADD A,R2
MOV R6,A
MOV A,R5
ADDC A,R3
MOV R7,A
RET
;双字节乘法子程序
;入口:(R7R6)=被乘数
; (R5R4)=乘数
;出口(R0)=乘积的4字节地址指针
MULT:
MOV A,R6
MOV B,R4
MUL AB
MOV @R0,A
MOV R3,B
MOV A,R4
MOV B,R7
MUL AB
ADD A,R3
MOV R3,A
MOV A,B
ADDC A,#00H
MOV R2,A
MOV A,R6
MOV B,R5
MUL AB
ADD A,R3
INC R0
MOV @R0,A
CLR F0
MOV A,R2
ADDC A,B
MOV R2,A
JNC LAST
SETB F0
LAST:
MOV A,R7
MOV B,R5
MUL AB
ADD A,R2
INC R0
MOV @R0,A
MOV A,B
ADDC A,#00H
MOV C,F0
ADDC A,#00H
INC R0
MOV @R0,A
RET
;双字节带符号数乘法子程序
;双字节乘法子程序
;入口:(R7R6)=被乘数
; (R5R4)=乘数
;SIGN1标号地址为0CH
;SIGN2标号地址为0DH
;出口(R0)=乘积的4字节地址指针
MULT1:
MOV A,R7
RLC A
MOV SIGN1,C
JNC POS1
MOV A,R6
CPL A
ADD A,#01H
MOV R6,A
MOV A,R7
CPL A
ADDC A,#00H
MOV R7,A
POS1:
MOV A,R5
RLC A
MOV SIGN2,C
JNC POS2
MOV A,R4
CPL A
ADD A,#01H
MOV R4,A
MOV A,R5
CPL A
ADDC A,#00H
MOV R5,A
POS2:
MOV 29H,R0
LCALL MULT
MOV C,SIGN1
ANL C,SIGN2
JC TP
MOV C,SIGN1
ORL C,SIGN2
JNC TP
MOV R0,29H
MOV A,@R0
CPL A
ADD A,#01H
MOV @R0,A
INC R0
MOV A,@R0
CPL A
ADDC A,#00H
MOV @R0,A
INC R0
MOV A,@R0
CPL A
ADDC A,#00H
MOV @R0,A
INC R0
MOV A,@R0
CPL A
ADDC A,#00H
MOV @R0,A
TP:
RET
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -