Measure signal frequency with STM32 using Timer Input Capture while controlling a servo via PWM.
This project demonstrates servo motor control using PWM and measures the frequency of an external signal using Input Capture mode on TIM4. The servo motor is controlled via two buttons with debounce handled by TIM3. The measured frequency is printed over UART2.
For PWM servo control and button debounce, refer to the previous project: Servo Motor Control Project
- Servo motor control using TIM2 PWM channel 1
- Pulse period: 20 ms
- Duty cycles for different positions:
- 0° → 1.5 ms
- 90° right → 2 ms
- 90° left → 1 ms
- Button debounce using TIM3 (1 ms interval)
- Input Capture on TIM4 to measure external signal frequency
- UART2 for frequency output
- Real-time frequency calculation:
- Measures the time difference between two rising edges
- Handles timer overflow
- Computes frequency as
freq = TIM_CLK / icDiff
- Servo motor connected to TIM2 Channel 1 (PWM output)
- Buttons connected to GPIO pins with pull-up resistors
- External signal for frequency measurement connected to TIM4 Channel 1 (input capture)
- UART2 for serial communication (115200 baud rate)
uint8_t captureIndex = 0;
uint32_t icValue1 = 0, icValue2 = 0, icDiff;
float freq = 0;
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM4 && htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
{
if(captureIndex == 0)
{
icValue1 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
captureIndex = 1;
}
else
{
icValue2 = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
if(icValue2 > icValue1)
icDiff = icValue2 - icValue1;
else
icDiff = (0xffff - icValue1) + icValue2 + 1;
freq = 800000 / icDiff;
captureIndex = 0;
}
}
}
captureIndex
tracks whether the first or second edge is captured.- Handles timer overflow if the second capture is smaller than the first.
- Frequency is computed using the timer clock (in this example, 800 kHz).
while (1)
{
printf("freq = %0.3f Hz\r\n", freq);
HAL_Delay(1000);
}
- Prints the measured frequency every second via UART2.
- TIM2: PWM output for servo motor
- TIM3: Base timer for button debounce (interrupt every 1 ms)
- TIM4: Input Capture to measure external signal frequency
-
USART2
- Baud rate: 115200
- 8-bit data, 1 stop bit, no parity
- This project builds upon the Servo Motor PWM Project
- Input Capture is useful for precise frequency measurement of digital signals
- Make sure to connect the servo motor and buttons as described in the previous project پ