if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) { Error_Handler(); } }
При этом проблема наблюдается только при использование PLL Source Mux. т.е. тактирования HSI RC -> System Clock Mux HSE -> System Clock Mux Работают нормально.... Настраиваю все через CubeMX Вот скриншоты рабочих настроек
Как только тактирование проходит через PLL Source Mux при вызове HAL_RCC_OscConfig(&RCC_OscInitStruct возвращается HAL_ERROR Опять же скрины настроек из CubeMX
И что то я совсем не понимаю в какую сторону дальше копать?
в 11 строке HAL_RCC_OscConfig(&RCC_OscInitStruct) возвращает HAL_ERROR Причем отладчиком до этой строки я дойти могу.... Ну а дальше попадаю в обработку ошибки и все на этом....
Почему так?
Добавлено after 2 hours 46 minutes 47 seconds: Ну и еще чуть глубокие капания функции HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) показали что ошибка формируется вот здесь
Код:
/* Do not return HAL_ERROR if request repeats the current configuration */ pll_config = RCC->CFGR; pll_config2 = RCC->CFGR2; if((READ_BIT(pll_config, RCC_CFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) || (READ_BIT(pll_config2, RCC_CFGR2_PREDIV) != RCC_OscInitStruct->PLL.PREDIV) || (READ_BIT(pll_config, RCC_CFGR_PLLMUL) != RCC_OscInitStruct->PLL.PLLMUL)) { return HAL_ERROR; }
и ошибка формируется потому что условие (READ_BIT(pll_config2, RCC_CFGR2_PREDIV) != RCC_OscInitStruct->PLL.PREDIV) true. остальные два false
В функции HAL_RCC_OscConfig должна быть запись регистра RCC->CFGR2 значением RCC_PREDIV_DIV1 (передается в функцию HAL_RCC_OscConfig в RCC_OscInitStruct->PLL.PREDIV)
срабатывает условие READ_BIT(pll_config, RCC_CFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource т.е. бит PLLSRC в регистре CFGR должен быть 1, а реально он 0. Получается что PLL тактируется от HSI а не HSE как в конфигурации. Ниже полный фрагмент кода инициализирующего PLL в функции HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
Собственно конфигурирование происходит в 32 строке вот так
Код:
/* Configure the main PLL clock source, predivider and multiplication factor. */ __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource, RCC_OscInitStruct->PLL.PREDIV, RCC_OscInitStruct->PLL.PLLMUL);
Но реально этого не происходит, потому что выше стоит условие (7 строка)
Код:
/* Check if the PLL is used as system clock or not */ if( __HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK)
т.е. если тактирование system clock от PLL, то его конфигурирование не выполняется..... В действиетельности так и есть. И вот теперь я совсем не понимаю как это работает... Причем эта проблема только в режиме отладки..... При простом запуске HAL_ERROR нет...
Спойлер
Код:
/*---------- PLL Configuration ----------*/ /* Check the parameters */ assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState)); if ((RCC_OscInitStruct->PLL.PLLState) != RCC_PLL_NONE) { /* Check if the PLL is used as system clock or not */ if( __HAL_RCC_GET_SYSCLK_SOURCE() != RCC_SYSCLKSOURCE_STATUS_PLLCLK) { if((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_ON) { /* Check the parameters */ assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource)); assert_param(IS_RCC_PLL_MUL(RCC_OscInitStruct->PLL.PLLMUL)); assert_param(IS_RCC_PREDIV(RCC_OscInitStruct->PLL.PREDIV));
/* Disable the main PLL. */ __HAL_RCC_PLL_DISABLE();
/* Configure the main PLL clock source, predivider and multiplication factor. */ __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource, RCC_OscInitStruct->PLL.PREDIV, RCC_OscInitStruct->PLL.PLLMUL); /* Enable the main PLL. */ __HAL_RCC_PLL_ENABLE();
/* Get Start Tick */ tickstart = HAL_GetTick();
/* Wait till PLL is ready */ while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET) { if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE) { return HAL_TIMEOUT; } } } else { /* Disable the main PLL. */ __HAL_RCC_PLL_DISABLE();
/* Get Start Tick */ tickstart = HAL_GetTick();
/* Wait till PLL is disabled */ while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET) { if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE) { return HAL_TIMEOUT; } } } } else { /* Check if there is a request to disable the PLL used as System clock source */ if((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_OFF) { return HAL_ERROR; } else { /* Do not return HAL_ERROR if request repeats the current configuration */ pll_config = RCC->CFGR; pll_config2 = RCC->CFGR2; if(( READ_BIT(pll_config, RCC_CFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) || (READ_BIT(pll_config2, RCC_CFGR2_PREDIV) != RCC_OscInitStruct->PLL.PREDIV) || (READ_BIT(pll_config, RCC_CFGR_PLLMUL) != RCC_OscInitStruct->PLL.PLLMUL)) { return HAL_ERROR; } } } }
HAl то еще маразм, ошибок море. Вы используете не последнею версию, может в последней устранили ошибку. Скорее всего время маленькое ожидания когда запуститься PLL или установиться кварц......нужно увеличивать .
Ну да, проще выставить в настройках код-генератор LL, всё будет понятнее. Но, мне кажется, возникающая у ТС ошибка связана скорее с использованием код-генератора, чем с HAL.
_________________ Относись к людям так, как хочешь, чтобы они относились к тебе.
Нет, чтобы включить HSE и PLL соответственно. Для себя у меня С++ код, но вам это сильно не понравится, поверьте. А для форума всё подробно на православном С.
Я бы тоже все на себя взял если бы мне показали картинку с надписями на асме, фиг знает что это, но очень страшно выглядит. Жутко охота разобратся, но не знаю с чего начать, вот у меня есть же иар и стмки я же могу попробовать освоить азы асма или совсем не подходит? И может есть хорошие статитьи или книга проверянная про асм для чайников?
Среднестатистическому программисту сейчас достаточно уметь читать ассемблерный код. IAR для этого, пожалуй, лучший инструмент. Ставите пару галок и изучаете что компилятор сделал из вашего кода. Ну и любое обучение в XXI веке начинается с изучения гугления.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 15
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения