AnsweredAssumed Answered

STM32L152ZE Timer pulse counter with "External clock source mode 1"

Question asked by kupchyk.daniil on Apr 11, 2018
Latest reply on Apr 12, 2018 by waclawek.jan

Good day Sirs, I have the following issue:

MCU: STM32L152ZE
Software library: Standart Peripherial Library (supporting old project)

I have need to count external pulses on PB3 input using TIM2 CH2.
Pulse train makes another timer using PWM, PB3 and PWM GPIO connected together, output signal checked with logic analyser - works.
According to "RM0038 Reference manual" the right way is to use timer in "External clock source mode 1".

Following instruction on page 397 - the upcounter have to count in response to a rising edge on the TI2
input:

1. Configure channel 2 to detect rising edges on the TI2 input by writing CC2S= ‘01 in the
TIMx_CCMR1 register.
2. Configure the input filter duration by writing the IC2F[3:0] bits in the TIMx_CCMR1
register (if no filter is needed, keep IC2F=0000).
Note: The capture prescaler is not used for triggering, so there’s no need to configure it.
3. Select rising edge polarity by writing CC2P=0 and CC2NP=0 in the TIMx_CCER
register.
4. Configure the timer in external clock mode 1 by writing SMS=111 in the TIMx_SMCR
register.
5. Select TI2 as the input source by writing TS=110 in the TIMx_SMCR register.
6. Enable the counter by writing CEN=1 in the TIMx_CR1 register.
When a rising edge occurs on TI2, the counter counts once and the TIF flag is set.
The delay between the rising edge on TI2 and the actual clock of the counter is due to the
resynchronization circuit on TI2 input.

Clear.

 

GPIO_InitTypeDef GPIO_InitStruct;

// [0] enable port clock
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);

// [1] config pin
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_Init(GPIOB, &GPIO_InitStruct);

GPIO_PinAFConfig( GPIOB, GPIO_PinSource3, GPIO_AF_TIM2 ); // routing signal from pin to tim2

// [2] enable tim2 clock
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

// [3] stop timer clock in debug (case of breakpoint)
DBGMCU_APB1PeriphConfig(DBGMCU_TIM2_STOP, ENABLE);


// [4] init a timer following instruction from reference manual:

uint16_t CCMR1 = 0;
uint16_t CCER = 0;
uint16_t SMCR = 0;
uint16_t CR1 = 0;

// CCMR1 Configure channel 2 to detect rising edges on the TI2 CC2S=01
CCMR1 |= TIM_CCMR1_CC2S_0;

// set input filter to IC2F=0x0F
//CCMR1 |= TIM_CCMR1_IC2F_0 | TIM_CCMR1_IC2F_1 | TIM_CCMR1_IC2F_2 | TIM_CCMR1_IC2F_3;

// set input filter to IC2F=0x00 nothing to do with IC2F
TIM2->CCMR1 = CCMR1;

// TIM_CCER_CC2P=0 and TIM_CCER_CC2NP = 0 so nothing to do
TIM2->CCER = CCER;

// Configure the timer in external clock mode 1 SMS=111
SMCR |= TIM_SMCR_SMS_0 | TIM_SMCR_SMS_1 |TIM_SMCR_SMS_2;

// Select TI2 as the input source TS=110
SMCR |= TIM_SMCR_TS_2 | TIM_SMCR_TS_1;

TIM2->SMCR = SMCR;

// set CNT=0 and ARR to MAX.
TIM2->CNT = 0;
TIM2->ARR = 0xFFFF;

// start timer
TIM2->CR1 = TIM_CR1_CEN;


if I make stop in the breakpoint after pulse train TIM2->CNT still 0;

The values of tim registers the same as set values.

What did I wrong with tim configuration?

Looking forward for any help.

Outcomes