⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 单片机温度控制.txt

📁 PID 的温度控制。。。。。。。。。。。。。。。。。。。。
💻 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 + -