Update
I checked the block diagram of the timer 3 again
It looks like there's no connection between channel 4 and the trigger input TRGI. Is this correct?
Can I use channel 4 for gated mode?
original question
I have the following signal with varying pulse width. (high)
I want to measure the pulse width with an STM32F030F4 (link removed due to reputation limit).
The signal is connected to Pin 14, PB1. I verified that the signal can be scoped directly at the pin of the µC, so it should be there. I want to use timer 3 because its channel 4 is connected to that pin.
Chapter 13.3.19 TIMx and external trigger synchronization of the reference manual describes a mode that's exactly what I'm looking for.
Slave mode: Gated mode
The counter can be enabled depending on the level of a selected input.
There's also an example for that:
A.8.13 Gated mode code example
/* (1) Configure channel 1 to detect low level on the TI1 input by writing CC1S = ‘01’, and configure the input filter duration by writing the IC1F[3:0] bits in the TIMx_CCMR1 register (if no filter is needed, keep IC1F=0000). */ /* (2) Select polarity by writing CC1P=1 in the TIMx_CCER register */ /* (3) Configure the timer in gated mode by writing SMS=101 Select TI1 as the trigger input source by writing TS=101 in the TIMx_SMCR register. */ /* (4) Set prescaler to 12000-1 in order to get an increment each 250us */ /* (5) Enable the counter by writing CEN=1 in the TIMx_CR1 register. */ TIMx->CCMR1 |= TIM_CCMR1_CC1S_0; /* (1)*/ TIMx->CCER |= TIM_CCER_CC1P; /* (2) */ TIMx->SMCR |= TIM_SMCR_SMS_2 | TIM_SMCR_SMS_0 | TIM_SMCR_TS_2 | TIM_SMCR_TS_0; /* (3) */ TIMx->PSC = 11999; /* (4) */ TIMx->CR1 |= TIM_CR1_CEN; /* (5) */
I tried to modify the example to my needs and it looks like that:
// based on example A.8.13 /* (1) Configure channel 4 to detect low level on the TI4 input * by writing CC4S = ‘01’, * and configure the input filter duration by writing the IC1F[3:0] * bits in the TIMx_CCMR1 register (if no filter is needed, * keep IC1F=0000). */ /* (2) Select polarity by writing CC4P=1 in the TIMx_CCER register */ /* (3) Configure the timer in gated mode by writing SMS=101 * Select TI1 as the trigger input source by writing TS=101 * in the TIMx_SMCR register. */ /* (4) Set prescaler to 12000-1 in order to get an increment each 250us */ /* (5) Enable the counter by writing CEN=1 in the TIMx_CR1 register. */ TIM3->CCMR2 |= TIM_CCMR2_CC4S_0; /* (1) */ TIM3->CCER |= TIM_CCER_CC4P; /* (2) */ TIM3->SMCR |= TIM_SMCR_SMS_2 | TIM_SMCR_SMS_0 | TIM_SMCR_TS_2 | TIM_SMCR_TS_0; /* (3) */ TIM3->PSC = 11999; /* (4) */ TIM3->CR1 |= TIM_CR1_CEN; /* (5) */ I would expect that the counter register of timer 3 TIM3->CNT changes over time as the pulses tickle in.
However, TIM3->CNT does not change at all.
Here's the configuration that I suspect to be erroneous
GPIO
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle) { GPIO_InitTypeDef GPIO_InitStruct; if(tim_baseHandle->Instance==TIM3) { /* USER CODE BEGIN TIM3_MspInit 0 */ /* USER CODE END TIM3_MspInit 0 */ /* Peripheral clock enable */ __TIM3_CLK_ENABLE(); /**TIM3 GPIO Configuration PB1 ------> TIM3_CH4 */ GPIO_InitStruct.Pin = GPIO_PIN_1; GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_LOW; GPIO_InitStruct.Alternate = GPIO_AF1_TIM3; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* USER CODE BEGIN TIM3_MspInit 1 */ /* USER CODE END TIM3_MspInit 1 */ } } timer
/* TIM3 init function */ void MX_TIM3_Init(void) { TIM_ClockConfigTypeDef sClockSourceConfig; TIM_SlaveConfigTypeDef sSlaveConfig; TIM_MasterConfigTypeDef sMasterConfig; TIM_IC_InitTypeDef sConfigIC; htim3.Instance = TIM3; htim3.Init.Prescaler = 0; htim3.Init.CounterMode = TIM_COUNTERMODE_UP; htim3.Init.Period = 0; htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; if (HAL_TIM_Base_Init(&htim3) != HAL_OK) { Error_Handler(); } sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK) { Error_Handler(); } if (HAL_TIM_IC_Init(&htim3) != HAL_OK) { Error_Handler(); } sSlaveConfig.SlaveMode = TIM_SLAVEMODE_GATED; sSlaveConfig.InputTrigger = TIM_TS_ITR0; if (HAL_TIM_SlaveConfigSynchronization(&htim3, &sSlaveConfig) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK) { Error_Handler(); } sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING; sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI; sConfigIC.ICPrescaler = TIM_ICPSC_DIV1; sConfigIC.ICFilter = 0; if (HAL_TIM_IC_ConfigChannel(&htim3, &sConfigIC, TIM_CHANNEL_4) != HAL_OK) { Error_Handler(); } } When debugging, I can see the configuration registers change and read/write their values, but the counter register is not increasing.


__TIM3_CLK_ENABLE();? \$\endgroup\$