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

📄 pid算法程序.txt

📁 使用C8051单片机来实现PID调节
💻 TXT
📖 第 1 页 / 共 2 页
字号:
;********增量式PID控制算法程序*********** 
;T、TD、TI、KP依次从30H,33H,36H,39H开始。 
;A,B,C的值依次存在BLOCK1,BLOCK2,BLOCK3的地址里 
; 这里R(k)给的是定值 



ORG 0000H 
BLOCK1 EQU 43H ;A,B ,C 
BLOCK2 EQU 46H 
BLOCK3 EQU 49H 
UK EQU 4CH ;存结果UK 
RK EQU 50H 
EK EQU 53H ;存放偏差值E(k)的始址 
EK1 EQU 56H ;存放E(k-1)的始址 
EK2 EQU 59H ;存放E(k-2)的始址 
CK EQU 5CH ;采样数据始址 
BUFF EQU 60H ;暂存区 
BUFF1 EQU 63H 
BUFF2 EQU 66H 
REC EQU 69H 
TEST: 
MOV RK,#01H ;常数Rk的BCD码浮点数 
MOV RK+1,#12H ;1.25 
MOV RK+2,#50H 
MOV 3CH,#01H ;常数1的BCD码浮点数 
MOV 3DH,#10H 
MOV 3EH,#00H 
MOV 40H,#01H ;常数2的BCD码浮点数 
MOV 41H,#20H 
MOV 42H,#00H 
MOV 30H,#01H ;T的BCD 码浮点数 
MOV 31H,#23H ;2.34 
MOV 32H,#40H 
MOV 33H,#01H ;Td的BCD码浮点数 
MOV 34H,#35H ;3.54 
MOV 35H,#40H 
MOV 36H,#01H ;Ti的BCD码浮点数 
MOV 37H,#11H ;1.12 
MOV 38H,#20H 
MOV 39H,#01H ;Kp的BCD码浮点数 
MOV 3AH,#12H ;1.25 
MOV 3BH,#50H 

MOV R0,#RK ;指向BCD码浮点操作数 
LCALL BTOF ;将其转换成二进制浮点操作数 
MOV R0,#3CH 
LCALL BTOF 
MOV R0,#40H 
LCALL BTOF 

MOV R0,#39H 
LCALL BTOF 
MOV R0,#36H ;指向BCD码浮点操作数Ti 
LCALL BTOF ;将其转换成二进制浮点操作数 
MOV R0,#33H ;指向BCD码浮点操作数Td 
LCALL BTOF ;将其转换成二进制浮点操作数 
MOV R0,#30H ;指向BCD码浮点操作数T 
LCALL BTOF ;将其转换成二进制浮点操作数 

MOV R1, #BUFF1 ;保存30H中的值 即T值 
LCALL FMOVR0 
MOV R1, #36H ;计算A值(1+T/Ti+Td/T).Kp 
LCALL FDIV 
MOV R1,#3CH ;常数1 
LCALL FADD 
MOV R0,#33H ;保存33H中的值 
MOV R1,#BUFF 
LCALL FMOVR0 
MOV R1,#BUFF1 
LCALL FDIV 
MOV R1,#30H ;30H里存的是T/Ti+1 
LCALL FADD 
MOV R1,#39H 
LCALL FMUL 
MOV R1 ,#BLOCK1 ;将结果保存在BLOCK1中 
LCALL FMOVR0 
MOV R1,#BUFF1 ;30H恢复原值 
MOV R0,#30H 
LCALL FMOV 
MOV R1,#BUFF ;33H恢复原值 
MOV R0,#33H 
LCALL FMOV 
MOV R0,#40H ;计算B的值Kp.(1+2.Td/T) 
MOV R1,#33H 
LCALL FMUL 
MOV R1,#30H 
LCALL FDIV 
MOV R1,#3CH 
LCALL FADD 
MOV R1,#39H 
LCALL FMUL 
MOV R1,#BLOCK2 ;保存B值到BLOCK2中 
LCALL FMOVR0 
MOV R0,#39H ;计算C的值Kp.Td/T 
MOV R1,#33H 
LCALL FMUL 
MOV R1,#30H 
LCALL FDIV 
MOV R1,#BLOCK3 ;保存C值到BLOCK3中 
LCALL FMOVR0 
MOV R0,#EK1 ;将EK1,EK2设初值0 
LCALL FCLR 
MOV R0,#EK2 
LCALL FCLR 
MOV REC,#03H ;设置采样次数 
LOOP: MOV CK,#7eH ;采样数据暂时给了一个定值 
MOV CK+1,#21H ;0.002112 
MOV CK+2,#12H 
MOV R0,#CK 
LCALL BTOF 
MOV R0,#RK ;保存R(k)中的值 
MOV R1,#BUFF 
LCALL FMOVR0 
MOV R1,#CK 
LCALL FSUB ;计算R(k)-C(k)的值送给E(k) 
MOV R1,#EK 
LCALL FMOVR0 
MOV R1,#BUFF ;恢复RK的值 释放BUFF 
MOV R0,#RK 
LCALL FMOV 
MOV R0,#BLOCK2 ;将B.e(k-1)的值暂存在BUFF1中 
MOV R1,#BUFF ;保存B 
LCALL FMOVR0 
MOV R1,#EK1 
LCALL FMUL 
MOV R1,#BUFF1 
LCALL FMOVR0 
MOV R1,#BUFF ;恢复B释放BUFF 
LCALL FMOV 
MOV R0,#BLOCK3 ;将C.e(K-2)的值暂存在BUFF2中 
MOV R1,#BUFF ;保存C 
LCALL FMOVR0 
MOV R1,#EK2 
LCALL FMUL 
MOV R1,#BUFF2 
LCALL FMOVR0 
MOV R1,#BUFF ;恢复C释放BUFF 
LCALL FMOV 
MOV R0,#BLOCK1 ;A.E(k) 
MOV R1,#BUFF 
LCALL FMOVR0 
MOV R1,#EK 
LCALL FMUL 
MOV R1,#BUFF1 ;计算Uk值A.E(k)-B.E(k-1)+C.E(k-2) 
LCALL FSUB 
MOV R1,#BUFF2 
LCALL FADD 
MOV R1,#UK ;保存结果到UK中 
LCALL FMOVR0 
MOV R1,#BUFF ;恢复A 释放BUFF 
LCALL FMOV 
MOV R0,#UK ;UK转换成BCD码浮点数输出 
LCALL FTOB 
MOV R1,#EK1 ;将E(k-1)-->E(k-2),E(k)-->E(k-1) 
MOV R0,#EK2 
LCALL FMOV 
MOV R1,#EK 
MOV R0,#EK1 
LCALL FMOV 
LCALL DELAY ;等待采样时刻 
DJNZ REC,NEXT1 
SJMP $ 
NEXT1: LJMP LOOP 
DELAY: MOV R7,#02H 
DELAY1: MOV R6,#0FFH 
DELAY2: DJNZ R6,DELAY2 
DJNZ R7,DELAY1 
RET 


; (1) 标号: FSDT 功能:浮点数格式化 

;入口条件:待格式化浮点操作数在[R0]中。 

;出口信息:已格式化浮点操作数仍在[R0]中。 
;影响资源:PSW、A、R2、R3、R4、位1FH 堆栈需求: 6字节 

FSDT: LCALL MVR0 ;将待格式化操作数传送到第一工作区中 
LCALL RLN ;通过左规完成格式化 
LJMP MOV0 ;将已格式化浮点操作数传回到[R0]中 

; (2) 标号: FADD 功能:浮点数加法 

;入口条件:被加数在[R0]中,加数在[R1]中。 
;出口信息:OV=0时,和仍在[R0]中,OV=1时,溢出。 
;;影响资源:PSW、A、B、R2~R7、位1EH、1FH 堆栈需求: 6字节 

FADD: CLR F0 ;设立加法标志 

SJMP AS ;计算代数和 

; (3) 标号: FSUB 功能:浮点数减法 

;入口条件:被减数在[R0]中,减数在[R1]中。 
;出口信息:OV=0时,差仍在[R0]中,OV=1时,溢出。 
;影响资源:PSW、A、B、R2~R7、位1EH、1FH 堆栈需求:6字节 

FSUB: SETB F0 ;设立减法标志 
AS: LCALL MVR1 ;计算代数和。先将[R1]传送到第二工作区 
MOV C,F0 ;用加减标志来校正第二操作数的有效符号 
CLR A ; ********???应加的一条语句 
RRC A 
XRL A,@R1 
MOV C,ACC.7 
ASN: MOV 1EH,C ;将第二操作数的有效符号存入位1EH中 
XRL A,@R0 ;与第一操作数的符号比较 
RLC A 
MOV F0,C ;保存比较结果 
LCALL MVR0 ;将[R0]传送到第一工作区中 
LCALL AS1 ;在工作寄存器中完成代数运算 
MOV0: INC R0 ;将结果传回到[R0]中的子程序入口 
INC R0 
MOV A,R4 ;传回尾数的低字节 
MOV @R0,A 
DEC R0 
MOV A,R3 ;传回尾数的高字节 
MOV @R0,A 
DEC R0 
MOV A,R2 ;取结果的阶码 
MOV C,1FH ;取结果的数符 
MOV ACC.7,C ;拼入阶码中 
MOV @R0,A 
CLR ACC.7 ;不考虑数符 
CLR OV ;清除溢出标志 
CJNE A,#3FH,MV01;阶码是否上溢? ******** 应为#40H 

SETB OV ;设立溢出标志 
MV01: MOV A,@R0 ;取出带数符的阶码 
RET 
MVR0: MOV A,@R0 ;将[R0]传送到第一工作区中的子程序 
MOV C,ACC.7 ;将数符保存在位1FH中 
MOV 1FH,C 
MOV C,ACC.6 ;将阶码扩充为8bit补码 
MOV ACC.7,C 
MOV R2,A ;存放在R2中 
INC R0 
MOV A,@R0 ;将尾数高字节存放在R3中 
MOV R3,A ; 
INC R0 
MOV A,@R0 ;将尾数低字节存放在R4中 
MOV R4,A 
DEC R0 ;恢复数据指针 
DEC R0 
RET 
MVR1: MOV A,@R1 ;将[R1]传送到第二工作区中的子程序 

MOV C,ACC.7 ;将数符保存在位1EH中 
MOV 1EH,C 
MOV C,ACC.6 ;将阶码扩充为8bit补码 
MOV ACC.7,C 
MOV R5,A ;存放在R5中 
INC R1 
MOV A,@R1 ;将尾数高字节存放在R6中 
MOV R6,A 
INC R1 
MOV A,@R1 ;将尾数低字节存放在R7中 
MOV R7,A 
DEC R1 ;恢复数据指针 
DEC R1 
RET 
AS1: MOV A,R6 ;读取第二操作数尾数高字节 
ORL A,R7 
JZ AS2 ;第二操作数为零,不必运算 
MOV A,R3 ;读取第一操作数尾数高字节 
ORL A,R4 
JNZ EQ 
MOV A,R6 ;第一操作数为零,结果以第二操作数为准 

MOV R3,A 
MOV A,R7 
MOV R4,A 
MOV A,R5 
MOV R2,A 
MOV C,1EH 
MOV 1FH,C 
AS2: RET 
EQ: MOV A,R2 ;对阶,比较两个操作数的阶码 
XRL A,R5 
JZ AS4 ;阶码相同,对阶结束 
JB ACC.7,EQ3;阶符互异 
MOV A,R2 ;阶符相同,比较大小 
CLR C 
SUBB A,R5 
JC EQ4 
EQ2: CLR C ;第二操作数右规一次 
MOV A,R6 ;尾数缩小一半 
RRC A 
MOV R6,A 
MOV A,R7 
RRC A 
MOV R7,A 
INC R5 ;阶码加一 
ORL A,R6 ;尾数为零否? 
JNZ EQ ;尾数不为零,继续对阶 

MOV A,R2 ;尾数为零,提前结束对阶 
MOV R5,A 
SJMP AS4 
EQ3: MOV A,R2 ;判断第一操作数阶符 
JNB ACC.7,EQ2;如为正,右规第二操作数 
EQ4: CLR C 
LCALL RR1 ;第一操作数右规一次 
ORL A,R3 ;尾数为零否? 
JNZ EQ ;不为零,继续对阶 
MOV A,R5 ;尾数为零,提前结束对阶 
MOV R2,A 
AS4: JB F0,AS5 ;尾数加减判断 
MOV A,R4 ;尾数相加 
ADD A,R7 
MOV R4,A 
MOV A,R3 
ADDC A,R6 
MOV R3,A 
JNC AS2 
LJMP RR1 ;有进位,右规一次 

AS5: CLR C ;比较绝对值大小 
MOV A,R4 
SUBB A,R7 
MOV B,A 
MOV A,R3 
SUBB A,R6 
JC AS6 
MOV R4,B ;第一尾数减第二尾数 
MOV R3,A 
LJMP RLN ;结果规格化 
AS6: CPL 1FH ;结果的符号与第一操作数相反 
CLR C ;结果的绝对值为第二尾数减第一尾数 
MOV A,R7 
SUBB A,R4 
MOV R4,A 
MOV A,R6 
SUBB A,R3 
MOV R3,A 
RLN: MOV A,R3 ;浮点数规格化 
ORL A,R4 ;尾数为零否? 
JNZ RLN1 
MOV R2,#0C1H;阶码取最小值 ******??应为#C0H 
RET 
RLN1: MOV A,R3 
JB ACC.7,RLN2;尾数最高位为一否? 
CLR C ;不为一,左规一次 
LCALL RL1 
SJMP RLN ;继续判断 
RLN2: CLR OV ;规格化结束 
RET 
RL1: MOV A,R4 ;第一操作数左规一次 
RLC A ;尾数扩大一倍 
MOV R4,A 
MOV A,R3 
RLC A 
MOV R3,A 
DEC R2 ;阶码减一 
CJNE R2,#0C0H,RL1E;阶码下溢否? ***** 应改为CJNE R2,#0BFH,RL1E; 
CLR A 
MOV R3,A ;阶码下溢,操作数以零计 
MOV R4,A 
MOV R2,#0C1H ; ******应改为MOV R2,#0C0H 
RL1E: CLR OV 
RET 
RR1: MOV A,R3 ;第一操作数右规一次 
RRC A ;尾数缩小一半 

MOV R3,A 
MOV A,R4 
RRC A 
MOV R4,A 
INC R2 ;阶码加一 
CLR OV ;清溢出标志 
CJNE R2,#40H,RR1E;阶码上溢否? 
MOV R2,#3FH ;阶码溢出 
SETB OV 
RR1E: RET 

; (4) 标号: FMUL 功能:浮点数乘法 

;入口条件:被乘数在[R0]中,乘数在[R1]中。 
;出口信息:OV=0时,积仍在[R0]中,OV=1时,溢出。 
;影响资源:PSW、A、B、R2~R7、位1EH、1FH 堆栈需求:6字节 

FMUL: LCALL MVR0 ;将[R0]传送到第一工作区中 
MOV A,@R0 
XRL A,@R1 ;比较两个操作数的符号 

RLC A 
MOV 1FH,C ;保存积的符号 
LCALL MUL0 ;计算积的绝对值 
LJMP MOV0 ;将结果传回到[R0]中 
MUL0: LCALL MVR1 ;将[R1]传送到第二工作区中 
MUL1: MOV A,R3 ;第一尾数为零否? 
ORL A,R4 
JZ MUL6 
MOV A,R6 ;第二尾数为零否? 
ORL A,R7 
JZ MUL5 
MOV A,R7 ;计算R3R4×R6R7-→R3R4 
MOV B,R4 
MUL AB 
MOV A,B 
XCH A,R7 
MOV B,R3 
MUL AB 
ADD A,R7 
MOV R7,A 
CLR A 
ADDC A,B 
XCH A,R4 
MOV B,R6 
MUL AB 
ADD A,R7 
MOV R7,A 
MOV A,B 
ADDC A,R4 
MOV R4,A 
CLR A 
RLC A 
XCH A,R3 
MOV B,R6 
MUL AB 
ADD A,R4 
MOV R4,A 
MOV A,B 
ADDC A,R3 
MOV R3,A 
JB ACC.7,MUL2;积为规格化数否? R7四舍五入 
MOV A,R7 ;左规一次 
RLC A 
MOV R7,A 
LCALL RL1 
MUL2: MOV A,R7 
JNB ACC.7,MUL3 
INC R4 
MOV A,R4 
JNZ MUL3 
INC R3 
MOV A,R3 
JNZ MUL3 
MOV R3,#80H 
INC R2 
MUL3: MOV A,R2 ;求积的阶码 
ADD A,R5 
MD: MOV R2,A ;阶码溢出判断 

JB ACC.7,MUL4 
JNB ACC.6,MUL6 
MOV R2,#3FH ;阶码上溢,设立标志 
SETB OV 
RET 
MUL4: JB ACC.6,MUL6 
MUL5: CLR A ;结果清零(因子为零或阶码下溢) 
MOV R3,A 
MOV R4,A 
MOV R2,#41H 
MUL6: CLR OV 
RET 

; (5) 标号: FDIV 功能:浮点数除法 

;入口条件:被除数在[R0]中,除数在[R1]中。 
;出口信息:OV=0时,商仍在[R0]中,OV=1时,溢出。 
;影响资源:PSW、A、B、R2~R7、位1EH、1FH 堆栈需求: 5字节 

FDIV: INC R0 
MOV A,@R0 
INC R0 

ORL A,@R0 
DEC R0 
DEC R0 
JNZ DIV1 
MOV @R0,#41H;被除数为零,不必运算 
CLR OV 
RET 
DIV1: INC R1 
MOV A,@R1 
INC R1 
ORL A,@R1 
DEC R1 
DEC R1 
JNZ DIV2 
SETB OV ;除数为零,溢出 
RET 
DIV2: LCALL MVR0 ;将[R0]传送到第一工作区中 
MOV A,@R0 
XRL A,@R1 ;比较两个操作数的符号 
RLC A 
MOV 1FH,C ;保存结果的符号 
LCALL MVR1 ;将[R1]传送到第二工作区中 
LCALL DIV3 ;调用工作区浮点除法 
LJMP MOV0 ;回传结果 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -