2018-01-19 02:23 AM
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.
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