INPUT CAPTURE - FREQUENCY MEASUREMENT
Hello, STM32F407G DISC-1, STMCubeIDE
I configured timer3 for generating PWM signal which is 1kHz with %70 duty cycle. I connected its pin(PB4) to input capture channel(PA1). I use default HSI clock 16Mhz.
I can measure this PWM signal using logic analyzer. However, when I try to calculate its duty cycle with timer5 input capture mode, I always receive those values firstRise = 15559, secondRise = 31300. My expected value, difference of them should have been 100.Since one tick is 10us , and the period the PWM signal 1ms. 100 / 100000 = 1ms. What did I misunderstand? What might be the problem?
Thank you for your assistance..
Have a nice day.
#include <stdint.h>
#include "stm32f4xx.h"
#include <stdbool.h>
#include "gpio.h"
#include "utility.h"
#include "armcortexm4.h"
#include "timer.h"
volatile uint32_t firstRise, secondRise;
volatile bool captureDone = false;
void TIM5_IRQHandler(void)
{
if (TIMER5->TIMx_SR & (1 << 2)) // Check if capture event occurred
{
static bool flag = false;
if (!flag)
{
firstRise = TIMER5->TIMx_CCR2;
flag = true;
}
else
{
secondRise = TIMER5->TIMx_CCR2;
captureDone = true;
flag = false;
}
TIMER5->TIMx_SR &= ~(1 << 2); // Clear interrupt flag
}
}
int main(void)
{
GPIO_Handle_t PWM_TIMER3_CH1_PB4 = { .PORTNAME = GPIOB,
.PINCONF.PIN = GPIO_PIN_4,
.PINCONF.MODE = GPIO_MODE_ALTARNATE,
.PINCONF.OTYPE = GPIO_OTYPE_PP,
.PINCONF.OSPEED = GPIO_OSPEED_HIGH,
.PINCONF.PUPD = GPIO_PUPD_PU,
.PINCONF.AF = AF2
};
GPIO_Handle_t CCP_TIMER5_CH2_PA1 = { .PORTNAME = GPIOA,
.PINCONF.PIN = GPIO_PIN_1,
.PINCONF.MODE = GPIO_MODE_ALTARNATE,
.PINCONF.OTYPE = GPIO_OTYPE_PP,
.PINCONF.OSPEED = GPIO_OSPEED_HIGH,
.PINCONF.PUPD = GPIO_PUPD_PD ,
.PINCONF.AF = AF2
};
gpioInit(&PWM_TIMER3_CH1_PB4);
gpioInit(&CCP_TIMER5_CH2_PA1);
timerxConfig(TIMER3, 160 - 1, 100 - 1); // (100kHz) 10us counting, 1ms PWM period 1kHz PWM freq
timer3PwmEnable(DUTY_CYCLE_70);
timerxPeripheralEnable(TIMER3);
timerxConfig(TIMER5, 160 - 1, 0xFFFFFFFF);
timerxPeripheralEnable(TIMER5);
timer5InterruptEnable();
TIMER5->TIMx_CCER &= ~(1u << 4); // Disable capture on CH2
TIMER5->TIMx_CCMR1 |= (0b01 << 8); // TI2 capture input
TIMER5->TIMx_CCER &= ~(1u << 5); // Ensure CC2P = 0 (rising edge capture)
TIMER5->TIMx_CCER |= (1u << 4); //enable capture
while (1)
{
if (captureDone)
{
uint32_t periodTicks = secondRise - firstRise;
float periodMs = periodTicks * 10.0f / 1000.0f; // 10µs per tick (100kHz clock)
float frequency = 1.0 / periodMs;
captureDone = false; // Reset flag
// Debug: Print or check frequency
}
}
}
