In the STM32MP157 I am trying to program an interrupt every 100 us using timer 14. It looks like the code generated is correct, but the result is not correct. It looks like the DiV4 has no effect. The timing is the same as no divide.
Looking at the clock in the MX Device Configuration Tool it says 204 to APB1 Timer Clocks (MHz).
To get to 10000 Hz I have to divide 204 MHz by 20400.
Fortunately there are a bunch of ways to do this. But on the first try I tried
Prescaler 51
Counter Period 100
Internal Clock Division Division by 4
The reason I did it this way is that I suspected 10000 Hz will be too fast and they will eventually go to 1000 Hz or something between 1000 Hz and 10000 Hz and it would be easy to change the counter period for the new value.
I saved it and generated new code.
static void MX_TIM14_Init(void)
{
/* USER CODE BEGIN TIM14_Init 0 */
/* USER CODE END TIM14_Init 0 */
TIM_OC_InitTypeDef sConfigOC = {0};
/* USER CODE BEGIN TIM14_Init 1 */
/* USER CODE END TIM14_Init 1 */
htim14.Instance = TIM14;
htim14.Init.Prescaler = 51;
htim14.Init.CounterMode = TIM_COUNTERMODE_UP;
htim14.Init.Period = 100;
htim14.Init.ClockDivision = TIM_CLOCKDIVISION_DIV4;
htim14.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if (HAL_TIM_Base_Init(&htim14) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_OC_Init(&htim14) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_TIMING;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_OC_ConfigChannel(&htim14, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM14_Init 2 */
/* USER CODE END TIM14_Init 2 */
}The generated code looks good.
The interrupt would toggle a GPIO and I can see the timing.
My USB logic Analyzer was set to sample at 25 Msamples/sec
And I was reading 25.72 and 25.76 microseconds (us) when I expected 100 us.
It was off by a factor of 4.
It made me think it was the divide by 4.
So I went back to MX Device Configuration Tool and changed the Divide by 4 to No Division.
The result was:
Prescaler 51
Counter Period 100
Internal Clock Division No Division
I saved and it generated the code
static void MX_TIM14_Init(void)
{
/* USER CODE BEGIN TIM14_Init 0 */
/* USER CODE END TIM14_Init 0 */
TIM_OC_InitTypeDef sConfigOC = {0};
/* USER CODE BEGIN TIM14_Init 1 */
/* USER CODE END TIM14_Init 1 */
htim14.Instance = TIM14;
htim14.Init.Prescaler = 51;
htim14.Init.CounterMode = TIM_COUNTERMODE_UP;
htim14.Init.Period = 100;
htim14.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim14.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if (HAL_TIM_Base_Init(&htim14) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_OC_Init(&htim14) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_TIMING;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_OC_ConfigChannel(&htim14, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM14_Init 2 */
/* USER CODE END TIM14_Init 2 */
}Looking at the logic analyzer I got the exact same result. An interrupt every 25.72 and 25.76 us, when it should have been 1/4 that.
Like I said there multiple ways to do this, so I changed the prescaler from 51 to 204.
Prescaler 204
Counter Period 100
Internal Clock Division No Division
Saved and generated new code.
static void MX_TIM14_Init(void)
{
/* USER CODE BEGIN TIM14_Init 0 */
/* USER CODE END TIM14_Init 0 */
TIM_OC_InitTypeDef sConfigOC = {0};
/* USER CODE BEGIN TIM14_Init 1 */
/* USER CODE END TIM14_Init 1 */
htim14.Instance = TIM14;
htim14.Init.Prescaler = 204;
htim14.Init.CounterMode = TIM_COUNTERMODE_UP;
htim14.Init.Period = 100;
htim14.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim14.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
if (HAL_TIM_Base_Init(&htim14) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_OC_Init(&htim14) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_TIMING;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_OC_ConfigChannel(&htim14, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM14_Init 2 */
/* USER CODE END TIM14_Init 2 */
}This time I got the interrupt every 101.48 to 101.52 us which I was expecting.
I have not dug into your code to find out why the Divide by 4 it is not working. I am just saying it is not working.
The about says I am running:
Version: 1.8.0
Build: 11526_20211125_0815 (UTC)

