;此控温程序是采用PD控温方式,入口在 : BLXS 最大取值 255 WFXS 最大取值 255 ; SDWDHH,SDWDHL 设定温度的16进制高低字节存储地址 ; WDZHH,WDZHL 当前温度的16进制高低字节存储地址 ; ; 出口在: ZSJCSH 加热时间 ; ZSJCSL 不加热时间 ; ; ZSJCSH+ZSJCSL=200 则一个控温周期= 200*基本定时周期 BCPCHH EQU 30H BCPCHL EQU 31H BLCSH EQU 32H BLCSL EQU 33H BLXS EQU 34H WFXS EQU 35H PCWFH EQU 36H PCWFL EQU 37H SCPCHH EQU 38H SCPCHL EQU 39H SDWDHH EQU 3AH SDWDHL EQU 3BH WDZHH EQU 3CH WDZHL EQU 3DH WFCSH EQU 3EH WFCSL EQU 3FH ZSJCSH EQU 40H ZSJCSL EQU 41H BLPCFH BIT 00H SCBLPCFH BIT 01H WFPCFH BIT 02H
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;PID控温子程序需定义RAM SDWDHH SDWDHL WDZHL WDZHH BCPCHL BCPCHH SCPCHH SCPCHL ; BLXS WFXS PCWFH PCWFL WFCSL WFCSH BLCSL BLCSH ZSJCSH ZSJCSL ; ; 标志位 BLPCFH SCBLPCFH WFPCFH PDJS: ;计算e(t) 值 CLR C MOV A,SDWDHL ;sdwdhh,sdwdhl 存设定温度带一位小数 MOV R7,WDZHL SUBB A,R7 MOV BCPCHL,A ;存本次偏差低8位 MOV A,SDWDHH MOV R7,WDZHH SUBB A,R7 MOV BCPCHH,A ;存本次偏差高8位 JC BOOLL2 CLR BLPCFH ;清比例偏差符号 BOOLL3: JB BLPCFH,JSSZ3 ;符号位为0表示正值,为1表示负值 本次比例偏差符号 为负不加热退出 JB SCBLPCFH,JSSZ2 ;符号位为0表示正值,为1表示负值 上次比例偏差符号 JMP JSSZ1 BOOLL2: SETB BLPCFH CLR C MOV A,#0FFH SUBB A,BCPCHL ;本次温度大于设定温度,求补锝实际数值 e(t) MOV BCPCHL,A MOV A,#0FFH SUBB A,BCPCHH MOV BCPCHH,A INC BCPCHL JMP BOOLL3 JSSZ3: MOV A,BCPCHL MOV SCPCHL,A MOV A,BCPCHH MOV SCPCHH,A JB BLPCFH,MLLP1232 ;将本次偏差数值与符号赋给上次保存地址 CLR SCBLPCFH JMP fool2 MLLP1232: SETB SCBLPCFH jmp fool2 JSSZ2: CLR C ;e(t)>0 e(t-1) <0 MOV A,BCPCHL ;计算e(t)-e(t-1) 的结果,存入PCWFL,PCWFH中 ADDC A,SCPCHL MOV PCWFL,A MOV A,BCPCHH ADDC A,SCPCHH MOV PCWFH,A CLR WFPCFH JMP AOOL1 JSSZ1: CLR C ;到此为止,本次e(t) 值已算出,并有符号位,可判正负%%%%%%%%%%%%%%%%%%%%%%% MOV A,BCPCHL ;计算e(t)-e(t-1) 的结果,存入PCWFL,PCWFH中 SUBB A,SCPCHL ;e(t) e(t-1) 都为正值 MOV PCWFL,A MOV A,BCPCHH SUBB A,SCPCHH MOV PCWFH,A CLR WFPCFH JNC AOOL1 ;本次偏差>上次偏差,转走 SETB WFPCFH ;微分偏差符号置位 CLR C MOV A,#0FFH SUBB A,PCWFL ;本次偏差<上次偏差,求补锝实际数值 MOV PCWFL,A MOV A,#0FFH SUBB A,PCWFH MOV PCWFH,A INC PCWFL AOOL1: MOV A,BCPCHL MOV SCPCHL,A MOV A,BCPCHH MOV SCPCHH,A JB BLPCFH,MLLP1 ;将本次偏差数值与符号赋给上次保存地址 CLR SCBLPCFH JMP MLLP2 MLLP1: SETB SCBLPCFH MLLP2: MOV R2,BCPCHH MOV R3,BCPCHL MOV R4,#0 ;求kp*e(t) MOV R5,#0 MOV R6,#0 MOV R7,BLXS CALL MULD MOV BLCSL,R5 ;结果送到比例常数存储 MOV BLCSH,R4 MOV R3,PCWFL MOV R2,PCWFH MOV R4,#0 MOV R5,#0 MOV R6,#0 MOV R7,WFXS CALL MULD ;求kd*(e(t)-e(t-1)) MOV WFCSL,R5 MOV WFCSH,R4 ;结果送到微分常数存储 JB BLPCFH,FOOL2 ;比例相为负,不计算结果,直接赋pouth=#00 poutl=#200,退出中断 JB WFPCFH,AOOL2 ;微分项为负转走 CLR C MOV A,BLCSL ADD A,WFCSL ;KP>0,KD>0 MOV ZSJCSL,A ;将结果存入总时间常数中 kp*e(t)+kd*(e(t)-e(t-1)) MOV A,BLCSH ADDC A,WFCSH MOV ZSJCSH,A AOOL4: CLR C MOV A,ZSJCSL SUBB A,#0D0H MOV A,ZSJCSH SUBB A,#07H ;为什么是小于2000而不是200呢,因为进行偏差计算时时带一位小数的扩大了10倍 JC AOOL3 ;有借位,说明总时间常数《2000h,数据没有溢出继续 MOV ZSJCSL,#0D0H MOV ZSJCSH,#07H ;无借位说明总时间常数>2000h,数据溢出赋最大值2000h继续 JMP AOOL3 FOOL2: MOV ZSJCSL,#0 ;比例项小于微分项不加热 MOV ZSJCSH,#0 JMP AOOL3 AOOL2: CLR C MOV A,BLCSL SUBB A,WFCSL ;KP>0,KD<0 MOV ZSJCSL,A ;将结果存入总时间常数中 kp*e(t)-kd*(e(t)-e(t-1)) MOV A,BLCSH SUBB A,WFCSH MOV ZSJCSH,A JNC AOOL4 ;KP>KD MOV ZSJCSL,#0 ;比例项小于微分项不加热 MOV ZSJCSH,#0 JMP AOOL3 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;以下程序的4舍5入是为了增加精度,否则总时间常数可以直接除以10得POUTH值;;;;;;;; AOOL3: MOV R6,ZSJCSH MOV R7,ZSJCSL ;总数据常数里面存的是16进制数 MOV R3,#0 MOV R4,#0 MOV R5,#0 CALL HB2 ;换算成bcd码出口在r3,r4,r5中 MOV A,R5 ANL A,#0FH ;取小数位 CLR C SUBB A,#5 JC PPPOOP1 ;小数位<5,转走 MOV A,R5 ANL A,#0F0H SWAP A INC A PPPOOP2: MOV R5,A ;小数位>5,个位数加1实现四舍五入 MOV A,R4 ANL A,#0FH SWAP A ADD A,R5 MOV R3,A MOV A,R4 ANL A,#0F0H SWAP A MOV R2,A CALL BH2 mov ZSJCSH,r3 ;MOV POUTH,R3 为了节省存储器此处用zsjcsh,zsjcsl MOV A,#200 ;代替pouth,poutl SUBB A,R3 mov ZSJCSl,a ;MOV POUTL,A RET PPPOOP1: MOV A,R5 ANL A,#0F0H SWAP A JMP PPPOOP2 ;(21)标号: BH2 功能:双字节BCD码整数转换成双字节十六进制整数 ;入口条件:待转换的双字节BCD码整数在R2、R3中。 ;出口信息:转换后的双字节十六进制整数仍在R2、R3中。 ;影响资源:PSW、A、B、R2、R3、R4 堆栈需求: 4字节 BH2: MOV A,R3; ;将低字节转换成十六进制 LCALL BCDH MOV R3,A MOV A,R2; ;将高字节转换成十六进制 LCALL BCDH MOV B,#100; ;扩大一百倍 MUL AB ADD A,R3; ;和低字节按十六进制相加 MOV R3,A CLR A ADDC A,B MOV R2,A RET ;(20)标号:BCDH 功能:单字节BCD码整数转换成单字节十六进制整数 ;入口条件:待转换的单字节BCD码整数在累加器A中。 ;出口信息:转换后的单字节十六进制整数仍在累加器A中。 ;影响资源:PSW、A、B、R4 堆栈需求: 2字节 BCDH: MOV B,#10H ; ;分离十位和个位 DIV AB MOV R4,B ; ;暂存个位 MOV B,#10 ; ;将十位转换成十六进制 MUL AB ADD A,R4 ; ;按十六进制加上个位 RET ;(17) 标号: HB2 功能:双字节十六进制整数转换成双字节BCD码整数
;入口条件:待转换的双字节十六进制整数在R6、R7中。 ;出口信息:转换后的三字节BCD码整数在R3、R4、R5中。 ;影响资源:PSW、A、R2~R7 堆栈需求: 2字节 HB2: CLR A ; ;BCD码初始化 MOV R3,A MOV R4,A MOV R5,A MOV R2,#10H ; ;转换双字节十六进制整数 HB3: MOV A,R7 ; ;从高端移出待转换数的一位到CY中 RLC A MOV R7,A MOV A,R6 RLC A MOV R6,A MOV A,R5 ; ;BCD码带进位自身相加,相当于乘2 ADDC A,R5 DA A ; ;十进制调整 MOV R5,A MOV A,R4 ADDC A,R4 DA A MOV R4,A MOV A,R3 ADDC A,R3 MOV R3,A ; ;双字节十六进制数的万位数不超过6,不用调整 DJNZ R2,HB3 ; ;处理完16bit RET ;(5) 标号: MULD 功能:双字节二进制无符号数乘法 ; ;入口条件:被乘数在R2、R3中,乘数在R6、R7中。 ;出口信息:乘积在R2、R3、R4、R5中。 ;影响资源:PSW、A、B、R2~R7 堆栈需求: 2字节 MULD: MOV A,R3 ; ;计算R3乘R7 MOV B,R7 MUL AB MOV R4,B ; ;暂存部分积 MOV R5,A MOV A,R3 ; ;计算R3乘R6 MOV B,R6 MUL AB ADD A,R4 ; ;累加部分积 MOV R4,A CLR A ADDC A,B MOV R3,A MOV A,R2 ; ;计算R2乘R7 MOV B,R7 MUL AB ADD A,R4 ; ;累加部分积 MOV R4,A MOV A,R3 ADDC A,B MOV R3,A CLR A RLC A XCH A,R2 ; ;计算R2乘R6 MOV B,R6 MUL AB ADD A,R3 ; ;累加部分积 MOV R3,A MOV A,R2 ADDC A,B MOV R2,A RET
|