STM32のタイマーは、システムやウォッチドッグなどの特殊なものを除くと、モーター向けオプションのあるアドバンスタイマー(TMR1,TMR8)、入出力を持たない基本タイマー(TMR6,TMR7)、PWM出力もできる汎用タイマー(16bit:TMR3,TMR4 / 32bit:TMR2,TMR5)が汎用タイマーとして利用できます(モデルにより未対応や追加もあり)。

タイマーはクロックソースをPrescalerで分割した単位でカウントしていき、この値が設定したPeriodに達するとタイマーイベントを発生させます。

クロックソースの周波数は基本的にAPB1の値(TIM1,8,9,10はAPB2)が適用されます。
このクロックはSPIやI2Sなどのソースにも適用されるため、これらの機能も使いたい場合はそれらを考慮した周波数を設定しなくてはいけません。

(Prescaler + 1)*(Period)=Clockの式が成り立つとき、イベント発生の周期は1秒ごととなります。つまり、APB1が40MHzであれば、Prescaler=19999、Period=1999で値が一致するので、1秒ごとのイベント発生が行えるようになります。また、このPeriod+1の値を半分(Period=999)にすると、カウンタが到達するまでの時間が半分になるため、結果として0.5秒周期のイベント発生になります。
タイマー割り込みコードはNVIC設定で割り込みにチェックを入れることで「Src/stm32f4xx_it.c」に追加されます。
void TIM2_IRQHandler(void)
{
  /* USER CODE BEGIN TIM2_IRQn 0 */
  HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);

  /* USER CODE END TIM2_IRQn 0 */
  HAL_TIM_IRQHandler(&htim2);
  /* USER CODE BEGIN TIM2_IRQn 1 */

  /* USER CODE END TIM2_IRQn 1 */
}
割り込みの受付を始めるための命令をプログラム内に記述しないと、いつまでたっても割り込みが発生しないので、この点にも気をつけましょう。
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART2_UART_Init();
  MX_TIM2_Init();
  /* USER CODE BEGIN 2 */
  HAL_TIM_Base_Start_IT(&htim2);  // Begin timer(TMR2) interrupt
  /* USER CODE END 2 */