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

📄 pid_reg1.asm

📁 无刷直流电机的无传感器控制TI程序
💻 ASM
字号:
;===========================================================================
; File Name:	pid_reg1.asm	
;
; Module Name: 	PID_REG1				     
;
; Initialization Routine: PID_REG1_INIT
;
; Originator:	Digital Control Systems Group
;			Texas Instruments
;
; Description:	Digital PID controller without anti-windup correction
;
;				|~~~~~~~~~~~~~~~~~~~|
;				| 		    |
;	pid_ref_reg1 o--------->|Q15   PID_REG1	 Q15|----->o pid_out_reg1
;	pid_fb_reg1  o--------->|Q15		    |
;				|___________________|
;
; Target dependency:	C2xx core only
;
;=====================================================================================
; History:
;-------------------------------------------------------------------------------------
; 9-15-2000	Release Rev 1.0
;===========================================================================
;(To use this Module, copy this section to main system file)
;		.ref	PID_REG1, PID_REG1_INIT					;function call
;		.ref	pid_fb_reg1, pid_ref_reg1				;Inputs
;		.ref	pid_out_reg1							;Output
;===========================================================================
		.def	PID_REG1, PID_REG1_INIT					;function call
		.def	pid_fb_reg1, pid_ref_reg1				;Inputs
		.def	pid_out_reg1							;Output
;===========================================================================
Kp_REG1_		.set	2000h	      ; for Kp_reg1 
Ki_HI_REG1_		.set	0010h	      ; for Ki_low_reg1   (Ki=0 for PD)
Ki_LO_REG1_		.set	0BEEFh	      ; for Ki_high_reg1  (Ki=0 for PD)
Kd_REG1_		.set	0000h	      ; for Kd_reg1       (Kd=0 for PI)
PID_OUT_MAX_    .set	0666h	      ; for pid_out_max  
PID_OUT_MIN_    .set	0000h	      ; for pid_out_min 

		.include 	"x24x_app.h"  

;===========================================================================
;Variable Definitions for PID_REG1 module
;---------------------------------------------------------------------------
Kp_reg1			.usect	"pid_reg1",1     		; Kp = Q15
Ki_low_reg1		.usect	"pid_reg1",1            ; Ki = Q31
Ki_high_reg1	.usect	"pid_reg1",1            ; Ki = Q31
Kd_reg1			.usect	"pid_reg1",1            ; Kd = Q15
K0_low_reg1		.usect	"pid_reg1",1            ; K0 = Q31
K0_high_reg1    .usect	"pid_reg1",1            ; K0 = Q31
K1_reg1			.usect	"pid_reg1",1            ; K1 = Q15
pid_fb_reg1		.usect	"pid_reg1",1
pid_ref_reg1	.usect	"pid_reg1",1
pid_out_reg1	.usect	"pid_reg1",1
pid_out1_reg1   .usect	"pid_reg1",1
pid_e0_reg1		.usect	"pid_reg1",1
pid_e1_reg1		.usect	"pid_reg1",1
pid_e2_reg1		.usect	"pid_reg1",1
tmp1_low_reg1	.usect	"pid_reg1",1
tmp1_high_reg1	.usect	"pid_reg1",1
tmp2_low_reg1	.usect	"pid_reg1",1
tmp2_high_reg1	.usect	"pid_reg1",1
tmp3_reg1		.usect	"pid_reg1",1
abs_e0_reg1		.usect	"pid_reg1",1
sign_reg1       .usect	"pid_reg1",1

;=========================================================================
PID_REG1_INIT:
;=========================================================================
        LDP		#Kp_reg1                      		
 		
 		SPLK	#Kp_REG1_,Kp_reg1
		SPLK	#Ki_LO_REG1_,Ki_low_reg1
		SPLK	#Ki_HI_REG1_,Ki_high_reg1			
		SPLK	#Kd_REG1_,Kd_reg1
		SPLK	#0,pid_e1_reg1
		SPLK	#0,pid_e2_reg1
		SPLK	#0,pid_out1_reg1  

        RET

;===============================================================================
PID_REG1:
;===============================================================================

    	SETC	SXM           		; Sign extension mode
        SETC	OVM              	; Overflow mode
        SPM		0                	; Reset SPM 	   

; Converting from Kp, Ki, Kd to K0, K1 (Note: K2 = Kd)
		LDP		#Kp_reg1
		LACC	Ki_high_reg1,16     ; ACC = Ki              	(Q31)
		ADDS	Ki_low_reg1			; ACC = Ki 					(Q31)		
 		ADD		Kp_reg1,16			; ACC = Kp + Ki				(Q31)
		ADD		Kd_reg1,16			; ACC = Kp + Ki + Kd		(Q31)
		SACH    K0_high_reg1		; K0 = Kp + Ki + Kd			(Q31)
		SACL	K0_low_reg1			; K0 = Kp + Ki + Kd			(Q31)
		
		LACC	Kd_reg1,16			; ACC = Kd					(Q15)
		SFL							; ADD = 2*Kd				(Q15)	
		ADD		Kp_reg1,16			; ACC = 2*Kd+Kp				(Q15)				
		SACH 	K1_reg1				; K1 = 2*Kd+Kp				(Q15)

; e(k) = ref(k)-fb(k) => Q15 = Q15 - Q15 
		LACC    pid_ref_reg1        ; ACC =  pid_ref_reg1               (Q15)
		SUB     pid_fb_reg1         ; ACC = pid_ref_reg1 - pid_fb_reg1  (Q15)
		SACL    pid_e0_reg1         ; e(k) = pid_ref_reg1 - pid_fb_reg1 (Q15)

; tmp1 = -K1*e(k-1)+K2*e(k-2) => Q31 = -Q15*Q15 + Q15*Q15 		
   		LT		Kd_reg1				; TREG = K2   						(Q15)
		MPY		pid_e2_reg1			; PREG = K2*e(k-2)   				(Q30)
		PAC							; ACC = K2*e(k-2)   				(Q30)
		LT		K1_reg1				; TREG = K1   						(Q15)
		MPY		pid_e1_reg1			; PREG = K1*e(k-1)   				(Q30)
		SPAC						; ACC = -K1*e(k-1)+K2*e(k-2)   		(Q30)	
        SACH	tmp1_high_reg1,1	; tmp1 = -K1*e(k-1)+K2*e(k-2)   	(Q31)
        SACL	tmp1_low_reg1,1		; tmp1 = -K1*e(k-1)+K2*e(k-2)   	(Q31)
                
; tmp2 = K0*e(k)   =>  Q31 = Q31*Q15   	   	
; check sign for "error" only   
        
  		LACC	pid_e0_reg1      	; ACC = e(k)	
   		SACL	sign_reg1			; Sign (0=+,1=-) for K0*e(k)

; take absolute for "pid_e2_reg1" only because "K0" is always positive    	   	

   		ABS							; ACC = |e(k)|
   		SACL	abs_e0_reg1			; |e(k)| = ACC low  	   	       
   	   	
; now they're positive.    	   	
		LT		abs_e0_reg1   		; TREG = |e(k)|            
   		MPYU	K0_low_reg1    		; PREG = K0_low*|e(k)| 	   
  		SPH		tmp2_low_reg1  		; tmp2_low = PREG high      
  		MPYU	K0_high_reg1		; PREG = K0_high*|e(k)|
   		PAC							; ACC = K0_high*|e(k)|
   		ADDS 	tmp2_low_reg1 		; ACC = K0_high*|e(k)| + tmp2_low
   		SACH	tmp2_high_reg1,1	; tmp2_high = ACC high   	(Q31)
   		SACL	tmp2_low_reg1,1		; tmp2_low = ACC low     	(Q31)

; check the sign condition
		LACC	sign_reg1			; ACC = sign
		BCND  	DONE_REG1, GT      	; Check sign = positive ?
		LACC	tmp2_high_reg1,16  	; ACC high= tmp2_high
		ADDS	tmp2_low_reg1		; ACC low = tmp2_low
		NEG							; Make the result negative
  		SACH	tmp2_high_reg1		; tmp2_high = ACC high  
  		SACL	tmp2_low_reg1		; tmp2_low = ACC low
DONE_REG1	

; tmp2 + tmp1 = tmp3  => Q31 + Q31 = Q15
		LACC	tmp1_high_reg1,16  	; ACC high = tmp1_high			(Q31)
   		ADDS	tmp1_low_reg1		; ACC low = tmp1_low            (Q31)
		ADDS	tmp2_low_reg1		; ACC = tmp1_low+tmp2_low       (Q31)
		ADDH 	tmp2_high_reg1		; ACC = tmp1_high+tmp2_high     (Q31)
		SACH	tmp3_reg1			; tmp3 = tmp1_high+tmp1_high    (Q15) 

; u(k) = u(k-1) + tmp3  =>  Q15 = Q15 + Q15 
		LACC	pid_out1_reg1,16	; ACC = u(k-1)						(Q15)
		ADD		tmp3_reg1,16		; ACC = u(k-1)+K0*e(k)-K1*e(k-1)+K2*e(k-2)  (Q15)
		SACH	pid_out_reg1	    ; u(k) = u(k-1)+K0*e(k)-K1*e(k-1)+K2*e(k-2)  (Q15)

; If u(k) > u_max, u(k) = u_max. If u(k) < u_min, u(k) = u_min.  
		LACC 	pid_out_reg1		; ACC = u(k)						(Q15)
        SUB		#PID_OUT_MAX_		; ACC = u(k)-u_max					(Q15)
        BCND	SAT_MAX,GT			; Branch if saturated at max
        LACC  	pid_out_reg1		; ACC = u(k)						(Q15)
        SUB		#PID_OUT_MIN_		; ACC = u(k)-u_min					(Q15)
        BCND	SAT_MIN,LT			; Brnch if saturated at min
		B		REG1_END
SAT_MIN
        SPLK	#PID_OUT_MIN_,pid_out_reg1	; u(k) = u_min             (Q15)
   		B		REG1_END
SAT_MAX        
        SPLK    #PID_OUT_MAX_,pid_out_reg1	; u(k) = u_max             (Q15)
REG1_END 
; Updating the errors e(k-1), e(k-2) and output u(k-1)		
		LACC	pid_e1_reg1			; ACC = e(k-1)                 		(Q15)
		SACL	pid_e2_reg1	        ; e(k-2) = e(k-1)                   (Q15)
		LACC	pid_e0_reg1			; ACC = e(k)                 		(Q15)
		SACL	pid_e1_reg1	        ; e(k-1) = e(k)        			 	(Q15)				
        LACC	pid_out_reg1		; ACC = u(k)                 		(Q15)
		SACL	pid_out1_reg1	    ; u(k-1) = u(k)                     (Q15)
	
		CLRC    SXM
		
		RET





⌨️ 快捷键说明

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