Wrong period values during motor startup.
I am making a BLDC motor controller using STM32G030C8t6. This microcontroller has a hall sensor sensing capability known as ‘Hall Sensor Mode / XOR Mode’. This generates an interrupt when any one of the three channels toggle. We are taking the timer period between this interrupts.
This period value is used for the calculation of SVPWM (Space Vector Pulse Width Modulation). Using this value, we are calculating the angle within sector. While debugging, we found that the motor vibrates slightly during the motor startup, So we are getting improper period values.

The blue line is the period value, and green is how it should have looked according to motor speed. As in this image, due to vibrations during the initial stage, we get multiple interrupts, this messing up the period values.
This is the part of code where we are measuring the period value.
// Function to measure the period of a hall sensor signal
void getMotorPostion(){
// Check if it's the first capture
if (0U == Motor.FirstCap) {
Motor.FirstCap++; // Increment the first capture flag
(void)LL_TIM_IC_GetCaptureCH1(TIM3); // Get the first capture value
} else {
// Get the current capture value
uint16_t CurrentVal = LL_TIM_IC_GetCaptureCH1(TIM3);
// Calculate and update the moving average speed
CalcMovingAvgSpeed(CurrentVal);
// Clip the current value to ensure it is within the specified range
if (CurrentVal < MIN_HALL_PERIOD) {
CurrentVal = MIN_HALL_PERIOD;
} else if (CurrentVal > MAX_HALL_PERIOD) {
CurrentVal = MAX_HALL_PERIOD;
}
// Update the Motor structure with the calculated period
Motor.Period = CurrentVal;
}
}
The following function shows the implementation of the SVPWM calculation.
// Function to execute SVPWM calculation at a frequency of 20 kHz
void Fastloop() {
// Increment the speed PI counter
motorVar.speedPI_counter++;
// Check if the counter has reached the maximum value
if (motorVar.speedPI_counter >= motorParam.speedPI_maxCounter) {
motorVar.speedPI_counter = 0; // Reset the counter
speedPI(); // Execute speed PI control
}
// Execute current PI control
currentPI();
// Calculate and update the moving average of the motor period
CalcMovingAvgPeriod(Motor.Period);
// Get the average period from the moving average filter
uint16_t AvgPeriod = movingAvgFilterPeriod.avg;
// Check if the average period is not zero to avoid division by zero
if (AvgPeriod != 0) {
// Calculate the phase increment based on the average period
Motor.phaseInc = ((long unsigned int)PHASE_INC_CALC / (unsigned int)(AvgPeriod));
}
// Update the motor phase by subtracting the phase increment
Motor.Phase = Motor.Phase - Motor.phaseInc;
// Execute Space Vector Modulation (SVM) with the current PI output and updated motor phase
SVMX(motorVar.currentPI_output, Motor.Phase);
}