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

📄 pid.asm

📁 这个是关于实现同步电机FOC的控制程序源代码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;=======================================================================
; 文件名:	pid.asm			      
;
; 模块名: 	PID_REG3_ID, PID_REG3_IQ, PID_REG3_SPD	
;
; 初始化程序名: PID_REG3_ID_INIT, PID_REG3_IQ_INIT, PID_REG3_SPD_INIT
;
; 公司:	达盛科技
;
; 功能:	三个带积分饱和校正功能的 PID 调节器
;       i)   d 轴电流调节器
;       ii)  q 轴电流调节器
;       iii) 转速调节器
;
;		             |~~~~~~~~~~~~|
;        fdb o------>|		      |
;        ref o------>|            |
;                    |  pid_reg3  |----->o out
;         Kp o------>|            |
; 	      Ki o------>|            |
;         Kd o------>|            |
;         Kc o------>|____________|
;
; 目标CPU:	x2407 
;=====================================================================================
; 更改纪录:
;-------------------------------------------------------------------------------------
; 最后更新时间:2005.08.10	版本号:Ver 1.0	
;===========================================================================
*************************************************************
* D轴电流PID调节器 
*************************************************************
;------------------------------------------------------------
; 变量声明
;------------------------------------------------------------
;(使用子程序就把下面的变量声明文件复制到主程序中)
;		.ref	PID_REG3_ID,PID_REG3_ID_INIT		; 子程序调用
;		.ref	id_fdb,id_ref						; 输入
;		.ref	ud_out								; 输出
;		.ref	Kp_d,Ki_d,Kd_d,Kc_d,ud_max,ud_min 	; 参数
;------------------------------------------------------------
; 全局标号定义
;------------------------------------------------------------
		.def	PID_REG3_ID,PID_REG3_ID_INIT		; 子程序调用
		.def	id_fdb,id_ref						; 输入
		.def	ud_out								; 输出
		.def	Kp_d,Ki_d,Kd_d,Kc_d,ud_max,ud_min 	; 参数

;------------------------------------------------------------
; 局部变量定义
;------------------------------------------------------------
id_fdb		.usect "pid",1		; 电流反馈
id_ref		.usect "pid",1		; 电流参考
ud_out		.usect "pid",1		; 控制电压输出

ud_max	  	.usect "pid",1		; 最大输出电压 (Q15)
ud_min	  	.usect "pid",1		; 最小输出电压 (Q15)

up_d        .usect "pid",1		; 比例误差        (Q14)
up1_d   	.usect "pid",1		; 前一次比例误差  (Q14)

ui_hi_d		.usect "pid",1		; 积分误差 (Q30)
ui_lo_d		.usect "pid",1

ud_hi_d		.usect "pid",1		; 微分误差 (Q30)
ud_lo_d		.usect "pid",1

Kp_d		.usect "pid",1		; 比例增益
Ki_d		.usect "pid",1		; 积分增益
Kd_d        .usect "pid",1		; 微分增益
Kc_d		.usect "pid",1		; 积分饱和校正增益

e_d			.usect "pid",1		; 电流误差
uprsat_d	.usect "pid",1		; 饱和前控制电压

saterr_d	.usect "pid",1		; 饱和误差

;------------------------------------------------------------
; 参数设置
;------------------------------------------------------------
Kp_d_		.set	11178				; Q15, 比例增益
Ki_d_		.set	8000;4194			; Q31, 积分增益
Kd_d_       .set	0					; Q14, 微分增益
Kc_d_		.set	20281				; Q15, 饱和校正增益
Umax_d_		.set	05000h				; 输出电压上限
Umin_d_		.set	0b000h				; 输出电压下限

;------------------------------------------------------------
; 初始化
;------------------------------------------------------------
PID_REG3_ID_INIT
    
    LDP		#Kp_d				
	SPLK	#Kp_d_,Kp_d        	; 比例增益初始化 (Q15)
  	SPLK  	#Ki_d_,Ki_d        	; 积分增益初始化 (Q31-16bit)截取位#23-#8
   	SPLK  	#Kd_d_,Kd_d        	; 微分增益初始化 (Q14)     
    SPLK  	#Kc_d_,Kc_d       	; 饱和校正增益初始化 (Q15)
	SPLK	Umax_d_,ud_max      ; 最大输出电压初始化 (Q15)
	SPLK	Umin_d_,ud_min      ; 最小输出电压初始化 (Q15)	
	SPLK	#0,up1_d            ; 比例误差初始化 (Q14)
	SPLK	#0,ui_hi_d			; 积分时间初始化 (Q30)
    SPLK	#0,ui_lo_d          ; 积分时间初始化 (Q30)
	SPLK	#0,ud_hi_d			; 微分时间初始化 (Q30)
    SPLK	#0,ud_lo_d          ; 微分时间初始化 (Q30)
	
	RET

;------------------------------------------------------------
; 控制程序
;------------------------------------------------------------
PID_REG3_ID
		SETC	SXM           	; 允许符号扩展
		SETC	OVM				; 设置溢出保护
    	SPM		0 				; 复位乘积移位模式		
    
      	LDP		#id_ref			

; e(k) = ref(k)-fdb(k) => Q14 = Q15-Q15
      	LACC	id_ref,15		; ACC = ref        	(Q30)
      	SUB   	id_fdb,15		; ACC = ref-fdb    	(Q30)
      	SACH  	e_d				; e = ref-fdb      	(Q14)
; up(k) = Kp*e(k)  => Q14 = Q15*Q14
		LT		Kp_d			; TREG = Kp        	(Q15)
		MPY		e_d				; PREG = Kp*e	   	(Q29)
		PAC						; ACC = Kp*e	   	(Q29)
		SACH	up_d,1			; up = Kp*e 	   	(Q14)
; uprsat(k) = up(k)+ui(k-1)+ud(k-1) => Q14 = Q14+Q30+Q30		
		LACC	ui_hi_d,16      ; ACC = ui         	(Q30)
		ADDS	ui_lo_d	 		; ACC = ui         	(Q30)
		ADDS	ud_lo_d			; ACC = ui+ud      	(Q30)
		ADDH	ud_hi_d			; ACC = ui+ud      	(Q30)
		ADDH	up_d			; ACC = up+ui+ud   	(Q30)
		SACH	uprsat_d		; uprsat = up+ui+ud (Q14)
; 检查是否饱和
		LACC	uprsat_d,16	    ; ACC = uprsat      (Q14)
		SUB		ud_max,15		; ACC = uprsat-umax (Q14)
        BCND	SAT_MAX_D,GT	; 转到 SAT_MAX,当 uprsat > umax
        LACC	uprsat_d,16	    ; ACC = uprsat      (Q14)
        SUB		ud_min,15		; ACC = uprsat-umin (Q14)
        BCND	SAT_MIN_D,LT	; 转到 SAT_MIN,当 uprsat < umin        
        LACC	uprsat_d,16		; ACC = uprsat    	(Q30)
        SACH	ud_out,1		; uout = uprsat   	(Q15)		
		B		UPDATE_D    
SAT_MAX_D
		LACC	ud_max          ; ACC = umax   		(Q15)
		SACL	ud_out			; uout = umax  		(Q15)
		B		UPDATE_D        
SAT_MIN_D
		LACC	ud_min          ; ACC = umin   		(Q15)
		SACL	ud_out			; uout = umin  		(Q15)
UPDATE_D        
		LACC	ud_out,15		; ACC = uout        (Q30)
		SUB		uprsat_d,16		; ACC = uout-uprsat (Q30)
		SACH	saterr_d		; saterr = uout-uprsat   (Q14)

; ui(k) = ui(k-1)+Ki*up(k)+Kc*(uout-uprsat) => Q30 = Q30+Q31*Q14+Q15*Q14
		SPM		3				; 设置乘积移位6
		LT		Ki_d			; TREG = Ki        	(Q31-16bit)
		MPY		up_d			; PREG = Ki*up     	(Q38)
		PAC				        ; ACC = Ki*up      	(Q32)
		SFR                     ; ACC = Ki*up      	(Q31)
		SFR						; ACC = Ki*up      	(Q30)	
        SPM		1				; 设置乘积移位1
        LT		Kc_d			; TREG = Kc        	(Q15)
        MPY		saterr_d        ; PREG = Kc*(uout-uprsat)       	(Q29)
        APAC					; ACC = Ki*up+Kc*(uout-uprsat)  	(Q30)
		ADDS	ui_lo_d			; ACC = ui+Ki*up+Kc*(uout-uprsat)  	(Q30)
		ADDH	ui_hi_d			; ACC = ui+Ki*up+Kc*(uout-uprsat)  	(Q30)
		SACL	ui_lo_d			; ui = ui+Ki*up+Kc*(uout-uprsat)   	(Q30)       
		SACH	ui_hi_d			; ui = ui+Ki*up+Kc*(uout-uprsat)   	(Q30)  

; ud(k) = Kd*up(k)-Kd*up(k-1) => Q30 = Q14*Q14-Q14*Q14
        LT		Kd_d			; TREG = Kd      	 (Q14)
        MPY		up_d			; PREG = Kd*up   	 (Q28)
    	PAC						; ACC = Kd*up    	 (Q29)
		MPY		up1_d			; PREG = Kd*up1   	 (Q28)
		SPAC					; ACC = Kd*up-Kd*up1 (Q29)
		SACL	ud_lo_d,1		; ud = Kd*up-Kd*up1  (Q30)
		SACH	ud_hi_d,1		; ud = Kd*up-Kd*up1  (Q30)					

; 刷新 up
		LACC	up_d			; ACC = up   (Q14)
		SACL	up1_d			; up1 = up   (Q14)
				
		spm 0
		RET

*** D轴 PID 电流调节器程序代码结束

		
*************************************************************
* Q轴 PID 电流调节器
*************************************************************
;------------------------------------------------------------
;(使用子程序就把下面的变量声明文件复制到主程序中)
;		.ref	PID_REG3_IQ,PID_REG3_IQ_INIT		; 子程序调用
;		.ref	iq_fdb,iq_ref						; 输入
;		.ref	uq_out								; 输出
;		.ref	Kp_q,Ki_q,Kd_q,Kc_q,uq_max,uq_min 	; 参数
;------------------------------------------------------------
; 标号定义
;------------------------------------------------------------
;变量定义.
		.def	PID_REG3_IQ,PID_REG3_IQ_INIT		; 子程序调用
		.def	iq_fdb,iq_ref						; 输入
		.def	uq_out								; 输出
		.def	Kp_q,Ki_q,Kd_q,Kc_q,uq_max,uq_min 	; 参数

;------------------------------------------------------------
; 变量定义
;------------------------------------------------------------
iq_fdb		.usect "pid",1		; 电流反馈
iq_ref		.usect "pid",1		; 电流参考
uq_out		.usect "pid",1		; 控制电压输出

uq_max	  	.usect "pid",1		; 最大输出电压 (Q15)
uq_min	  	.usect "pid",1		; 最小输出电压 (Q15)

up_q        .usect "pid",1		; 比例误差        (Q14)
up1_q   	.usect "pid",1		; 前一时刻比例误差(Q14)

ui_hi_q		.usect "pid",1		; 积分误差 (Q30)
ui_lo_q		.usect "pid",1

ud_hi_q		.usect "pid",1		; 微分误差 (Q30)
ud_lo_q		.usect "pid",1

Kp_q		.usect "pid",1		; 比例增益
Ki_q		.usect "pid",1		; 积分增益
Kd_q        .usect "pid",1		; 微分增益
Kc_q		.usect "pid",1		; 积分饱和校正增益

e_q			.usect "pid",1		; 电流误差
uprsat_q	.usect "pid",1		; 饱和前控制电压

saterr_q	.usect "pid",1		; 饱和误差 

;------------------------------------------------------------
; PID参数
;------------------------------------------------------------
Kp_q_		.set	11178				; Q15, 比例增益
Ki_q_		.set	8000;4194			; Q31, 积分增益
Kd_q_       .set	0 					; Q14, 微分增益
Kc_q_		.set	20281				; Q15, 饱和校正增益

Umax_q_		.set	06700h				; 最大电压
Umin_q_		.set	09900h				; 最小电压

;------------------------------------------------------------
; 初始化程序
;------------------------------------------------------------
PID_REG3_IQ_INIT
    
    LDP		#Kp_q				
	
	SPLK	#Kp_q_,Kp_q        	; 比例增益初始化 (Q15)

⌨️ 快捷键说明

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