How to measure phase difference with STM32?
Hedy

Hedy @carolineee

About: Publish some interesting electronic articles

Joined:
Dec 18, 2023

How to measure phase difference with STM32?

Publish Date: Aug 1
0 0

Measuring phase difference between two signals (e.g., voltage and current) with an STM32 microcontroller involves capturing timing or zero-crossing events using its built-in peripherals like timers, ADCs, or comparators. Here’s a step-by-step guide:

Methods to Measure Phase Difference
1. Zero-Crossing Detection (Digital Input)
Principle: Measure time difference between zero-crossings of two signals.

Hardware Setup:

  • Condition signals to 0–3.3V (use op-amp comparators or Schmitt triggers).
  • Connect signals to GPIO pins (e.g., PA0, PA1) with interrupt support.

STM32 Peripherals:

  • TIM (Timer): Capture timestamps of zero-crossing edges.
  • EXTI (External Interrupt): Trigger on rising/falling edges.

Code Example (HAL Library)

c
// Configure GPIO and EXTI for zero-crossing detection
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
  static uint32_t time1, time2;
  if (GPIO_Pin == GPIO_PIN_0) { // Signal 1
    time1 = TIM2->CNT;
  } else if (GPIO_Pin == GPIO_PIN_1) { // Signal 2
    time2 = TIM2->CNT;
    uint32_t phase_diff = abs(time2 - time1); // Timer ticks
    float phase_deg = (phase_diff * 360.0) / TIM_PERIOD; // Convert to degrees
  }
}
Enter fullscreen mode Exit fullscreen mode

2. Analog Cross-Correlation (ADC + Timer)
Principle: Sample both signals with ADC and compute phase shift mathematically.

Hardware Setup:

  • Use dual ADC mode (STM32F3/F4/H7) or simultaneous sampling.
  • Feed signals to ADC channels (e.g., PA0, PA1).

Algorithm:

Apply cross-correlation or FFT to find time delay.

Code Example (Dual ADC)

c
// Configure ADC in dual mode
ADC_HandleTypeDef hadc1, hadc2;
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc1_buffer, BUFFER_SIZE);
HAL_ADC_Start_DMA(&hadc2, (uint32_t*)adc2_buffer, BUFFER_SIZE);

// Process buffers (e.g., find peak delay)
void Process_ADC_Data() {
  int max_corr = 0;
  int best_lag = 0;
  for (int lag = -BUFFER_SIZE/2; lag < BUFFER_SIZE/2; lag++) {
    int corr = 0;
    for (int i = 0; i < BUFFER_SIZE; i++) {
      if (i + lag >= 0 && i + lag < BUFFER_SIZE) {
        corr += adc1_buffer[i] * adc2_buffer[i + lag];
      }
    }
    if (corr > max_corr) {
      max_corr = corr;
      best_lag = lag;
    }
  }
  float phase_deg = (best_lag * 360.0) / BUFFER_SIZE;
}
Enter fullscreen mode Exit fullscreen mode

3. Timer Input Capture (High-Frequency Signals)
Principle: Use timer input capture to measure pulse timing.

Hardware Setup:

Connect signals to timer channels (e.g., TIM1_CH1, TIM2_CH2).

STM32 Peripherals:

Input Capture Mode: Records timestamps on rising/falling edges.

Code Example (PWM Phase Difference)

c
// Configure TIM1 in input capture mode
TIM_HandleTypeDef htim1;
HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_1); // Signal 1
HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_2); // Signal 2

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) {
  static uint32_t time1, time2;
  if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) {
    time1 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
  } else if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2) {
    time2 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2);
    uint32_t phase_diff = abs(time2 - time1);
    float phase_deg = (phase_diff * 360.0) / htim->Instance->ARR;
  }
}
Enter fullscreen mode Exit fullscreen mode

Key Considerations
1. Signal Conditioning:

  • For AC signals, use op-amp circuits to scale and clamp voltages.
  • Add low-pass filters to reduce noise.

2. Timer Resolution:

Higher timer clock = better accuracy (e.g., 72 MHz on STM32F4).

3. Frequency Range:

  • Zero-crossing: Best for 50/60 Hz power lines.
  • ADC + FFT: Suitable for higher frequencies (1 kHz–10 kHz).

4. STM32 Peripherals:

  • High-end models (H7): Use hardware accelerators (e.g., HRTIM, FD CAN) for precision.
  • Low-end models (F0): Rely on basic timers/ADC.

Example Calculation
If timer period = 1000 ticks and phase difference = 200 ticks:

Phase (degrees)=(200/1000)×360=72∘

Troubleshooting

  • Noisy Signals: Increase hysteresis in comparators or use software debouncing.
  • ADC Overflow: Adjust sampling rate or buffer size.
  • Timer Overflow: Use 32-bit timers (e.g., TIM2 on STM32F4) for long intervals.

Conclusion
For low-frequency signals (50/60 Hz), zero-crossing detection is simple and effective. For higher frequencies, use ADC + FFT or timer input capture. The STM32’s flexible peripherals make it ideal for precise phase measurements.

Comments 0 total

    Add comment