Исправление:
Сводка:
Увеличьте приоритет SysTick_Handler
NVIC (уменьшив его числовое значение NVIC, которое имеет диапазон от 0 до 15).
Подробности:
То, что @P__J__ говорит в своем ответе здесь , верно, и я тоже подозреваю, что это ваша проблема.Чтобы исправить это, вам нужно, чтобы ваше прерывание SysTick имело приоритет NVIC (Nested Vectored Interrupt Controller) выше , чем любых других прерываний, которые делают вызовы HAL, которые могут зависеть от увеличения системного тика. Это включает в себя все вызовы HAL, которые имеют тайм-ауты, например, а также задержки HAL.Более высокий приоритет NVIC означает, что вы должны сделать его меньшим числовым значением, так как самый высокий приоритет NVIC равен 0, а самый низкий - 15 для чипов STM32 в конфигурации по умолчанию.
Чтобы установить приоритеты NVIC в STM32CubeMX 5, перейдите в Распиновка и Конфигурация -> Системное ядро -> (нажмите крошечную стрелку вверх / вниз, чтобы перейти на страницу с NVIC), затем нажмите NVIC-> Уменьшите значение «Приоритет выкупа», чтобы оно было ниже, чем (более высокий приоритет, чем) для любых других ISR, использующих вызовы HAL.
Вот снимок экрана.Обратите внимание, что вы также можете попасть на этот экран, нажав кнопку «Вид системы» рядом с «Видом распиновки», а затем нажав «NVIC» в разделе «Системное ядро».
Снимок экрана:
![enter image description here](https://i.stack.imgur.com/EBTBc.png)
Подробнее о HAL_IncTick();
:
Из файла "stm32f4xx_it.c" вы увидите, что SysTick_Handler
ISR вызывает HAL_IncTick();
:
/**
* @brief This function handles SysTick Handler.
* @param None
* @retval None
*/
void SysTick_Handler(void)
{
HAL_IncTick();
}
Если вы нажмете Ctrl + клик по нему (по крайней мере, в System Workbench / Eclipse), чтобы перейти к реализации HAL_IncTick()
, вы увидите следующее, которое предоставляетдополнительная информация в комментариях:
/**
* @brief This function is called to increment a global variable "uwTick"
* used as application time base.
* @note In the default implementation, this variable is incremented each 1ms
* in Systick ISR.
* @note This function is declared as __weak to be overwritten in case of other
* implementations in user file.
* @retval None
*/
__weak void HAL_IncTick(void)
{
uwTick++;
}
Эта HAL_IncTick()
функция находится внутри файла "... STM32Cube_FW_F4_V1.19.0 / Drivers / STM32F4xx_HAL_Driver / Src / stm32f4xx_hal.c", который также содержит HAL_InitTick()
функция чуть выше HAL_IncTick()
.Его комментарии очень проницательны:
/**
* @brief This function configures the source of the time base.
* The time source is configured to have 1ms time base with a dedicated
* Tick interrupt priority.
* @note This function is called automatically at the beginning of program after
* reset by HAL_Init() or at any time when clock is reconfigured by HAL_RCC_ClockConfig().
* @note In the default implementation, SysTick timer is the source of time base.
* It is used to generate interrupts at regular time intervals.
* Care must be taken if HAL_Delay() is called from a peripheral ISR process,
* The SysTick interrupt must have higher priority (numerically lower)
* than the peripheral interrupt. Otherwise the caller ISR process will be blocked.
* The function is declared as __weak to be overwritten in case of other
* implementation in user file.
* @param TickPriority Tick interrupt priority.
* @retval HAL status
*/
__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
{
/* Configure the SysTick to have interrupt in 1ms time basis*/
if (HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq)) > 0U)
{
return HAL_ERROR;
}
/* Configure the SysTick IRQ priority */
if (TickPriority < (1UL << __NVIC_PRIO_BITS))
{
HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U);
uwTickPrio = TickPriority;
}
else
{
return HAL_ERROR;
}
/* Return function status */
return HAL_OK;
}
Обратите особое внимание: часть, которая гласит:
Необходимо соблюдать осторожность, если HAL_Delay () вызывается из периферийного процесса ISR,
Прерывание SysTick должно иметь более высокий приоритет (численно ниже)
, чем периферийное прерывание.В противном случае процесс вызывающего абонента будет заблокирован.
Это именно то место, где я это узнал.
Обязательно прыгайте по коду и иногда просматривайте функции и документацию в самом исходном коде ST HAL, чтобы найти скрытое понимание, подобное этому.Сделайте это, конечно, в дополнение к ссылкам на следующие основные документы:
Ключевые документы STM32 для вашего чипа, в порядке приоритета (самый важный первый):
- Справочное руководство:RM0351
- Лист данных: DS10198
- UM1725 - Описание драйверов STM32F4 HAL и LL
- Руководство по программированию: PM0214
Эти и другие важные руководства можно легко найти на веб-сайте ST (https://www.st.com/en/microcontrollers/stm32l476vg.html), или, что еще удобнее: в STM32CubeMX через Справка -> Документы и ресурсы (ярлык: Alt + D ).