Страница 1 из 1
Ошибка при настройки тактирования STM32F030
Добавлено: Ср янв 17, 2024 23:14:17
Foxhound
ДОброго времени суток!
Наткнулся на странную проблему при инициализации контроллера от внешнего кварцевого резонатора 8МГц.
В функции void SystemClock_Config(void) при вызове HAL_RCC_OscConfig(&RCC_OscInitStruct возвращается HAL_ERROR
Код: Выделить всё
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL4;
RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV1;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
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
И что то я совсем не понимаю в какую сторону дальше копать?
Re: Ошибка при настройки тактирования STM32F030
Добавлено: Пт янв 19, 2024 00:20:00
Foxhound
Немного подробностей..... Похоже проблема только в режиме отладки.....
Прицепил к контроллеру свотодиод и вот так им моргаю
Код: Выделить всё
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
while (1) {
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11, GPIO_PIN_SET);
HAL_Delay(5000);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11, GPIO_PIN_RESET);
HAL_Delay(5000);
}
}
При обоих схемах настроки тактирования (с PLL и без) все работает, т.е. светодиод мигает....
Но при попытке походить отладчиком по коду в случае без PLL все получается, а вот если спользовать PLL, то получаю ошибку HAL_ERROR.
Вот void SystemClock_Config(void) с которым под отладчиком все работает.....
Код: Выделить всё
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSE;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
}
А вот void SystemClock_Config(void) с которым под отладчиком все НЕ работает.....
Код: Выделить всё
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL2;
RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV1;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
}
в 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
Re: Ошибка при настройки тактирования STM32F030
Добавлено: Пт янв 19, 2024 07:07:09
bob1
В функции HAL_RCC_OscConfig должна быть запись регистра RCC->CFGR2 значением RCC_PREDIV_DIV1 (передается в функцию HAL_RCC_OscConfig в RCC_OscInitStruct->PLL.PREDIV)
Re: Ошибка при настройки тактирования STM32F030
Добавлено: Сб янв 20, 2024 10:57:51
Foxhound
В продолжение эпопеи..... В предыдущем сообщении был неправ относительно условия
HAL_ERROR возникает в блоке
Код: Выделить всё
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_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();
/* 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;
}
}
/* 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;
}
}
}
}
Re: Ошибка при настройки тактирования STM32F030
Добавлено: Сб янв 20, 2024 11:45:24
VladislavS
Вы прикалываетесь? Там два с половиной регистра надо записать чтобы тактирование настроить.
Re: Ошибка при настройки тактирования STM32F030
Добавлено: Сб янв 20, 2024 12:40:44
jcxz
[uquote="VladislavS",url="/forum/viewtopic.php?p=4532822#p4532822"]Вы прикалываетесь? Там два с половиной регистра надо записать чтобы тактирование настроить.[/uquote]Это для тех, кто не имеет кубо-зависимости - 2 регистра. не путайте.
Для кубо-зависимых - "целая эпопея".

Re: Ошибка при настройки тактирования STM32F030
Добавлено: Сб янв 20, 2024 20:38:03
VladislavS
[uquote="jcxz",url="/forum/viewtopic.php?p=4532849#p4532849"]2 регистра. не путайте.[/uquote]FLASH_ACR, RCC_CR два раза по четвертинке и RCC_CFGR два раза. Так что, тут как считать. Всего 2,5 регистра, но один два раза
Спойлер
Код: Выделить всё
FLASH->ACR = FLASH_ACR_PRFTBE | _VAL2FLD(FLASH_ACR_LATENCY,1); // Настройка тактов ожидания Flash
*((volatile uint8_t *)&RCC->CR+2) = RCC_CR_HSEON>>16; // Включить HSE
while(!(RCC->CR&RCC_CR_HSERDY)); // Жадать пока запустится HSE
const uint32_t cfgr = RCC_CFGR_PLLSRC_HSE_PREDIV // Конфигурация PLL и делителей
| RCC_CFGR_PLLMUL6
| RCC_CFGR_HPRE_DIV1
| RCC_CFGR_PPRE_DIV1
| RCC_CFGR_ADCPRE_DIV4
| RCC_CFGR_MCO_NOCLOCK ;
RCC->CFGR = cfgr | RCC_CFGR_SW_HSI;
*((volatile uint8_t *)&RCC->CR+3) = RCC_CR_PLLON>>24; // Включить PLL
while(!(RCC->CR&RCC_CR_PLLRDY)); // Жадать пока запустится PLL
RCC->CFGR = cfgr | RCC_CFGR_SW_PLL; // Переключиться на PLL
Re: Ошибка при настройки тактирования STM32F030
Добавлено: Сб янв 20, 2024 21:00:40
Нефертити
Вы так пишите, чтобы вопросы задавали?
Код: Выделить всё
*((volatile uint8_t *)&RCC->CR+2) = RCC_CR_HSEON>>16; // Включить HSE
*((volatile uint8_t *)&RCC->CR+3) = RCC_CR_PLLON>>24; // Включить PLL
Да, и неважно.
Re: Ошибка при настройки тактирования STM32F030
Добавлено: Сб янв 20, 2024 21:02:47
bob1
HAl то еще маразм, ошибок море. Вы используете не последнею версию, может в последней устранили ошибку.
Скорее всего время маленькое ожидания когда запуститься PLL или установиться кварц......нужно увеличивать

.
Re: Ошибка при настройки тактирования STM32F030
Добавлено: Сб янв 20, 2024 21:11:26
Нефертити
Ну да, проще выставить в настройках код-генератор LL, всё будет понятнее.
Но, мне кажется, возникающая у ТС ошибка связана скорее с использованием код-генератора, чем с HAL.
Re: Ошибка при настройки тактирования STM32F030
Добавлено: Сб янв 20, 2024 21:16:25
VladislavS
[uquote="Нефертити",url="/forum/viewtopic.php?p=4533053#p4533053"]Вы так пишите, чтобы вопросы задавали?[/uquote]Нет, чтобы включить HSE и PLL соответственно. Для себя у меня С++ код, но вам это сильно не понравится, поверьте. А для форума всё подробно на православном С.
Re: Ошибка при настройки тактирования STM32F030
Добавлено: Сб янв 20, 2024 21:20:12
Нефертити
Я верю, т.к. давно читаю форум.
Только, смысла не вижу в добавлении к исходному коду неподъёмного числа строк.
Re: Ошибка при настройки тактирования STM32F030
Добавлено: Пн янв 22, 2024 07:49:01
VladislavS
А не могли бы показать, как вы бы написали "подъёмный вариант"?
Re: Ошибка при настройки тактирования STM32F030
Добавлено: Вт янв 23, 2024 19:45:40
Нефертити
Могу.
Взять Ваш вариант c регистрами, только:
заменить на
Ваш вариант неверен.
Добавлено after 1 hour 12 minutes 29 seconds:
Я на Ваш вопрос ответил.
Вы мне не ответили на мой вопрос.
Я у Вас спрашивал, [uquote="Нефертити",url="/forum/viewtopic.php?p=4533053#p4533053"]Вы так пишите, чтобы вопросы задавали?[/uquote]
Re: Ошибка при настройки тактирования STM32F030
Добавлено: Вт янв 23, 2024 20:01:19
VladislavS
[uquote="Нефертити",url="/forum/viewtopic.php?p=4534281#p4534281"]Могу.
Взять Ваш вариант c регистрами, только:
заменить на
Ваш вариант неверен.[/uquote]И чем же он не верен? Зачем переключать тактирование на кварцевый резонатор, если его всё равно тут же на PLL переключать? Какой в этом смысл?
[uquote="Нефертити",url="/forum/viewtopic.php?p=4534281#p4534281"]Я на Ваш вопрос ответил.[/uquote]Я вообще-то не об этом спрашивал. Как бы вы написали вот это?
Код: Выделить всё
*((volatile uint8_t *)&RCC->CR+3) = RCC_CR_PLLON>>24;
[uquote="Нефертити",url="/forum/viewtopic.php?p=4534281#p4534281"]Вы мне не ответили на мой вопрос.
Я у Вас спрашивал, [uquote="Нефертити",url="/forum/viewtopic.php?p=4533053#p4533053"]Вы так пишите, чтобы вопросы задавали?[/uquote][/uquote]Странно, вроде в
этом сообщении русским по жёлтому написано НЕТ, да ещё и с пояснением почему.
Re: Ошибка при настройки тактирования STM32F030
Добавлено: Вт янв 23, 2024 20:15:37
Нефертити
[uquote="VladislavS",url="/forum/viewtopic.php?p=4534307#p4534307"]Я вообще-то не об этом спрашивал. Как бы вы написали вот это?
Код: Выделить всё
*((volatile uint8_t *)&RCC->CR+3) = RCC_CR_PLLON>>24;
[/uquote]
или
Re: Ошибка при настройки тактирования STM32F030
Добавлено: Вт янв 23, 2024 20:55:58
VladislavS
Как говорится, почувствуйте разницу.
И что там насчёт переключения на HSE? Будут обоснования?
Re: Ошибка при настройки тактирования STM32F030
Добавлено: Вт янв 23, 2024 21:01:13
Нефертити
Да, я ошибся. Извините.
Re: Ошибка при настройки тактирования STM32F030
Добавлено: Пн фев 05, 2024 22:45:30
TEPEM
Я бы тоже все на себя взял если бы мне показали картинку с надписями на асме, фиг знает что это, но очень страшно выглядит.
Жутко охота разобратся, но не знаю с чего начать, вот у меня есть же иар и стмки я же могу попробовать освоить азы асма или совсем не подходит?
И может есть хорошие статитьи или книга проверянная про асм для чайников?
Re: Ошибка при настройки тактирования STM32F030
Добавлено: Вт фев 06, 2024 08:43:59
VladislavS
Среднестатистическому программисту сейчас достаточно уметь читать ассемблерный код. IAR для этого, пожалуй, лучший инструмент.
Ставите пару галок и изучаете что компилятор сделал из вашего кода. Ну и любое обучение в XXI веке начинается с изучения гугления.