This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/TMS320F28035: HFI frequency

Part Number: TMS320F28035

Tool/software: Code Composer Studio

Hi , Yanming Luo :

    I try your suggestion of HFI frequency.  it seems work.  at build level 8 , I apply a constant voltage at q axis ,just like bulid level 2 , rotor spins at speed about 350rpm.

but rotor can't spin under current loop at build level 9 .  and i found out it needs low pass filter in other training video ( ) but I wonder what digital fitler algorithm is suitable.

Looking forward to your reply, thanks in advance.

  • HFI is only used for low speed and IPM motor. The motor speed maybe exceeds the transition value of HFI if motor spin under torque mode without load. The HFI includes some filters in the algorithm, it's not necessary to add any additional filter.
  • Thanks for your reply.  but I'm a little confused.

    In bulid 9 block diagram,  there is no filter block  in d and q axis current loop , shown as below

    In train video,  there is band filter block. shown as below

    signals after low pass filter go into d and q axis current regulator. signals after hign pass filter go into  HFI to get zero or low speed position information.  do you mean  we don't need to filter d&q axis current feedback for current regulator?

  • Right. It is included and implemented in hfi.lib, you don't need to add an additional filter in most case.
  • Thanks for your reply. but I can not find any code related to  low  pass  filter in example project , shown as below

    // =============================== LEVEL 9 ======================================
    //      Level 9 uses high frequency injection at lower speeds to identify
    //    rotor position, and uses eSMO discussed in LEVEL7 at higher speeds,
    //    providing speed control over the entire range
    // ==============================================================================
    //  lsw=0: controller in RESET state without powering the motor
    //  lsw=1: identify initial rotor position, change lsw to 2 if success else to 0
    //  lsw=2: motor runs in speed loop

        /*************************************************************************
         * NOTE:-                                                                *
         * The executable for Initial Position Detection (IPD) and               *
         * High Frequency Injection (HFI) are in hfi.lib file, which are not     *
         * part of the downloadable version of control suite.                    *
         * Any attempt to build LEVEL9 code will result in error.                *
         * For access to the library and/or source code, the user is advised     *
         * to contact the nearest TI sales office.                               *
         * ***********************************************************************
         */

    #if (BUILDLEVEL==LEVEL9)

    // ------------------------------------------------------------------------------
    //  Connect inputs of the RMP module and call the ramp control macro
    // ------------------------------------------------------------------------------
        if(lsw != RUN_STATE) {
            rc1.TargetValue = 0;
            rc1.SetpointValue = 0;
        }
        else
            rc1.TargetValue = SpeedRef;
        RC_MACRO(rc1)

    // ------------------------------------------------------------------------------
    //  Connect inputs of the RAMP GEN module and call the ramp generator macro
    // ------------------------------------------------------------------------------
        rg1.Freq = rc1.SetpointValue;
        RG_MACRO(rg1)
        ANGLE_WRAP(rg1.Out);

    // ------------------------------------------------------------------------------
    //    Connect inputs of the SPEED_EST module and call the estimated speed macro
    // ------------------------------------------------------------------------------
        transition1.spd      = rc1.SetpointValue;
        transition1.angleHFI = hfi1.thetaEst;
        transition1.angleSMO = esmo1.Theta;
        ANGLE_TRANSIT(&transition1);

        speed3.EstimatedTheta = transition1.angle;

        if (lsw != RUN_STATE)
            speed3.OldEstimatedTheta = speed3.EstimatedTheta;
        SE_MACRO(speed3)

    // ------------------------------------------------------------------------------
    //  Measure the DC bus voltage in _IQ format
    // ------------------------------------------------------------------------------
        volt1.DcBusVolt = _IQ12toIQ(AdcResult.ADCRESULT7);

    // ------------------------------------------------------------------------------
    //  Measure phase currents, subtract the offset and normalize from (-0.5,+0.5) to (-1,+1).
    //    Connect inputs of the CLARKE module and call the clarke transformation macro
    // ------------------------------------------------------------------------------
        clarke1.As = _IQmpy2(_IQ12toIQ(AdcResult.ADCRESULT1)-offsetA); // Phase A curr.
        clarke1.Bs = _IQmpy2(_IQ12toIQ(AdcResult.ADCRESULT2)-offsetB); // Phase B curr.
        CLARKE_MACRO(clarke1)
    //    clarke1.Cs = _IQmpy2(_IQ12toIQ(AdcResult.ADCRESULT3)-offsetC); // Phase C curr.
    //    CLARKE1_MACRO(clarke1)

    // ------------------------------------------------------------------------------
    //  Connect inputs of the PARK module and call the park trans. macro
    // ------------------------------------------------------------------------------
        park1.Alpha  = clarke1.Alpha;
        park1.Beta   = clarke1.Beta;
        park1.Angle  = speed3.EstimatedTheta;
        park1.Sine   = _IQsinPU(park1.Angle);
        park1.Cosine = _IQcosPU(park1.Angle);
        PARK_MACRO(park1)

        hpf_Iq.In1 = park1.Qs;

    // ------------------------------------------------------------------------------
    // State Machine for motor control
    // ------------------------------------------------------------------------------
        if(lsw == RESET_STATE)
        {
          // reset all PI regulators
          RESET_PI(pi_spd);
          RESET_PI(pi_id);
          RESET_PI(pi_iq);

          HFI_RESET(&hfi1);          // reset HFI module
          HPF_RESET(&hpf_Iq);        // reset HPF
          HPF_INIT(&hpf_coeff1);     // optional - to change HPF corner freq during debug

          dbc1.gain  = 0;
        }

        else if (lsw == IPD_STATE)
        {
          ZLSPD(&hpf_Iq, &hpf_coeff1, &hfi1, &ns_id1, &clarke1, &volt1);
          pi_id.Out = hfi1.duty;
          pi_iq.Out = 0;
          if(hfi1.HFI_Status == HFI_RUN_STATE)
          {
              lsw = RUN_STATE;
              pi_id.Out = 0;
          }
          else if(hfi1.HFI_Status == HFI_RESET_STATE)
          {
              lsw = RESET_STATE;
          }
        }

        else if (lsw == RUN_STATE)
        {
          // ------------------------------------------------------------------------------
          //    Connect inputs of the PI module and call the PID speed controller macro
          // ------------------------------------------------------------------------------
          if (++SpeedLoopCount >= SpeedLoopPrescaler)
          {
            pi_spd.Ref = rc1.SetpointValue;
            pi_spd.Fbk = speed3.EstimatedSpeed;
            PI_MACRO(pi_spd);
            SpeedLoopCount=0;
          }

          // ------------------------------------------------------------------------------
          //    Connect inputs of the PI module and call the PID IQ controller macro
          // ------------------------------------------------------------------------------
          pi_iq.Ref = pi_spd.Out;
          pi_iq.Fbk = park1.Qs;
          PI_MACRO(pi_iq);

          // ------------------------------------------------------------------------------
          //    Connect inputs of the PI module and call the PID ID controller macro
          // ------------------------------------------------------------------------------
          pi_id.Ref = 0;
          pi_id.Fbk = park1.Ds;
          PI_MACRO(pi_id);

          // Zero and low speed position detection
          if ( _IQabs(rc1.SetpointValue) <= transition1.spdHi )
          {
            ZLSPD(&hpf_Iq, &hpf_coeff1, &hfi1, &ns_id1, &clarke1, &volt1);
            pi_id.Out += hfi1.duty;
          }

    //      dbc1.gain  = _IQ(0.5);             // comment to tune in debug environment
        }

    // ------------------------------------------------------------------------------
    //  Connect inputs of the INV_PARK module and call the inverse park trans. macro
    // ------------------------------------------------------------------------------
        ipark1.Ds     = pi_id.Out;
        ipark1.Qs     = pi_iq.Out;
        ipark1.Sine   = park1.Sine;
        ipark1.Cosine = park1.Cosine;
        IPARK_MACRO(ipark1)

    // ------------------------------------------------------------------------------
    //    Connect inputs of the VOLT_CALC module and call the phase voltage macro
    // ------------------------------------------------------------------------------
    //    volt1.DcBusVolt = _IQ12toIQ(AdcResult.ADCRESULT7);
        volt1.MfuncV1 = svgen1.Ta;
        volt1.MfuncV2 = svgen1.Tb;
        volt1.MfuncV3 = svgen1.Tc;
        PHASEVOLT_MACRO(volt1)

    // ------------------------------------------------------------------------------
    //    Connect inputs of the eSMO_POS module and call the eSMO module
    // ------------------------------------------------------------------------------
        if ((lsw == RUN_STATE) && (esmo1.Kslide  < smoK_set))
          esmo1.Kslide += _IQ(0.00001);
        esmo1.Ialpha   = clarke1.Alpha;
        esmo1.Ibeta    = clarke1.Beta;
        esmo1.Valpha   = volt1.Valpha;
        esmo1.Vbeta    = volt1.Vbeta;
        esmo1.runSpeed = speed3.EstimatedSpeed;
        esmo1.cmdSpeed = rc1.SetpointValue;
        eSMO_MODULE(&esmo1);

        /********************************************************************
         * Supplemental filter to remove jitters from esmo estimated angle
         * ******************************************************************/
    //    esmo1.Theta = angleFilter(&pi_smo, &esmo1);  // Uncomment to include

    // ------------------------------------------------------------------------------
    //  Connect inputs of the SVGEN_DQ module and call the space-vector gen. macro
    // ------------------------------------------------------------------------------
        svgen1.Ualpha = ipark1.Alpha;
        svgen1.Ubeta  = ipark1.Beta;
        SVGENDQ_MACRO(svgen1)

    // ------------------------------------------------------------------------------
    //  Connect inputs of the PWM_DRV module and call the PWM signal generation macro
    // ------------------------------------------------------------------------------
        if (lsw != RUN_STATE)     dbc1.gain = 0;
    //    else          dbc1.gain = _IQ(0.5);         // comment line to tune in debug
        pwm1.MfuncC1 = svgen1.Ta;
        pwm1.MfuncC2 = svgen1.Tb;
        pwm1.MfuncC3 = svgen1.Tc;

        if (hfi1.HFI_Status != HFI_NSID_STATE)        // not NSID state
        {
            /**********************************************
             * PWM Gen w Dead Band Compensation Macro
             *     if curA > 0   Ta = Ta + Tdt
             *     else          Ta = Ta - Tdt
             **********************************************/
            dbc1.scale = _IQdiv(_IQdiv2(pwm1.Deadband), dbc1.Ith);  // uncomment to tune in debug
            dbc1.Kdtc  = _IQmpy(dbc1.scale, dbc1.gain);             // uncomment to tune  "  "
            PWMwDBC_MACRO(1,2,3,pwm1,clarke1,dbc1);
        }

    // ------------------------------------------------------------------------------
    //    Connect inputs of the PWMDAC module
    // ------------------------------------------------------------------------------
        pwmdac1.MfuncC1 = speed3.EstimatedTheta;
        pwmdac1.MfuncC2 = pi_id.Out;
        PWMDAC_MACRO(6,pwmdac1)                              // PWMDAC 6A, 6B

        pwmdac1.MfuncC1 = rg1.Out;
        pwmdac1.MfuncC2 = pi_iq.Out;
        PWMDAC_MACRO(7,pwmdac1)                              // PWMDAC 7A, 7B

    // ------------------------------------------------------------------------------
    //    Connect inputs of the DATALOG module
    // ------------------------------------------------------------------------------
        DlogCh1 = (int16)_IQtoIQ15(rg1.Out);
        DlogCh2 = (int16)_IQtoIQ15(clarke1.Bs);
        DlogCh3 = (int16)_IQtoIQ15(volt1.VphaseA);
        DlogCh4 = (int16)_IQtoIQ15(qep1.ElecTheta);

    #endif // (BUILDLEVEL==LEVEL9)

    as highlight part shows ,  d&q axis current feedback just come from signals after PARK transition, which is not filtered.

    and no low pass filter is mentioned in HFI library document.   the library version which I got from FAE  is V13.1 .  is it the latest version?

  • As replied to you, there is a high pass filter for Id and Iq to extract the HF component, and an optional low pass filter which is only used for speed estimation, both are defined and called in hfi.lib, not in the example project file.
    You could tune the HFP parameters as below in example project files, you can't change the filter parameters for speed in project files.
    // Initialize HPF parameters
    hpf_coeff1.freq = _IQ(18.0); // in Hz
    hpf_coeff1.PiT = _IQ(PI*T);
    HPF_INIT(&hpf_coeff1);

    Btw, we would like to close this thread since you created a new one about the same topic.