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

📄 stm32f10x_svpwm_ics.c

📁 ARM_CORTEX-M3应用实例开发详解光盘
💻 C
📖 第 1 页 / 共 2 页
字号:
  ADC_RegularChannelConfig(ADC2, POT1_VOLT_FDBK_CHANNEL,  1, ADC_SampleTime_239Cycles5); 
  /* ADC2 Regular Channel AIN0 */ 
  ADC_RegularChannelConfig(ADC2, AIN0_VOLT_FDBK_CHANNEL,  2, ADC_SampleTime_239Cycles5); 
   /* ADC1 Regular Channel AIN1 */ 
  ADC_RegularChannelConfig(ADC2, AIN1_VOLT_FDBK_CHANNEL,  3, ADC_SampleTime_239Cycles5); 

//=============================================================================

  /* Enable ADC1 */
  ADC_Cmd(ADC1, ENABLE);	 //唤醒ADC1

  ADC_TempSensorVrefintCmd(ENABLE);    // Chanel 16 = Temp On Chip

  //下面是校正ADC1和ADC2 
//==============================================================================
  /* Enable ADC1 reset calibaration register */   
  ADC_ResetCalibration(ADC1);
  
  /* Check the end of ADC1 reset calibration register */
  while(ADC_GetResetCalibrationStatus(ADC1));

  /* Start ADC1 calibaration */
  ADC_StartCalibration(ADC1);
  
  /* Check the end of ADC1 calibration */
  while(ADC_GetCalibrationStatus(ADC1));

 /* Enable ADC2 */
  ADC_Cmd(ADC2, ENABLE);   //唤醒ADC2

  /* Enable ADC2 reset calibaration register */   
  ADC_ResetCalibration(ADC2);
  
  /* Check the end of ADC2 reset calibration register */
  while(ADC_GetResetCalibrationStatus(ADC2));

  /* Start ADC2 calibaration */
  ADC_StartCalibration(ADC2);
  
  /* Check the end of ADC2 calibration */
  while(ADC_GetCalibrationStatus(ADC2));
 //================================================================================== 

  /* ADC1 Injected conversions configuration */ 
  ADC_InjectedSequencerLengthConfig(ADC1,2);
  SVPWM_IcsCurrentReadingCalibration();
    
  /* ADC2 Injected conversions configuration */ 
  ADC_InjectedSequencerLengthConfig(ADC2,2);

  ADC_InjectedChannelConfig(ADC2, PHASE_B_ADC_CHANNEL, 1, 
                                                      SAMPLING_TIME_CK);
  ADC_InjectedChannelConfig(ADC2, TEMP_FDBK_CHANNEL, 2,
                                                      SAMPLING_TIME_CK);
  
  ADC_ExternalTrigInjectedConvCmd(ADC2,ENABLE);

  
  /* Configure TWO bit for preemption priority */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	//4个抢先级、4个子优先级
  
//  NVIC_StructInit(&NVIC_InitStructure);
  /* Enable the ADC Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = ADC_PRE_EMPTION_PRIORITY;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = ADC_SUB_PRIORITY;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

  /* Enable the TIM1 BRK Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = TIM1_BRK_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = BRK_PRE_EMPTION_PRIORITY;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = BRK_SUB_PRIORITY;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;		//没有打开紧急停车功能
  NVIC_Init(&NVIC_InitStructure); 
    
  /* Enable the DMA_CHANEL1 Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = DMA_CH1_PRE_EMPTION_PRIORITY;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = DMA_CH1_SUB_PRIORITY;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

//  ADC_SoftwareStartConvCmd(ADC1, ENABLE);		  //首先软件触发规则组,连续扫描
  /* ADC1、ADC2 regular conversions trigger is TIM4_CC4*/ 
  ADC_ExternalTrigConvCmd(ADC1, ENABLE);
  ADC_ExternalTrigConvCmd(ADC2, ENABLE);

} 

/*******************************************************************************
* Function Name  : SVPWM_IcsCurrentReadingCalibration
* Description    : Store zero current converted values for current reading 
                   network offset compensation in case of Ics 
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/

void SVPWM_IcsCurrentReadingCalibration(void)
{
 static u8 bIndex;
   
  /* ADC1 Injected group of conversions end interrupt disabling */
  ADC_ITConfig(ADC1, ADC_IT_JEOC, DISABLE);
  
  hPhaseAOffset=0;
  hPhaseBOffset=0;
   
  /* ADC1 Injected conversions trigger is given by software and enabled */ 
  ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_None);  
  ADC_ExternalTrigInjectedConvCmd(ADC1,ENABLE); 
  
  /* ADC1 Injected conversions configuration */   
  ADC_InjectedChannelConfig(ADC1, PHASE_A_ADC_CHANNEL,1,SAMPLING_TIME_CK);
  ADC_InjectedChannelConfig(ADC1, PHASE_B_ADC_CHANNEL,2,SAMPLING_TIME_CK);
   
  /* Clear the ADC1 JEOC pending flag */
  ADC_ClearFlag(ADC1, ADC_FLAG_JEOC);   
  ADC_SoftwareStartInjectedConvCmd(ADC1,ENABLE);
  
  /* ADC Channel used for current reading are read 
     in order to get zero currents ADC values*/ 
  for(bIndex=NB_CONVERSIONS; bIndex !=0; bIndex--)
  {
    while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_JEOC)) { }

  //求Q1.15格式的零电流值,16个(零电流值/8)的累加,把最高符号位溢出。  
    hPhaseAOffset += (ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_1)
                                                         >>ADC_RIGHT_ALIGNMENT);
    hPhaseBOffset += (ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_2)
                                                         >>ADC_RIGHT_ALIGNMENT);  
    /* Clear the ADC1 JEOC pending flag */
    ADC_ClearFlag(ADC1, ADC_FLAG_JEOC); 	
    ADC_SoftwareStartInjectedConvCmd(ADC1,ENABLE);
  }
  
  SVPWM_IcsInjectedConvConfig();  
}


/*******************************************************************************
* Function Name  : SVPWM_IcsInjectedConvConfig
* Description    : This function configure ADC1 for ICS current 
*                  reading and temperature and voltage feedbcak after a 
*                  calibration of the utilized ADC Channels for current reading
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void SVPWM_IcsInjectedConvConfig(void)
{
  /* ADC1 Injected conversions configuration */ 
  ADC_InjectedChannelConfig(ADC1, PHASE_A_ADC_CHANNEL, 1, 
                                                      SAMPLING_TIME_CK);
  ADC_InjectedChannelConfig(ADC1, BUS_VOLT_FDBK_CHANNEL, 
                                                   2, SAMPLING_TIME_CK);
  
  /* ADC1 Injected conversions trigger is TIM1 TRGO */ 
  ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_T1_TRGO); 
  
  /* ADC1 Injected group of conversions end interrupt enabling */
  //  这里才能打开注入AD中断
  ADC_ITConfig(ADC1, ADC_IT_JEOC, ENABLE);
}

/*******************************************************************************
* Function Name  : SVPWM_IcsPhaseCurrentValues
* Description    : This function computes current values of Phase A and Phase B 
*                 in q1.15 format starting from values acquired from the A/D 
*                 Converter peripheral.
* Input          : None
* Output         : Stat_Curr_a_b
* Return         : None
*******************************************************************************/
Curr_Components SVPWM_IcsGetPhaseCurrentValues(void)
{
  Curr_Components Local_Stator_Currents;
  s32 wAux;

      
 // Ia = (hPhaseAOffset)-(PHASE_A_ADC_CHANNEL vale) 
 //零电流减去A/D转换的值去掉最高的符号位。得到Q1.15格式的电流值。 
  wAux = (s32)(hPhaseAOffset)-((ADC1->JDR1)<<1);          
 //Saturation of Ia 
  if (wAux < S16_MIN)
  {
    Local_Stator_Currents.qI_Component1= S16_MIN;
  }  
  else  if (wAux > S16_MAX)
        { 
          Local_Stator_Currents.qI_Component1= S16_MAX;
        }
        else
        {
          Local_Stator_Currents.qI_Component1= wAux;
        }
                     
 // Ib = (hPhaseBOffset)-(PHASE_B_ADC_CHANNEL value)
  wAux = (s32)(hPhaseBOffset)-((ADC2->JDR1)<<1);
 // Saturation of Ib
  if (wAux < S16_MIN)
  {
    Local_Stator_Currents.qI_Component2= S16_MIN;
  }  
  else  if (wAux > S16_MAX)
        { 
          Local_Stator_Currents.qI_Component2= S16_MAX;
        }
        else
        {
          Local_Stator_Currents.qI_Component2= wAux;
        }
  
  return(Local_Stator_Currents); 
}

/*******************************************************************************
* Function Name  : SVPWM_IcsCalcDutyCycles
* Description    : Computes duty cycle values corresponding to the input value
		   and configures 
* Input          : Stat_Volt_alfa_beta
* Output         : None
* Return         : None
*******************************************************************************/

void SVPWM_IcsCalcDutyCycles (Volt_Components Stat_Volt_Input)
{
   u8 bSector;
   s32 wX, wY, wZ, wUAlpha, wUBeta;
   u16  hTimePhA=0, hTimePhB=0, hTimePhC=0;		//下面是REV_CLARK变换过程
    
   wUAlpha = Stat_Volt_Input.qV_Component1 * T_SQRT3 ;
   wUBeta = -(Stat_Volt_Input.qV_Component2 * T);

   wX = wUBeta;
   wY = (wUBeta + wUAlpha)/2;
   wZ = (wUBeta - wUAlpha)/2;
									   //上面是REV_CLARK变换过程
  // Sector calculation from wX, wY, wZ	  //下面是查找定子电流的扇区号
   if (wY<0)
   {
      if (wZ<0)
      {
        bSector = SECTOR_5;
      }
      else // wZ >= 0
        if (wX<=0)
        {
          bSector = SECTOR_4;
        }
        else // wX > 0
        {
          bSector = SECTOR_3;
        }
   }
   else // wY > 0
   {
     if (wZ>=0)
     {
       bSector = SECTOR_2;
     }
     else // wZ < 0
       if (wX<=0)
       {  
         bSector = SECTOR_6;
       }
       else // wX > 0
       {
         bSector = SECTOR_1;
       }
    }							   //上面是查找定子电流的扇区号
   
   /* Duty cycles computation */
  
  switch(bSector)		  //根据所在扇区号,计算三相占空比
  {  
    case SECTOR_1:
    case SECTOR_4:
                hTimePhA = (T/8) + ((((T + wX) - wZ)/2)/131072);
		hTimePhB = hTimePhA + wZ/131072;
		hTimePhC = hTimePhB - wX/131072;                                       
                break;
    case SECTOR_2:
    case SECTOR_5:  
                hTimePhA = (T/8) + ((((T + wY) - wZ)/2)/131072);
        	hTimePhB = hTimePhA + wZ/131072;
		hTimePhC = hTimePhA - wY/131072;
                break;

    case SECTOR_3:
    case SECTOR_6:
                hTimePhA = (T/8) + ((((T - wX) + wY)/2)/131072);
		hTimePhC = hTimePhA - wY/131072;
		hTimePhB = hTimePhC + wX/131072;
                break;
    default:
		break;
   }
  
  /* Load compare registers values */
   
  TIM1->CCR1 = hTimePhA;
  TIM1->CCR2 = hTimePhB;
  TIM1->CCR3 = hTimePhC;
}

/*******************************************************************************
* Function Name  : SVPWMEOCEvent
* Description    :  Routine to be performed inside the end of conversion ISR
* Input           : None
* Output         : None
* Return         : None
*******************************************************************************/
u8 SVPWMEOCEvent(void)
{
  // Store the Bus Voltage and temperature sampled values
  h_ADCTemp = ADC_GetInjectedConversionValue(ADC2,ADC_InjectedChannel_2);
  h_ADCBusvolt = ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_2);
  return ((u8)(1));
}
#endif //ICS_SENSORS
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/  

⌨️ 快捷键说明

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