本文分析STM32 FOC库R3_2_SetADCSampPointSectX函数。
R3_2_SetADCSampPointSectX用于确认ADC采样时刻。
3电阻电流采样以下图为例,电阻只能测量下管导通电流,理想电流采样点大概有如下图粉色方框的3个区域。AX、BY、CZ分别对应定时器1的通道1-3的互补PWM输出。波形图左侧起始对应定时器CNT=ARR。
图1
__weak uint16_t R3_2_SetADCSampPointSectX( PWMC_Handle_t * pHdl )
{
PWMC_R3_2_Handle_t * pHandle = ( PWMC_R3_2_Handle_t * )pHdl;
uint16_t hCntSmp;
uint16_t hDeltaDuty;
register uint16_t lowDuty = pHdl->lowDuty;
register uint16_t midDuty = pHdl->midDuty;
/* Check if sampling AB in the middle of PWM is possible */
if ( ( uint16_t )( pHandle->Half_PWMPeriod - lowDuty ) > pHandle->pParams_str->hTafter )
{
/* When it is possible to sample in the middle of the PWM period, always sample the same phases
* (AB are chosen) for all sectors in order to not induce current discontinuities when there are differences
* between offsets */
/* sector number needed by GetPhaseCurrent, phase A and B are sampled wIch corresponds
* to sector 4 */
pHandle->_Super.Sector = SECTOR_4;
/* set sampling point trigger in the middle of PWM period */
hCntSmp = ( uint32_t )( pHandle->Half_PWMPeriod ) - 1u;
}
else
{ // lowDuty + pHandle->pParams_str->hTafter >= pHandle->Half_PWMPeriod
/* ADC Injected sequence configuration. The stator phase with minimum value of complementary
duty cycle is set as first. In every sector there is always one phase with maximum complementary duty,
one with minimum complementary duty and one with variable complementary duty. In this case, phases
with variable complementary duty and with maximum duty are converted and the first will be always
the phase with variable complementary duty cycle */
/* Crossing Point Searching */
hDeltaDuty = ( uint16_t )( lowDuty - midDuty );
/* Definition of crossing point */
if ( hDeltaDuty > ( uint16_t )( pHandle->Half_PWMPeriod - lowDuty ) * 2u )
{
/* hTbefore = 2*Ts + Tc, where Ts = Sampling time of ADC, Tc = Conversion Time of ADC */
hCntSmp = lowDuty - pHandle->pParams_str->hTbefore;
}
else
{
/* hTafter = DT + max(Trise, Tnoise) */
hCntSmp = lowDuty + pHandle->pParams_str->hTafter;
if ( hCntSmp >= pHandle->Half_PWMPeriod )
{
/* It must be changed the trigger direction from positive to negative
to sample after middle of PWM*/
pHandle->ADCTriggerEdge = LL_ADC_INJ_TRIG_EXT_FALLING;
hCntSmp = ( 2u * pHandle->Half_PWMPeriod ) - hCntSmp - 1u;
}
}
}
return R3_2_WriteTIMRegisters( &pHandle->_Super, hCntSmp );
}
函数用到两个关键参数pHandle->pParams_str->hTafter、pHandle->pParams_str->hTbefore,它们定义如下图
图2
图3
hTafter定义为PWM死区时间+MOS管开关引起的电流振铃时间。每次开关管动作后需要经过hTafter时间后才能触发ADC电流采样。
hTbefore定义为ADC触发延迟+ADC采样保持时间。触发电流采样的时刻到MOS管动作之间时间不能小于hTbefore。
hTafter、hTbefore时间单位为定时器时钟个数。
TW_BEFORE = (ADC_TRIG_CONV_LATENCY_CYCLES + ADC_SAMPLING_CYCLES) * ADV_TIM_CLK_MHz) / ADC_CLK_MHz + 1
= (3 + 28) * 168 / 21 + 1 = 249
TW_AFTER = ((DEADTIME_NS+MAX_TNTR_NS)*ADV_TIM_CLK_MHz)/1000ul)
= (800 + 2550) * 168 / 1000 = 563
hTafter大于hTbefore。
区域1
图1中区域1对应代码如下:
图4
如下图1起始对应ABC三项最后一个下桥臂MOS管打开。从1起始延时Tafter定时器CNT增计数还没有到ARR,这种情况就可以把电流采样ADC触发时刻定位hCntSmp = ( uint32_t )( pHandle->Half_PWMPeriod ) - 1u,此时ABC三项的都是下桥臂MOS管打开,3项电流采样电阻都符合采样条件,STM32F407只有两个ADC,所以只能同时采样两路,这里决定将扇区确定为4,同时采样AB。总是采样相同的相位(选择AB),以便在存在差异时不会引起电流不连续。
图5
区域2
图1中区域2对应代码如下:
图6
区域2对应图5,2 > 1, ADC触发采样时刻取CCR4=CCRmax - hTbefore, 对应程序中hCntSmp = lowDuty - pHandle->pParams_str->hTbefore;
区域3
图1中区域3对应代码如下:
区域3对应1<=2*hTafter且2 <= 1,取电流采样时刻CCR4=2*ARR - (CCRmax+hTbefore),同时区域3对应通道4的下降沿,所以ADC修改为下降沿触发。
即hCntSmp = ( 2u * pHandle->Half_PWMPeriod ) - hCntSmp - 1u;粉色方框中 if (hCntSmp >= pHandle->Half_PWMPeriod )恒为真。