📄 stm32f10x_svpwm_ics.c
字号:
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 + -