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

📄 stm32f10x_hall.c

📁 ARM_CORTEX-M3应用实例开发详解光盘
💻 C
📖 第 1 页 / 共 2 页
字号:
* Returns  : Rotor mechanical frequency, with 0.1Hz resolution.
* Comments : Result is zero if speed is too low (glitches at start for instance)
*           Excessive speed (or high freq glitches will result in a pre-defined
*           value returned.
* Warning : Maximum expectable accuracy depends on CKTIM: 72MHz will give the
* 	    best results.
*******************************************************************************/
s16 HALL_GetSpeed ( void )
{ 
  s32 wAux;
  
  if( hRotorFreq_dpp == HALL_MAX_PSEUDO_SPEED)	//条件是:
  												//(PeriodMeasAux.wPeriod < (u32)SPEED_OVERFLOW )
  {
    return (HALL_MAX_SPEED);   //最高转速,
  }
  else
  {
    wAux = ((hRotorFreq_dpp* SAMPLING_FREQ * 10)/(65536*POLE_PAIR_NUM));
    return (s16)wAux;
  }
}

/*******************************************************************************
* ROUTINE Name : Hall_GetRotorFreq
*
* Description : This routine returns Rotor frequency with an unit that can be
*               directly integrated to get the speed in the field oriented
*               control loop.
*
* Input    : None
* Output   : None
* Returns  : Rotor mechanical frequency with rad/PWM period unit
*             (here 2*PI rad = 0xFFFF).
* Comments : Result is zero if speed is too low (glitches at start for instance)
*           Excessive speed (or high freq glitches will result in a pre-defined
*           value returned.
* Warning : Maximum expectable accuracy depends on CKTIM: 72MHz will give the
* 	    best results.
*******************************************************************************/
s16 HALL_GetRotorFreq ( void )
{
   PeriodMeas_s PeriodMeasAux;

   if ( DoRollingAverage)
   {
      PeriodMeasAux = GetAvrgHallPeriod();
   }
   else
   {  // Raw period
      PeriodMeasAux = GetLastHallPeriod();
   }

   if (HallTimeOut == TRUE)
   {
      hRotorFreq_dpp = 0;
   }
   else
   {
     if(PeriodMeasAux.bDirection != ERROR)
     //No errors have been detected during rotor speed information extrapolation          
     {
        if ( HALL_TIMER->PSC >= HALL_MAX_RATIO )/* At start-up or very low freq */
        {                           /* Based on current prescaler value only */
           hRotorFreq_dpp = 0;	   //马达启动或者转速非常低
        }
        else
        {							   //转速太低
           if( PeriodMeasAux.wPeriod > MAX_PERIOD) /* Speed is too low */
           {
              hRotorFreq_dpp = 0;
           }
           else
           {  /*Avoid u32 DIV Overflow*/
              if ( PeriodMeasAux.wPeriod > (u32)SPEED_OVERFLOW )  
              {
                if (HALL_GetCaptCounter()<2)// First capture must be discarded
                {
                  hRotorFreq_dpp=0;	 //第一次的计数器捕捉丢弃
                }										   //最高速			  //最低速
                else              //PSEUDO_FREQ_CONV  介于 SPEED_OVERFLOW和 MAX_PERIOD之间。  
                {
                   hRotorFreq_dpp = (s16)((u16) (PSEUDO_FREQ_CONV /
                                                          PeriodMeasAux.wPeriod));
                   hRotorFreq_dpp *= PeriodMeasAux.bDirection;               
                }
              }
              else	 // <=96000	 (PeriodMeasAux.wPeriod < (u32)SPEED_OVERFLOW )
              {
                hRotorFreq_dpp = HALL_MAX_PSEUDO_SPEED;	  //-32768 速度太高了
              }
           }
        }
     }          
   }

   return (hRotorFreq_dpp);
}


/*******************************************************************************
* ROUTINE Name : HALL_ClrTimeOut
*
* Description     : Clears the flag indicating that that informations are lost,
*                   or speed is decreasing sharply.
* Input           : None
* Output          : Clear HallTimeOut
* Return          : None
*******************************************************************************/
void HALL_ClrTimeOut(void)
{
   HallTimeOut = FALSE;
}


/*******************************************************************************
* ROUTINE Name : HALL_IsTimedOut
*
* Description     : This routine indicates to the upper layer SW that Hall 
*                   sensors information disappeared or timed out.
* Input           : None
* Output          : None
* Return          : boolean, TRUE in case of Time Out
* Note            : The time-out duration depends on timer pre-scaler,
*                   which is variable; the time-out will be higher at low speed.
*******************************************************************************/
bool HALL_IsTimedOut(void)
{
   return(HallTimeOut);
}


/*******************************************************************************
* ROUTINE Name : Hall_GetCaptCounter
*
* Description     : Gives the number of Hall sensors capture interrupts since last call
*                   of the HALL_ClrCaptCounter function.
* Input           : None
* Output          : None
* Return          : u16 integer (Roll-over is prevented in the input capture
*                   routine itself).
*******************************************************************************/
u16 HALL_GetCaptCounter(void)
{
   return(hCaptCounter);
}


/*******************************************************************************
* ROUTINE Name : HALL_ClrCaptCounter
*
* Description     : Clears the variable holding the number of capture events.
* Input           : None
* Output          : hCaptCounter is cleared.
* Return          : None
*******************************************************************************/
void HALL_ClrCaptCounter(void)
{
   hCaptCounter = 0;
}


/*******************************************************************************
* ROUTINE Name : GetLastHallPeriod
*
* Description     : returns the rotor pseudo-period based on last capture
* Input           : None
* Output          : None
* Return          : rotor pseudo-period, as a number of CKTIM periods
*******************************************************************************/
PeriodMeas_s GetLastHallPeriod(void)
{
      PeriodMeas_s PeriodMeasAux;
      u8 bLastSpeedFIFO_Index;

   // Store current index to prevent errors if Capture occurs during processing
   bLastSpeedFIFO_Index = bSpeedFIFO_Index;	//防止中断发生改变索引号

   // This is done assuming interval between captures is higher than time
   // to read the two values
   PeriodMeasAux.wPeriod = SensorPeriod[bLastSpeedFIFO_Index].hCapture;
   PeriodMeasAux.wPeriod *= (SensorPeriod[bLastSpeedFIFO_Index].hPrscReg + 1);
   
   PeriodMeasAux.bDirection = SensorPeriod[bLastSpeedFIFO_Index].bDirection;
   return (PeriodMeasAux);
}


/*******************************************************************************
* ROUTINE Name : GetAvrgHallPeriod
*
* Description    : returns the rotor pseudo-period based on 4 last captures
* Input          : None
* Output         : None
* Return         : averaged rotor pseudo-period, as a number of CKTIM periods
* Side effect: the very last period acquired may not be considered for the
* calculation if a capture occurs during averaging.
*******************************************************************************/
PeriodMeas_s GetAvrgHallPeriod(void)
{
    u32 wFreqBuffer, wAvrgBuffer, wIndex;
    PeriodMeas_s PeriodMeasAux;

  wAvrgBuffer = 0;

  for ( wIndex = 0; wIndex < HALL_SPEED_FIFO_SIZE; wIndex++ )
  {
     // Disable capture interrupts to have presc and capture of the same period
     HALL_TIMER->DIER &= ~TIM_IT_CC1; // NB:Std libray not used for perf issues
     
     wFreqBuffer = SensorPeriod[wIndex].hCapture;
     wFreqBuffer *= (SensorPeriod[wIndex].hPrscReg + 1);
     
     HALL_TIMER->DIER |= TIM_IT_CC1;   // NB:Std libray not used for perf issue
     wAvrgBuffer += wFreqBuffer;	// Sum the whole periods FIFO
     PeriodMeasAux.bDirection = SensorPeriod[wIndex].bDirection;
  }
  // Round to upper value
  wAvrgBuffer = (u32)(wAvrgBuffer + (HALL_SPEED_FIFO_SIZE/2)-1);  
  wAvrgBuffer /= HALL_SPEED_FIFO_SIZE;        // Average value	

  PeriodMeasAux.wPeriod = wAvrgBuffer;
  
  return (PeriodMeasAux);
}


/*******************************************************************************
* ROUTINE Name : HALL_StartHallFiltering
*
* Description : Set the flags to initiate hall speed values smoothing mechanism.
* Input       : None
* Output      : The result of the next capture will be copied in the whole array
*               to have 1st average = last value.
* Return      : None
* Note: The initialization of the FIFO used to do the averaging will be done
*       when the next input capture interrupt will occur.
*******************************************************************************/
void HALL_StartHallFiltering( void )
{
   InitRollingAverage = TRUE;
}

/*******************************************************************************
* ROUTINE Name : HALL_ReadHallState
*
* Description : Read the GPIO Input used for Hall sensor IC and return the state  
* Input       : None
* Output      : None
* Return      : STATE_X
*
*******************************************************************************/

u8 ReadHallState(void)
{
  u8 ReadValue;
#if defined(TIMER2_HANDLES_HALL)  
  
  ReadValue = (u8)(GPIO_ReadInputData(GPIOA)) & GPIO_MSK;
  
#elif defined(TIMER3_HANDLES_HALL)
  
  ReadValue = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0)<<2;
  ReadValue |= GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_6)<<1;
  ReadValue |= GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_7);

#elif defined(TIMER4_HANDLES_HALL)
  ReadValue = ((u8)(GPIO_ReadInputData(GPIOA))>>6) & GPIO_MSK;
#endif
  
  return(ReadValue);
}

/*******************************************************************************
* ROUTINE Name : HALL_GetElectricalAngle
*
* Description : Export the variable containing the latest angle updated by IC 
*               interrupt
* Input       : None
* Output      : None
* Return      : Electrical angle s16 format
*
*******************************************************************************/
s16 HALL_GetElectricalAngle(void)
{
  return(hElectrical_Angle);
}

/*******************************************************************************
* ROUTINE Name : HALL_IncElectricalAngle
*
* Description : Increment the variable containing the rotor position information.
*               This function is called at each FOC cycle for integrating 
*               the speed information
* Input       : None
* Output      : None
* Return      : Electrical angle s16 format
*
*******************************************************************************/
void HALL_IncElectricalAngle(void)
{ 
  static s16 hPrevRotorFreq;
 
  if (hRotorFreq_dpp != HALL_MAX_PSEUDO_SPEED)
  {
    hElectrical_Angle += hRotorFreq_dpp;
    hPrevRotorFreq = hRotorFreq_dpp;
  }
  else
  {
    hElectrical_Angle += hPrevRotorFreq;
  }
}

/*******************************************************************************
* ROUTINE Name : HALL_Init_Electrical_Angle
*
* Description : Read the logic level of the three Hall sensor and individuates   
*               this way the position of the rotor (+/- 30

⌨️ 快捷键说明

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