Многие скажут не красиво так мигать светодиодом - во время HAL_Delay(500); микроконтроллер ничего не делает, не хорошо. Исправим сей недостаток - пусть мигает в прерывании, в это время (между прерываниями) можно делать много чего полезного. Заодно настроим остальные ноги микроконтроллера.

Увидим, что заняв ноги мы "убили" функции I2C и функции ног таймера 3. I2C нам не пригодится, а таймеров еще немеряно. Используем таймер 3 для прерываний - прерываться будем раз в 0.5 сек или 500 мс, чтоб инвертировать пин11. Настраиваем таймер:
/* TIM3 init function */
void MX_TIM3_Init(void)
{
  htim3.Instance = TIM3;
  htim3.Init.Prescaler = 48000-1; // делим 48МГц на 48000 получаем 1000 Гц или 1 мс
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP; // таймер считает вверх
  htim3.Init.Period = 500-1; // считать будет до 500, т.е. через 500 мс произойдет прерывание
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; // частоту входную не делим - нам хватает
  HAL_TIM_Base_Init(&htim3);
  /*##-2- Start the TIM Base generation in interrupt mode ####################*/
  /* Start Channel1 */
  HAL_TIM_Base_Start_IT(&htim3); // настраиваем прерывания таймера 3
}
Прерывание таймера:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_11);
}

Основной цикл пока пустой - там теперь можно решать супер-пупер задачи, а точечки будут независимо мигать.
Компилируем, запускаем - опять мигает. И не надо никаких протеусов - можем остановить выполнение программы в любой момент, посмотреть регистры и много много чего, "а впрочем, это уже совсем другая история".