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

📄 stm32f10x_svpwm_1shunt.c

📁 ARM_CORTEX-M3应用实例开发详解光盘
💻 C
📖 第 1 页 / 共 5 页
字号:
#endif

  TIM1_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; 
  TIM1_OCInitStructure.TIM_OCNIdleState = LOW_SIDE_POLARITY;  //是否正确,应该用高电位吗?        
  
  TIM_OC1Init(TIM1, &TIM1_OCInitStructure); 
  TIM_OC3Init(TIM1, &TIM1_OCInitStructure);
  TIM_OC2Init(TIM1, &TIM1_OCInitStructure);


//===================================================================
  /*Timer1 alternate function full remapping*/  
  GPIO_PinRemapConfig(GPIO_FullRemap_TIM1,ENABLE);  
  
  GPIO_StructInit(&GPIO_InitStructure);
  /* GPIOE Configuration: Channel 1, 1N, 2, 2N, 3, 3N and 4 Output */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11; 
                                
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOE, &GPIO_InitStructure); 
  
  GPIO_StructInit(&GPIO_InitStructure);
  /* GPIOE Configuration: Channel 1N, 2N, 3N */
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_12;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOE, &GPIO_InitStructure); 

    /* Lock GPIOE Pin9 and Pin11 Pin 13 (High sides) */
  GPIO_PinLockConfig(GPIOE, GPIO_Pin_9 | GPIO_Pin_11 | GPIO_Pin_13 );
  
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_15;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOE, &GPIO_InitStructure); 


// 设定TIM1_CH4的工作状态 为比较输出模式,触发AD转换。
  TIM_OCStructInit(&TIM1_OCInitStructure);
  /* Channel 4 Configuration in OC */
  TIM1_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;  //TIM1 脉冲宽度调制模式 2 TIM1_CCMR1
													  // 寄存器的4-6位。	
  TIM1_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; 
  TIM1_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;                  
  TIM1_OCInitStructure.TIM_Pulse = PWM_PERIOD - TMIN - TBEFORE; // 占空比 ,确定一个触发ADC检测电流
  																// 时机,可以调整电流取样时间。
  TIM1_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; 
  TIM1_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;         
  TIM1_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
  TIM1_OCInitStructure.TIM_OCNIdleState = LOW_SIDE_POLARITY;            
  
  TIM_OC4Init(TIM1, &TIM1_OCInitStructure);
  
  /* Enables the TIM1 Preload on CC1 Register */
  TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Disable);
  /* Enables the TIM1 Preload on CC2 Register */
  TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Disable);
  /* Enables the TIM1 Preload on CC3 Register */
  TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Disable);
  /* Enables the TIM1 Preload on CC4 Register */
  TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Disable);
  
  /* Automatic Output enable, Break, dead time and lock configuration*/
  TIM1_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
  TIM1_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
  TIM1_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1; 
  TIM1_BDTRInitStructure.TIM_DeadTime = DEADTIME;
  TIM1_BDTRInitStructure.TIM_Break = TIM_Break_Enable;	  //没有打开紧急停车功能
  														  //NVIC中断向量也要关闭	
  TIM1_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;
  TIM1_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Disable;

  TIM_BDTRConfig(TIM1, &TIM1_BDTRInitStructure);

  TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Update);
  
  // Clear Break Flag and enable interrupt
  TIM_ClearITPendingBit(TIM1, TIM_IT_Break);
  TIM_ITConfig(TIM1, TIM_IT_Break,ENABLE);
  
  /* TIM1 counter enable */
  TIM_Cmd(TIM1, ENABLE);
  
  // Disnable update interrupt
  TIM_ITConfig(TIM1, TIM_IT_Update, DISABLE);
  
  // Resynch to have the Update evend during Undeflow
  TIM_GenerateEvent(TIM1, TIM_EventSource_Update); //软件产生TIM 更新事件源 
  
  // Enable DMA event
  TIM_DMACmd(TIM1, TIM_DMA_CC1, DISABLE);	//TIM1 捕获/比较1的DMA源 
  TIM_DMACmd(TIM1, TIM_DMA_CC2, DISABLE);	//TIM1 捕获/比较2的DMA源 
  TIM_DMACmd(TIM1, TIM_DMA_CC3, DISABLE);  //TIM1 捕获/比较3的DMA源 
  TIM_DMACmd(TIM1, TIM_DMA_Update,ENABLE); //TIM1 更新 DMA源 
  
  TIM_DMAConfig(TIM1, TIM_DMABase_CCR1, TIM_DMABurstLength_4Bytes);	 //TIM1 CCR1 寄存器作为 DMA传输起始
  																	 //TIM1 DMA连续传送长度 4 字节
  // Sets the disable preload vars for CCMR
  hPreloadCCMR1Disable = TIM1->CCMR1 & 0x8F8F;
  hPreloadCCMR2Disable = TIM1->CCMR2 & 0x8F8F;
   
  /* ADC1 registers reset ----------------------------------------------------*/
  ADC_DeInit(ADC1);
  /* ADC1 registers reset ----------------------------------------------------*/
  ADC_DeInit(ADC2);
  
  /* Enable ADC1 */
  ADC_Cmd(ADC1, ENABLE);
  /* Enable ADC2 */
  ADC_Cmd(ADC2, ENABLE);
  
  /* ADC1 configuration ------------------------------------------------------*/
  ADC_StructInit(&ADC_InitStructure);
  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; // 工作在独立模式 
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;		 // 单次(单通道)模式
  ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; // 单次模式
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;  // 软件触发启动
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Left;	// 数据左对齐 
  ADC_InitStructure.ADC_NbrOfChannel = 1;  // 顺序进行规则转换的 ADC 通道的数目
  ADC_Init(ADC1, &ADC_InitStructure);	   // 上面的这些设置只是为了校准AD精度。
  
  /* ADC2 Configuration ------------------------------------------------------*/
  ADC_StructInit(&ADC_InitStructure);  
  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Left;
  ADC_InitStructure.ADC_NbrOfChannel = 1;
  ADC_Init(ADC2, &ADC_InitStructure);
  
  ADC_InjectedDiscModeCmd(ADC1,ENABLE);
  ADC_InjectedDiscModeCmd(ADC2,ENABLE);
  
  // Start calibration of ADC1
  ADC_StartCalibration(ADC1);
  // Start calibration of ADC2
  ADC_StartCalibration(ADC2);
  
  // Wait for the end of ADCs calibration 
  while (ADC_GetCalibrationStatus(ADC1) & ADC_GetCalibrationStatus(ADC2))
  {
  }
  
  SVPWM_1ShuntCurrentReadingCalibration();
    
  /* Configure one bit for preemption priority */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  
//  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 Update Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = TIM1_UP_PRE_EMPTION_PRIORITY;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = TIM1_UP_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);
  
  // Default value of DutyValues
  dvDutyValues.hTimeSmp1 = (PWM_PERIOD >> 1) - TBEFORE;
  dvDutyValues.hTimeSmp2 = (PWM_PERIOD >> 1) + TAFTER;
} 

/*******************************************************************************
* Function Name  : SVPWM_1ShuntCurrentReadingCalibration
* Description    : Store zero current converted values for current reading 
                   network offset compensation in case of 1 shunt resistors 
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void SVPWM_1ShuntCurrentReadingCalibration(void)
{
  static u16 bIndex;
  
  /* ADC1 Injected group of conversions end interrupt disabling */
  ADC_ITConfig(ADC1, ADC_IT_JEOC, DISABLE);
  
  hPhaseOffset=0;
  
  /* ADC1 Injected conversions trigger is given by software and enabled */ 
  ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_T1_TRGO); // 选择定时器 1 的 TRGO作为注入转换外部触发 
  ADC_ExternalTrigInjectedConvCmd(ADC1,ENABLE);  // 启动注入组转换功能
  
  /* ADC1 Injected conversions configuration */ 
  ADC_InjectedSequencerLengthConfig(ADC1,2);  // 设置注入组通道的转换数量 
  
  // 设置指定 ADC 的注入组通道,设置它们的转化顺序和采样时间,这里对B相电流采样2次。
  ADC_InjectedChannelConfig(ADC1, PHASE_B_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 Channel used for current reading are read 
     in order to get zero currents ADC values*/ 
  for(bIndex=0; bIndex <NB_CONVERSIONS; bIndex++)
  {
    while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_JEOC)) { }

  // 获得零电流的AD转换值,实际上是每次/8,共计16个数,最后是2倍的实际电流值。  
    hPhaseOffset += (ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_1)>>3);
            
    /* Clear the ADC1 JEOC pending flag */
    ADC_ClearFlag(ADC1, ADC_FLAG_JEOC);    
  }
  // 设置温度和直流母线电压转换,使用ADC2。
  SVPWM_InjectedConvConfig();  
}

/*******************************************************************************
* Function Name  : SVPWM_InjectedConvConfig
* Description    : This function configure ADC1 for 1 shunt current 
*                  reading and ADC2  temperature and voltage feedbcak after a 
*                  calibration, it also setup the DMA and the default value of the 
*                 variables after the start command
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void SVPWM_InjectedConvConfig(void)
{  
  /* ADC2 Injected conversions configuration */ 
  ADC_InjectedSequencerLengthConfig(ADC2,2);
  ADC_InjectedChannelConfig(ADC2, TEMP_FDBK_CHANNEL, 1,SAMPLING_TIME_CK);
  ADC_InjectedChannelConfig(ADC2, BUS_VOLT_FDBK_CHANNEL, 2,SAMPLING_TIME_CK);
  
  /* ADC2 Injected conversions trigger is TIM1 TRGO */ 
  ADC_ExternalTrigInjectedConvConfig(ADC2, ADC_ExternalTrigInjecConv_T1_TRGO);	 //选择定时器 1 的 TRGO作为注入转换外部触发 
  ADC_ExternalTrigInjectedConvCmd(ADC2,ENABLE);	  // 启动注入组转换功能
  
  /* Bus voltage protection initialization*/                            
  ADC_AnalogWatchdogCmd(ADC2,ADC_AnalogWatchdog_SingleInjecEnable);// 单个注入通道上设置模拟看门狗 
  ADC_AnalogWatchdogSingleChannelConfig(ADC2,BUS_VOLT_FDBK_CHANNEL);   // 设置模拟看门狗的 ADC 通道
  ADC_AnalogWatchdogThresholdsConfig(ADC2,OVERVOLTAGE_THRESHOLD>>3,0x00);// 设置模拟看门狗的高/低阈值 
  
  /* ADC1 Injected group of conversions end and Analog Watchdog interrupts
                                                                     enabling */
  ADC_ITConfig(ADC2, ADC_IT_AWD, ENABLE);
  ADC_ITConfig(ADC1, ADC_IT_JEOC, ENABLE);
  

  // Default value of DutyValues
  dvDutyValues.hTimeSmp1 = (PWM_PERIOD >> 1) - TBEFORE;
  dvDutyValues.hTimeSmp2 = (PWM_PERIOD >> 1) + TAFTER;
  
  // Default value of sampling point
  hCCDmaBuffCh4[0] = dvDutyValues.hTimeSmp2; // Second point 
  hCCDmaBuffCh4[1] = dvDutyValues.hTimeSmp2;
  hCCDmaBuffCh4[2] = dvDutyValues.hTimeSmp1; // First point
  hCCDmaBuffCh4[3] = dvDutyValues.hTimeSmp1;

  // Set TIM1 CCx start value
  TIM1->CCR1 = PWM_PERIOD >> 1;
  TIM1->CCR2 = PWM_PERIOD >> 1;
  TIM1->CCR3 = PWM_PERIOD >> 1;
  TIM1->CCR4 = (PWM_PERIOD >> 1) - TBEFORE;
  
  // Default Update DMA buffer Ch 1,2,3,4 after reset
  hCCRBuff[0] = PWM_PERIOD >> 1;
  hCCRBuff[1] = PWM_PERIOD >> 1;
  hCCRBuff[2] = PWM_PERIOD >> 1;
  hCCRBuff[3] = (PWM_PERIOD >> 1) - TBEFORE;
  
  TIM_DMACmd(TIM1, TIM_DMA_CC4, ENABLE);
  
  // After start value of DMA buffers
  hCCDmaBuffCh1[0] = PWM_PERIOD-HTMIN;
  hCCDmaBuffCh1[1] = PWM_PERIOD-HTMIN;
  hCCDmaBuffCh1[2] = PWM_PERIOD >> 1;
  hCCDmaBuffCh1[3] = PWM_PERIOD >> 1;
  
  hCCDmaBuffCh2[0] = PWM_PERIOD-HTMIN;
  hCCDmaBuffCh2[1] = PWM_PERIOD-HTMIN;
  hCCDmaBuffCh2[2] = PWM_PERIOD >> 1;
  hCCDmaBuffCh2[3] = PWM_PERIOD >> 1;
  
  hCCDmaBuffCh3[0] = PWM_PERIOD-HTMIN;
  hCCDmaBuffCh3[1] = PWM_PERIOD-HTMIN;
  hCCDmaBuffCh3[2] = PWM_PERIOD >> 1;
  hCCDmaBuffCh3[3] = PWM_PERIOD >> 1;
  
  // After start value of dvDutyValues
  dvDutyValues.hTimePhA = PWM_PERIOD >> 1;
  dvDutyValues.hTimePhB = PWM_PERIOD >> 1;
  dvDutyValues.hTimePhC = PWM_PERIOD >> 1;
  
  // Set the default previous value of Phase A,B,C current
  hCurrAOld=0;
  hCurrBOld=0;
  hCurrCOld=0;
  
  hDeltaA = 0;
  hDeltaB = 0;
  hDeltaC = 0;
  bReadDelta = 0;
  bStatorFluxPosOld = REGULAR;
  bStatorFluxPos = REGULAR;
}

/*******************************************************************************
* Function Name  : SVPWM_1ShuntCalcDutyCycles
* Description    :  Implementation of the single shunt algorithm to setup the 
TIM1 register and DMA buffers values for the next PWM period.
* Input          : Stat_Volt_alfa_beta
* Output         : None
* Return         : None
*******************************************************************************/
void SVPWM_1ShuntCalcDutyCycles (Volt_Components Stat_Volt_Input)
{
    s32 wX, wY, wZ, wUAlpha, wUBeta;
    s16 hDeltaDuty[2];
    u16 hDutyV[4]; // the 4th element is the swap tmp
    
/*******************************************************************************
* Function Name  : SVPWM_1ShuntGetDuty
* Description    : Computes the three duty cycle values corresponding to the input value
                        using space vector modulation techinque
* Input          : Stat_Volt_alfa_beta
* Output         : None
* Return         : None
*******************************************************************************/
    //SVPWM_1ShuntGetDuty(Stat_Volt_Input);
    wUAlpha = Stat_Volt_Input.qV_Component1 * T_SQRT3 ;
    wUBeta = -(Stat_Volt_Input.qV_Component2 * T);

⌨️ 快捷键说明

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