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

📄 calcang.s

📁 dsPIC对于交流感应电机矢量控制的应用笔记的源代码(中文)
💻 S
字号:
;*******************************************************************
; Routines: CalcAng
;
;*******************************************************************

          .include "general.inc"
          .include "encoder.inc"

;*******************************************************************
; CalcAng
;  
;Description:        
;
; Angle scaling:  qMechAng = qKang * (POSCNT*4) / 2^Nang
;
; where qKang = (2^15)*(2^Nang)/CntsPerRev.
;
; The Nang scaling factor is picked to maximize precision without causing 
; qKang to overflow 1.15 format. To do this Nang must be small enough so that 
; 2^Nang < CntsPerRev but large enough to provide required precision.
;
; The Position POSCNT is multiplied by 2^M where M is chosen to be 2 so that
; the resulting Acc value of qKang*POSCNT*2^M can be shifted into the 1.15
; format by the SAR command. The requirement is that  
;         -8 <= 15-Nang-M<= +7
; An additional requirement is POSCNT*2^M < 2^15 not to overflow the 1.15
; requirement of the fractional multiply instruction. The 2^M factor is 
; explicity added and removed in the code using the lac and sac commands.
;
; If CntsPerRev satisfies the requirement 128 < CntsPerRev < 8192 then
; M can be = 2 and Nang has to satisfy the two requirements 
;         6 <= Nang <= 21 
;         2^Nang < CntsPerRev
; which combine to give 64 <= 2^Nang < CntsPerRev
;
; To calculate with DSP instr:
;        Accum = qKang * POSCNT  where both are treated as 1.15 format
;        then must /2^Nang and times 32768 to make 1.31 format in accum.
;        This step can be done using the shift value in SAR instr
;        hence use SAR on qKang*POSCNT using (Nang-15) shift value (neg->left)
;
;Functional prototype:
; 
; void CalcAng( void )
;
;On Entry:   EncoderParm structure must contain qKang
;
;On Exit:    EncoderParm will contain qMechAng
;
;Parameters: 
; Input arguments: None
;
; Return:
;   Void
;
; SFR Settings required:
;         CORCON.SATA  = 0
;         CORCON.IF    = 0
;
; Support routines required: None
;
; Local Stack usage: 0
;
; Registers modified: w4,w5,AccA
;
; Timing: 8 instruction cycles
;
;*******************************************************************
;
;=================== CODE =====================
          .section  .text

; Register usage for CalcAng

          .equ Work0W,  w4   ; Working register
          .equ PosW,    w5   ; current position: POSCNT


          .global   _CalcAng
          .global   CalcAng

_CalcAng:
CalcAng:
     ;; qMechAng = qKang * POSCNT / 2^Nang

 .ifdef SIMU
          mov.w     _uTestPos,PosW     ; encoder value  ??
 .else
          mov.w     POSCNT,PosW        ; encoder value
 .endif

     ;; Multiply POSCNT by 4  
          sl.w      PosW,#2,PosW

     ;; 4*POSCNT is an integer but as Q15 it = (4*POSCNT/2^15)

          mov.w     _EncoderParm+Encod_qKang,Work0W

          mpy       Work0W*PosW,A
          sac       A,#(Nang+2-15),Work0W         ; left shift by 15-Nang-2

     ;; qMechAng = qKang * Q15( POSCNT/2^Nang )
          mov.w     Work0W,_EncoderParm+Encod_qMechAng
          return

          .end

⌨️ 快捷键说明

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