User Tools

Site Tools

blog:2024-04-25_share_foc_mcsdk5.4.4_電流取樣



2024-04-25 Share: FOC控制庫MCSDK5.4.4梳理(2)-電流取樣

Local Backup

一、前言

  • 本文講解MCSDK中FOC控制的預備步驟-電流取樣,電流取樣的實作函數是R3_2_GetPhaseCurrents。 MCSDK中的電流取樣功能和上一篇文章SVPWM一樣,也是分扇區來進行電流取樣的,電流取樣涉及到R3_2_ParamsM1.ADCConfig1和R3_2_ParamsM1.ADCConfig2兩個陣列的配置,因此電流取樣部分也值得一說 UVW和ADC都是表示馬達的三個相序,只是說法不同

二、原始碼解析

1.電流取樣機制

  • 在FOC控制中,要求在同一時刻同時獲得UVW三相的電流,最理想的情況是一個引腳能同時復用成ADC1,ADC2和ADC3的通道,但這樣的引腳並不多,而且有些引腳會復用成其他功能,所以方法不可行。從上一章文章我們得知,三相電流的標量和為零,因此我們只需要在同一時刻讀取到其中兩相電流即可,基本上一個引腳可以同時復用成ADC1和ADC2,該方法可行這裡相電流取樣時,ADC要配置成注入轉換模式,注入轉換優先權比規則轉換優先權高。例如,當ADC同時滿足母線電壓取樣條件與相位電流取樣條件時,ADC會優先進行相電流取樣,完成後再進行相電壓取樣相電流取樣的觸發源配置為驅動SVPWM所使用的定時器的通道4,因此ADC取樣頻率為SVPWM的頻率,一般為10kHz到20kHz之間,即adc中斷頻率

  • 圖1 UVW三相電流與電角度關係

如圖1所示,在電角度從'π/3'到'π'的過程中,即扇區2和扇區3,U相和W相電流變化幅度最大且單調,幅度為3/2。同理,扇區4和扇區5,U相和V相電流變化幅度最大且單調,扇區6和扇區1,V相和W相電流變化幅度最大且單調。看下面ADC通道配置,處於磁區1時ADC1偵測V相電流,ADC2偵測W相電流,如我們預期的那樣,這就是這兩個ADC配置陣列的由來。

.ADCConfig1 = {   MC_ADC_CHANNEL_4<<ADC_JSQR_JSQ4_Pos    //V
                   ,MC_ADC_CHANNEL_5<<ADC_JSQR_JSQ4_Pos    //U
                   ,MC_ADC_CHANNEL_5<<ADC_JSQR_JSQ4_Pos    //U
                   ,MC_ADC_CHANNEL_5<<ADC_JSQR_JSQ4_Pos    //U
                   ,MC_ADC_CHANNEL_5<<ADC_JSQR_JSQ4_Pos    //U
                   ,MC_ADC_CHANNEL_4<<ADC_JSQR_JSQ4_Pos    //V
                  },

  .ADCConfig2 = {   MC_ADC_CHANNEL_3<<ADC_JSQR_JSQ4_Pos    //W
                   ,MC_ADC_CHANNEL_3<<ADC_JSQR_JSQ4_Pos    //W
                   ,MC_ADC_CHANNEL_3<<ADC_JSQR_JSQ4_Pos    //W
                   ,MC_ADC_CHANNEL_4<<ADC_JSQR_JSQ4_Pos    //V
                   ,MC_ADC_CHANNEL_4<<ADC_JSQR_JSQ4_Pos    //V
                   ,MC_ADC_CHANNEL_3<<ADC_JSQR_JSQ4_Pos    //W
                  },

2、電流取樣程式碼

  • void R3_2_GetPhaseCurrents( PWMC_Handle_t * pHdl, ab_t* pStator_Currents )
  • 函數入參是兩個指針,用於接收返回值:pHdl是FOC庫中的一個結構體,存儲了SVPWM佔空比和採樣電流等參數;pStator_Currents是存儲了UV兩相電流的結構體,用於後續FOC的計算
  • LL_TIM_CC_DisableChannel(TIMx, LL_TIM_CHANNEL_CH4);
  • 停用控制SVPWM定時器的4通道,防止再次觸發ADC取樣中斷,防止中斷嵌套的產生
  • bSector = pHandle->_Super.Sector;
    hReg1 = *pHandle->pParams_str->ADCDataReg1[bSector] * 2;
    hReg2 = *pHandle->pParams_str->ADCDataReg2[bSector] * 2;
  • 等同于
  • hReg1 = ADC1->JDR1 * 2;
    hReg2 = ADC2->JDR1 * 2;
  • 此處程式碼寫的有些多餘,目的就是將ADC1和ADC2的注入通道1的取樣值讀取出來。此處多說一些,程式碼中將ADC配置為左對齊模式。規則通道的有效位數是16位,因此ADC取樣值範圍是0-65535;而注入通道的有效位數是15位,最高位元以符號位存在,乘以2是將取樣值範圍擴大到0- 65535,方便歸一化計算。可以在ADC_JOFRx暫存器中配置ADC注入通道的偏移量,以此來改變JDRx暫存器的符號值
  • switch(bSector)
    {
        case SECTOR_6:
        case SECTOR_1:
          /* A相电流不可用     */
          /* B相电流 = B相零漂 - ADC采样值 */
          wAux = ( int32_t )( pHandle->PhaseBOffset ) - ( int32_t )( hReg1 );
          /* B相电流异常判断 */
          if ( wAux < -INT16_MAX )
          {
            pStator_Currents->b = -INT16_MAX;
          }
          else  if ( wAux > INT16_MAX )
          {
            pStator_Currents->b = INT16_MAX;
          }
          else
          {
            pStator_Currents->b = ( int16_t )wAux;
          }
    
          /* C相电流 = C相零漂 - ADC采样值 */
          /* A相电流 = -C相电流 -B相电流 */
          wAux = ( int32_t )( pHandle->PhaseCOffset ) - ( int32_t )( hReg2 );
          wAux = -wAux - ( int32_t )pStator_Currents->b;
    
          /* A相电流异常判断 */
          if ( wAux > INT16_MAX )
          {
            pStator_Currents->a = INT16_MAX;
          }
          else  if ( wAux < -INT16_MAX )
          {
            pStator_Currents->a = -INT16_MAX;
          }
          else
          {
            pStator_Currents->a = ( int16_t )wAux;
          }
          break;
    }
  • 從上一節我們得知,在磁區6和磁區1內,偵測的是V相和W相的電流,因此會有pHandle→PhaseBOffset - hReg1得到V相電流,會有pHandle→PhaseCOffset - hReg2得到W相電流,因為三相電流標量和等於零,所以再透過-wAux - pStator_Currents→b得到U相電流,如此得到AB(UV)兩相的電流值

3.電流取樣的觸發

  • 電流取樣的觸發是R3_2_TIMx_UP_IRQHandler,該函數在SVPWM的每個週期都會被呼叫一次,以下是該函數的實現
  • void * R3_2_TIMx_UP_IRQHandler( PWMC_R3_2_Handle_t * pHandle)
    {
      TIM_TypeDef* TIMx = pHandle->pParams_str->TIMx;
      ADC_TypeDef * ADCx_1 = pHandle->pParams_str->ADCx_1;
      ADC_TypeDef * ADCx_2 = pHandle->pParams_str->ADCx_2;
      uint32_t ADCInjFlags;
    
      /* ADC状态检测 LL_ADC_FLAG_JSTRT为通道开始标志 LL_ADC_FLAG_JEOS为通道转换结束标志*/
      ADCInjFlags = ADCx_1->SR & (LL_ADC_FLAG_JSTRT|LL_ADC_FLAG_JEOS);
      if ( ADCInjFlags == LL_ADC_FLAG_JSTRT )
      {
        /* ADC转换已开始,但未完成*/
        do
        {
          /* 等待转换结束  */
          ADCInjFlags = ADCx_1->SR & (LL_ADC_FLAG_JSTRT|LL_ADC_FLAG_JEOS);
        } 
        while ( ADCInjFlags != (LL_ADC_FLAG_JSTRT|LL_ADC_FLAG_JEOS) );
      }
      else if ( ADCInjFlags == 0 )
      {
        /* ADC转换未开始*/
        while ( ( TIMx->CNT ) < ( pHandle->pParams_str->Tw ) )
        {
          /* 等待一段时间,我配置的是3us */
        }
    
        ADCInjFlags = ADCx_1->SR & (LL_ADC_FLAG_JSTRT|LL_ADC_FLAG_JEOS);
        if ( ADCInjFlags == LL_ADC_FLAG_JSTRT )
        {
          /* ADC转换已开始,但未完成 */
          do
          {
            /* 等待转换结束 */
            ADCInjFlags = ADCx_1->SR & (LL_ADC_FLAG_JSTRT|LL_ADC_FLAG_JEOS);
          }
          while ( ADCInjFlags != (LL_ADC_FLAG_JSTRT|LL_ADC_FLAG_JEOS) );
        }
      }
      else
      {
        /* ADC转换已结束 */
      }
    
      /* 关闭ADC1和ADC2转换 */
      LL_ADC_INJ_StopConversionExtTrig(ADCx_1);
      LL_ADC_INJ_StopConversionExtTrig(ADCx_2);
    
      /* 根据扇区设置下一个电流转换通道  */
      ADCx_1->JSQR = pHandle->pParams_str->ADCConfig1[pHandle->_Super.Sector];
      ADCx_2->JSQR = pHandle->pParams_str->ADCConfig2[pHandle->_Super.Sector];
    
      /* 设置ADC1和ADC2触发源为内部 */
      LL_ADC_INJ_SetTriggerSource(ADCx_1,pHandle->ADC_ExternalTriggerInjected);
      LL_ADC_INJ_SetTriggerSource(ADCx_2,pHandle->ADC_ExternalTriggerInjected);
    
      /* 使能ADC触发源 */
      LL_TIM_CC_EnableChannel(TIMx, LL_TIM_CHANNEL_CH4);
      /* 开始转换 */
      LL_ADC_INJ_StartConversionExtTrig(ADCx_1, pHandle->ADCTriggerEdge);
      LL_ADC_INJ_StartConversionExtTrig(ADCx_2, pHandle->ADCTriggerEdge);
    
      return &( pHandle->_Super.Motor );
    }

三、結語

  • 調試過程中遇到過有些電機線序倒相的情況,需要根據電機改動ADCConfig1和ADCConfig2兩個數組,這個地方讓我困惑了很久,如今問題解決了,拿出來分享一下
  • 電流取樣還有UVW三相的零漂值沒有取樣沒有說,放到後面的狀態機部分一塊說

TAGS

  • 25 person(s) visited this page until now.

Permalink blog/2024-04-25_share_foc_mcsdk5.4.4_電流取樣.txt · Last modified: 2024/04/25 16:39 by jethro

oeffentlich