📄 pid.c
字号:
;**********************************************************************
;最佳参数:(此参数仅适用本系统)
; 采样周期10MS时
; KP=AFH*2,KI=46H,KD=F9*8H
; 运算中以上参数全当小数处理
; 即实际参数为:KP=0.6836*2 =1.3672
; KI=0.2734
; KD=0.9727*8=7.7813
;HURGE
;200710251556
;
;*****************************定义变量存储区******************************
PH EQU 30H
PM EQU 31H
PL EQU 32H
IH EQU 33H
IM EQU 34H
IL EQU 35H
DH EQU 36H
DM EQU 37H
DL EQU 38H
KP EQU 39H ;P参数
KI EQU 3AH ;I参数
KD EQU 3BH ;D参数
EK0 EQU 3CH
EK1 EQU 3DH
PEKH EQU 3EH
OLDKEY EQU 3FH
UK0H EQU 40H
UK0L EQU 41H
EI EQU 42H
PEKL EQU 43H
IEKH EQU 44H
IEKL EQU 45H
DEKH EQU 46H
DEKL EQU 47H
EKI EQU 48H
EK2 EQU 49H
UK1H EQU 4AH
UK1L EQU 4BH
;----------------------------------------------------------------------------
ORG 0000H
AJMP MAIN
ORG 0003H ;外部中断0入口地址
AJMP AINT
ORG 000BH ;定时器T0中断服务入口地址
AJMP T0INT
;*****************************************************-----------------------
; 主程序
;*****************************************************-----------------------
ORG 100H
MAIN: MOV SP,#50H ;初始化堆栈
;初始化数据段
MOV PH,#07H
MOV PM,#0H
MOV PL,#0H
MOV IH,#02H
MOV IM,#08H
MOV IL,#0H
MOV DH,#09H
MOV DM,#09H
MOV DL,#06H
;******************************************
MOV KP,#0AFH ;P参数 (.AFH)*2=1.3672
MOV KI,#046H ;I参数 (.46H)=0.2734
MOV KD,#0F9H ;D参数 (.F9H)*8=7.7813
;*******************************************
MOV EK0,#00H ;e(0)
MOV EK1,#00H ;e(-1)
MOV PEKH,#00H ;
MOV OLDKEY,#00H ;存按键值
MOV UK0H,#00H ;数据暂存
MOV UK0L,#00H
MOV EI,#50H ;门限电压值
MOV PEKL,#00H
MOV IEKH,#00H
MOV IEKL,#00H
MOV DEKH,#00H
MOV DEKL,#00H
MOV EKI,#00H
MOV EK2,#00H
MOV UK1H,#00H
MOV UK1L,#00H
MOV R0,#30H
MOV R2,#00H
MOV R3,#00H
MOV R4,#00H
MOV R5,#00H
MOV R6,#00H
MOV R7,#00H
MOV TMOD,#01H ;初始化定时器Xms
MOV TH0,#0E0H
MOV TL0,#0BFH
MOV IE,#82H ;开定时中断
SETB TR0 ;启用定时器0
MAINLOOP:
LCALL DISP ;调用显示
LCALL KEYP
JMP MAINLOOP
;*****************************************************
; 中断处理
;*****************************************************
;---------------------10MS定时中断处理------------------
T0INT: PUSH ACC
PUSH DPL
PUSH DPH
;启用AD转换
;*****************************************
;——方法1 地址方式
MOV DPTR,#3FFFH
MOVX @DPTR,A
;_____________________
;——方法2 IO方式
CLR P2.7
; NOP
; NOP
; ;AD转换start
; CLR P2.6
; CLR P3.6
; NOP
; NOP
; SETB P2.6
; SETB P3.6
MOV IE,#083H ;开外部中断
;赋计数初值
MOV TH0,#0E0H
MOV TL0,#0BFH
POP DPH
POP DPL
POP ACC
RETI
;--------------------------------------------------------------
;---------------外部中断处理-----------------------------------
AINT: PUSH ACC
PUSH PSW
PUSH DPL
PUSH DPH
SETB PSW.3
;AD运算 读AD转换值
;**********************************
;——方法1 地址方式
; MOV DPTR,#3FFFH
; NOP
; MOVX A,@DPTR
;——方法2 IO方式
CLR P2.6
CLR P3.7
NOP
MOV A,P0
NOP
SETB P3.7
SETB P2.6
;AD转换end
;----------------------
; CLR C
; SUBB A,#00H ;误差修正
MOV IE,#82H ;关外部中断
ADD A,#80H ;采样值转化为偏移二进制
;******************************************************************
;位置式PID算法,算法为UK0=UK1+(EK0-EK1)*KP+Kc*EK0*KI+(EK0-2EK1+EK2)*KD;当EKO不大于门限电压时,Kc取1,其他取0
;PID运算,R7为正负标志,EK0为本次误差,EK1为上次误差,EK2为上上次误差
;PEKL为P运算结果低位,PEKH为P运算结果高位
;IEKL为I运算结果低位,IEKH为I运算结果高位
;DEKL为D运算结果低位,DEKH为D运算结果高位
;UK0H为本次PID运算结果高位,UK0L为低位
;UK1H为上次PID运算结果高位,UK1L为低位
MOV EK0,A
;*****************比例运算*********************
PPP:
JNB ACC.7,PP1
MOV R7,#01H ;存负号标志
PP1: CLR C
SUBB A,EK1 ;EK0-EK1
JNB PSW.2,PP2 ;判断是否溢出并处理
CJNE R7,#01H,PP3 ;判断正负溢出
MOV R7,#00H ;清负标志
MOV A,#80H ;正溢出给正最大值
JMP PP2
PP3: MOV A,#7FH ;负溢出给正负最小值
PP2: MOV R7,#00H ;无益出清负标志
JNB ACC.7,PPP0 ;判断EK0-EK1是否为负
CPL A ;负值取其绝对值(取反加一)
INC A
MOV R7,#01H ;值负标志
PPP0:
MOV B,KP ;运算完成2(EK0-EK1)*KP 通过1次左移运算实现
MUL AB
CLR C
RLC A
MOV PEKL,A
MOV A,B
RLC A
MOV PEKH,A
JNB ACC.7,PPP1 ;运算有溢出给最大值,并结束左移运算
MOV PEKH,#7FH
MOV PEKL,#0FFH
PPP1: CJNE R7,#01H,PP5 ;被乘数为负结果处理(还原为补码)
MOV R7,#00H
MOV A,PEKL
CPL A ;取反
ADD A,#01H ;加一
MOV PEKL,A ;送低位结果
MOV A,PEKH
CPL A ;取反
ADDC A,#00H ;加进位位
MOV PEKH,A ;送高位结果
PP5: ;比例运算结束
;***************************
;********积分运算********
III: MOV A,EK0
JNB ACC.7,II1 ;判断正负
MOV R7,#01H ;置负标志
CPL A ;负值取其绝对值(取反加一)
INC A
II1:
MOV B,KI
MUL AB ;EK0*KI
MOV IEKL,A
MOV IEKH,B
CJNE R7,#01H,II3 ;EK0为负值的处理(还原成补码)
MOV R7,#00H
MOV A,IEKL
CLR C
CPL A
ADD A,#01H
MOV IEKL,A
MOV A,IEKH
CPL A
ADDC A,#00H
MOV IEKH,A
II3: ;积分运算结束
;**************微分运算 *********
DDD: MOV A,EK0
JNB ACC.7,DD1
MOV R7,#01H ;存负号标志
DD1: CLR C
SUBB A,EK1 ;EK0-EK1
JNB PSW.2,DD2 ;判断是否溢出并处理
CJNE R7,#01H,DD3 ;判断正负溢出
MOV R7,#00H ;清负标志
MOV A,#80H
JMP DD2
DD3: MOV A,#7FH
DD2: MOV R7,#00H ;清负标志
MOV EKI,A
MOV A,EK2
JNB ACC.7,DD4
MOV R7,#01H ;存负号标志
DD4: CLR C
SUBB A,EK1 ;EK2-EK1
JNB PSW.2,DD5 ;判断是否溢出并处理
CJNE R7,#01H,DD6 ;判断正负溢出
MOV R7,#00H ;清负标志
MOV A,#80H
JMP DD5
DD6: MOV A,#7FH
DD5: MOV R7,#00H ;清负标志
JNB ACC.7,DD7
MOV R7,#01H
DD7: ADD A,EKI
JNB PSW.2,DDD1 ;判断是否溢出并处理
CJNE R7,#01H,DDD2 ;判断正负溢出
MOV R7,#00H ;清负标志
MOV A,#80H
JMP DDD1
DDD2: MOV A,#7FH
DDD1: MOV R7,#00H ;清负标志
MOV EKI,A ;做(EK0-2EK1+EK2)
JNB ACC.7,DDD0 ;判断(EK0-2EK1+EK2是否为负
CPL A
INC A
MOV R7,#01H
DDD0: MOV B,KD ;运算完成8(EK0-2EK1+EK2)*KD,通过3次左移运算实现
MUL AB
CLR C
RLC A
MOV DEKL,A
MOV A,B
RLC A
MOV DEKH,A
JNB ACC.7,DDD3 ;运算有溢出给最大值,并结束左移运算
MOV DEKH,#7FH
MOV DEKL,#0FFH
JMP DDD5
DDD3: MOV A,DEKL
CLR C
RLC A
MOV DEKL,A
MOV A,DEKH
RLC A
MOV DEKH,A
JNB ACC.7,DDD4 ;运算有溢出给最大值,并结束左移运算
MOV DEKH,#7FH
MOV DEKL,#0FFH
JMP DDD5
DDD4: MOV A,DEKL
CLR C
RLC A
MOV DEKL,A
MOV A,DEKH
RLC A
MOV DEKH,A
JNB ACC.7,DDD5 ;运算有溢出给最大值
MOV DEKH,#7FH
MOV DEKL,#0FFH
DDD5: CJNE R7,#01H,DDD6
MOV R7,#00H
MOV A,DEKL
CLR C
CPL A
ADD A,#01H
MOV DEKL,A
MOV A,DEKH
CPL A
ADDC A,#00H
MOV DEKH,A
DDD6: ;*********微分运算结束*********
;************求和运算*****************
MOV UK0H,UK1H ;Uk(k-1)运算结果给UK0
MOV UK0L,UK1L
MOV R1,#UK0H ;Uk(k-1)+P运算结果给UK0
MOV R0,#UK0L
MOV R2,PEKL
MOV R3,PEKH
LCALL FADD
MOV R1,#UK0H ;Uk(k-1)+P+D运算结果给UK0
MOV R0,#UK0L
MOV R2,DEKL
MOV R3,DEKH
LCALL FADD
MOV A,EK0 ;门限比较
JNB ACC.7,UUUU0 ;判断正负
CPL A ;负值取其绝对值(取反加一)
INC A
UUUU0: CLR C
SUBB A,EI ;门限电压为3FH
JNC UUU ;过门限电压去掉积分项
MOV R1,#UK0H
MOV R0,#UK0L
MOV R2,IEKL
MOV R3,IEKH
LCALL FADD
;Uk(k-1)+P+D+I运算结果给UK0
UUU: ;------存UK0值
MOV UK1H,UK0H
MOV UK1L,UK0L
;-----------进位处理-------
MOV A,UK0H
JNB ACC.7,UUU0 ;判断PID运算结果正负(判断高八位最高为是否为1)
MOV A,UK0L ;为负时判断低八位是否为80H
JB ACC.7,SPID ;低八位最高位大于80H时不进位
MOV A,UK0H
CJNE A,#80H,UKA2 ;判断高八位为80H时也不进位(进位则会溢出)
JMP SPID
UKA2: DEC A ;高八位小于80H时进位(进位即高八位减一因为是负数)
MOV UK0H,A
JMP SPID
UUU0: MOV A,UK0L ;正数处理
JNB ACC.7,SPID ;判断低位是否大于80H,不大不做进位处理
MOV A,UK0H ;判断高位是否为7FH,是不做进位处理(进位则溢出)
CJNE A,#7FH,UKA5
JMP SPID
UKA5: INC A ;低八位大于80H时进位(进位即高8位加一 正数)
MOV UK0H,A
SPID: MOV A,UK0H
END1: ADD A,#80H ;回归原码
;-----------------------PID运算结束------------------
;DA转换
MOV DPTR,#0DFFFH
MOVX @DPTR,A
MOV EK2,EK1
MOV EK1,EK0
POP DPH
POP DPL
POP PSW
POP ACC
RETI
;两位加法子程序,带溢出处理
FADD: ;和运算程序,加数高位地址入口R1,低位R0,被加数高位入口R3,低位R2,出口高位地址入口R1,低位R0
MOV A,@R0
CLR C
ADD A,R2 ;完成低8位加
MOV @R0,A
MOV A,@R1 ;和送低位和入口地址
JNB ACC.7,FADD1 ;判断加数正负
MOV R7,#01H ;置负标志
FADD1: ADDC A,R3 ;高8位加
MOV @R1,A ;和送高位和入口地址
JNB PSW.2,FADD2 ;判断是否溢出并处理
CJNE R7,#01H,FADD3 ;判断正负溢出
MOV R7,#00H ;清负标志
MOV @R1,#80H ;正溢出给正最大值
MOV @R0,#00H
JMP FADD2
FADD3: MOV @R1,#7FH ;负溢出给正最小值
MOV @R0,#0FFH
FADD2: MOV R7,#00H ;清负标志
RET
;**********************************************************OK
;键盘采样与处理子程序 R4设定标志
;**********************************************************OK
;__________________________________-
KEYP: SETB P1.7 ;延时
NOP
NOP
CLR P1.7
CLR RI
MOV SCON,#10H ;串行口工作与方式0
REP1: JNB RI,REP1
MOV A,SBUF
CJNE A,OLDKEY,NEXT ;判断按键是否结束
LJMP BACK
NEXT: CJNE A,#0DFH,NEXT1 ;运行键是否按下
MOV OLDKEY,A
;置运行
SETB TR0
MOV R4,#00H
LJMP BACK2
NEXT1: CJNE A,#0FEH,NEXT2 ;设定键是否按下
MOV R4,#01H ;置设定标志
CLR TR0
;关AD转换
LJMP BACK
NEXT2: CJNE A,#0FDH,NEXT3 ;切换键是否按下
INC R0
INC R0
INC R0
CJNE R0,#39H,N1
MOV R0,#30H
N1: INC R2
CJNE R2,#03H,NN1
MOV R2,#00H
NN1:
LJMP BACK
NEXT3: CJNE R4,#00H,NEXT4 ;是否设定
LJMP BACK
NEXT4: CJNE A,#0FBH,NEXT5 ;位选键是否按下
INC R6
CJNE R6,#03H,N2
MOV R6,#00H
N2:
MOV OLDKEY,A
LJMP BACK1
NEXT5: CJNE A,#0F7H,NEXT6 ;上升键是否
INC @R1
CJNE @R1,#0AH,N3
MOV @R1,#00H
N3: LJMP BACK
NEXT6: CJNE A,#0EFH,BACK3 ;下降键是否按下
CJNE @R1,#00H,N4
MOV @R1,#0AH
N4: DEC @R1
BACK3: LJMP BACK
;_______----BACK2:PID参数转换程序-------------------_______________
BACK2: ;P参数转换
MOV A,PH
MOV B,#4
DIV AB
MOV R5,B
MOV B,#64H
MUL AB
MOV KP,A
MOV A,R5
MOV B,#0AH
MUL AB
ADD A,PM
MOV B,#4
DIV AB
MOV R5,B
MOV B,#0AH
MUL AB
ADD A,KP
MOV KP,A
MOV A,R5
MOV B,#0AH
MUL AB
ADD A,PL
MOV B,#4
DIV AB
ADD A,KP
MOV KP,A
;I参数转换
MOV A,IH
MOV B,#4
DIV AB
MOV R5,B
MOV B,#64H
MUL AB
MOV KI,A
MOV A,R5
MOV B,#0AH
MUL AB
ADD A,IM
MOV B,#4
DIV AB
MOV R5,B
MOV B,#0AH
MUL AB
ADD A,KI
MOV KI,A
MOV A,R5
MOV B,#0AH
MUL AB
ADD A,IL
MOV B,#4
DIV AB
ADD A,KI
MOV KI,A
;D参数转换
MOV A,DH
MOV B,#4
DIV AB
MOV R5,B
MOV B,#64H
MUL AB
MOV KD,A
MOV A,R5
MOV B,#0AH
MUL AB
ADD A,DM
MOV B,#4
DIV AB
MOV R5,B
MOV B,#0AH
MUL AB
ADD A,KD
MOV KD,A
MOV A,R5
MOV B,#0AH
MUL AB
ADD A,DL
MOV B,#4
DIV AB
ADD A,KD
MOV KD,A
JMP BACK1
BACK: MOV OLDKEY,A
BACK1: MOV A,R0
ADD A,R6
MOV R1,A
RET
;*************************************************************88
; 显示程序 88
;*************************************************************88
DISP:
MOV DPTR,#TABLE
MOV A,R2
ADD A,#0AH
MOVC A,@A+DPTR
MOV P1,A
SETB P2.0
CALL DELAY
CLR P2.0
MOV A,#0DH
MOVC A,@A+DPTR
MOV P1,A
SETB P2.1
CALL DELAY
CLR P2.1
MOV A,@R0
MOVC A,@A+DPTR
MOV P1,A
SETB P2.2
CALL DELAY
CLR P2.2
INC R0
MOV A,@R0
MOVC A,@A+DPTR
MOV P1,A
SETB P2.3
CALL DELAY
CLR P2.3
INC R0
MOV A,@R0
MOVC A,@A+DPTR
MOV P1,A
SETB P2.4
CALL DELAY
CLR P2.4
DEC R0
DEC R0
RET
DELAY: MOV R7,#30h
LOOP: NOP
DJNZ R7,LOOP
RET
;;TT DB 0FCH,18H,(1MS) 0F8H, 30H,(2MS) 0f6h,3ch(2.5MS) 0F4H,48H, (3MS) 0F0H,60H,(4MS) 0ECH,78H, 0E0H,0BFH (10MS) 0D8H,0F0H ;采样周期存储区
TABLE: DB 3FH,06H,5BH,4FH,66H
DB 6DH,7DH,07H,7FH,6FH,73H,30H,5EH,40H ;分别为0 1 2 3 4 5 6 7 8 9 P I D - 的字形码
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -