2021-03-20 03:58 PM
I am working with the STM32F769 microcontroller and I want to generate a pulse on PE14 that is "a few" milliseconds wide. My SystemCoreClock is 216 MHz and my timer, TIM1, is hooked up to the APB2-bus, which is clocked at 108 MHz. My code looks like this:
GPIO_InitTypeDef GPIO_InitStruct_TIM1_CH4 = {GPIO_PIN_14, GPIO_MODE_AF_PP, GPIO_NOPULL, GPIO_SPEED_FREQ_LOW, GPIO_AF1_TIM1};
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct_TIM1_CH4);
TIM_HandleTypeDef htim1;
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
htim1.Instance = TIM1;
htim1.Init.Prescaler = 4;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 65535;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_OnePulse_Init(&htim1, TIM_OPMODE_SINGLE) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 65535;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
{
Error_Handler();
}
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_4); // Start outputting the pulse
while ((TIM1->SR & TIM_SR_CC4IF) == 0) {} // Wait for CC4IF interrupt flag to be set
When I look on the oscilloscope, I see a pulse that is 1.524 ms wide. This doesn't make sense to me, it would mean TIM1 is incremented at a rate of roughly 42 MHz. Instead I would expect TIM1 to be incremented at a rate of 108/4 = 27 MHz. What am I doing wrong?
2021-03-21 02:26 AM
I found the problems:
1. TIM1 is not clocked at 108 MHz but rather 216 MHz.
2. The prescaler specified in STM32CubeMX is not translated into a user-friendly format, which I would expect from a GUI interface. Instead, the value that is specified in STM32CubeMX is exactly the same value that will go into the TIM1->PSC register. I chose 4 in STM32CubeMX because I thought that would divide the frequency by 4, but it actually divides it by 5.
So it makes sense that I would end up with 216/5 = 43.2 MHz increment rate in TIM1.
2021-03-21 04:14 AM
A common mnemonic is to write 4-1 in the GUI if you want a prescaler of 4 etc..