cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 Delay timer issues

Alexander Hoffman
Associate III
Posted on January 19, 2018 at 11:23

Hi all,

I am trying to implement a milli and microsecond delay, most importantly a micro delay as milli is obviously provided by the HAL libraries. My knowledge of timers is quite limited so I might be missing some key concept here.

I have been having some success with getting a milli second timer going but a couple of things that seem to work have left me with some questions. I added a timer to my project through CubeMX.

0690X00000609MVQAY.png

My through process was to be able to change the clock prescalar to switch between micro and milli and then simply do a count compare in a while loop to perform the delay.

My default generated timer config code is as follows 

static void MX_TIM2_Init(void)

{

TIM_ClockConfigTypeDef sClockSourceConfig;

TIM_MasterConfigTypeDef sMasterConfig;

TIM_OC_InitTypeDef sConfigOC;

htim2.Instance = TIM2;

htim2.Init.Prescaler = ((SystemCoreClock/TIMER_PRESCALAR_US) / (SystemCoreClock/PCLK2_FREQ))-1;

htim2.Init.CounterMode = TIM_COUNTERMODE_UP;

htim2.Init.Period = 0xFFFFFFFF;

htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

if (HAL_TIM_Base_Init(&htim2) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}

sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;

if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}

if (HAL_TIM_OC_Init(&htim2) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}

sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;

sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}

sConfigOC.OCMode = TIM_OCMODE_TIMING;

sConfigOC.Pulse = 0;

sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

if (HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}

}

I then have two functions to set up the timer again into the milli and micro configs, as follows 

#define PCLK2_FREQ 90000000

void my_timer_config_us(void)

{

htim2.Instance = TIM2;

htim2.Init.Prescaler =

((SystemCoreClock/TIMER_PRESCALAR_US) / (SystemCoreClock/PCLK2_FREQ))-1;

htim2.Init.Period = UINT32_MAX;

htim2.Init.CounterMode = TIM_COUNTERMODE_UP;

htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

if (HAL_TIM_Base_Init(&htim2) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}

HAL_TIM_Base_Start(&htim2);

}

void my_timer_config_ms(void)

{

TIM_ClockConfigTypeDef sClockSourceConfig;

sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;

htim2.Instance = TIM2;

htim2.Init.Prescaler =

((SystemCoreClock/TIMER_PRESCALAR_MS) / (SystemCoreClock/PCLK2_FREQ))-1;

htim2.Init.Period = UINT32_MAX;

htim2.Init.CounterMode = TIM_COUNTERMODE_UP;

htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

if (HAL_TIM_Base_Init(&htim2) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}

HAL_TIM_Base_Start(&htim2);

}

I then use these config functions with the following functions to stop, modify and restart the timer.

void stahp_timerz(void)

{

HAL_TIM_Base_Stop(&htim2);

HAL_TIM_Base_DeInit(&htim2);

}

void Delay_ms(uint32_t mS)

{

my_timer_config_ms();

volatile uint32_t start_count = TIM2->CNT;

while(TIM2->CNT-start_count <= mS);

stahp_timerz();

}

void Delay_us(uint32_t uS)

{

my_timer_config_us();

volatile uint32_t start_count = TIM2->CNT;

while(TIM2->CNT-start_count <= uS);

stahp_timerz();

}

The micro second delay seems to work well but the micro does not work as expected. I also was getting weird results until I added the PCLK2_FREQ bit, but I was unable to get it from the system so I used a define. Any tips on how to get that from the system would be appreciated. 

By my reasoning the milli second delay should work with my 180Mhz sysclock if I set a prescalar of 180000 but it does weird things.

Any help would be very much appreciated.

Alex
0 REPLIES 0