ozforester 0 10 мая, 2023 Опубликовано 10 мая, 2023 (изменено) · Жалоба Не могу разобраться. МК не хочет работать на скорости более 12 МГц (PLL множитель 3 и HSE 4 МГц). Даташит и референс вроде бы просмотрел и основные моменты проверил. К тому же для F030 примеры в RM имеются. Для проверки подключил олед и вывел на него RCC_CR. ( до 12 МГц PLL out) Сначала подаю питание без кварца - установлены биты 1:0, втыкаю на ходу кварц - устанавливаются 17:16 и 25:24. То есть при 12 МГц переключение на PLL происходит. Далее упростил конфигурацию до светодида. Включаю питание без кварца - мигает медленно (HSI), втыкаю кварц - мигание ускоряется (PLL). После вытаскивания кварца скорость снова уменьшается и далее уже не меняется после манипуляций с кварцем (CSS отработал и вырубил HSE с PLL). Это чтобы установить, что сам механизм переключения в принципе работает. Далее прошиваю с множителем PLL на единичку больше, и светодиод перестает мигать (а заодно и подключаться stlink). Дёргание кварца восстанавливает работу светодиода и обмен с stlink-ом. Думаю, если бы влетал в эксепшен по умолчанию, то вряд ли диод мигал после вытаскивания кварца. Прошу совета. На что здесь следует обратить внимание? /* * * STM32F030K6T6 (TQFP32) * LED - PB1 (15) * Crystal 4 MHz * */ static void delay (unsigned int time) { for (unsigned int i = 0; i < time; i++) for (volatile unsigned int j = 0; j < 500; j++); } void led_on(void){ RCC->AHBENR |= RCC_AHBENR_GPIOBEN; GPIOB->MODER |= GPIO_MODER_MODER1_0; GPIOB->BSRR = GPIO_BSRR_BS_1; while(1); } void Switch_to_PLL(void){ if ((RCC->CFGR & RCC_CFGR_SWS) == RCC_CFGR_SWS_PLL){ // Test if PLL is used as System clock RCC->CFGR &= (uint32_t) (~RCC_CFGR_SW); // Select HSI as system clock while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI); // Wait for HSI switched } RCC->CR &= (uint32_t)(~RCC_CR_PLLON); // Disable the PLL RCC->CFGR |= RCC_PLLSOURCE_HSE; // select HSE as PLL input while((RCC->CR & RCC_CR_PLLRDY) != 0); // Wait until PLLRDY is cleared RCC->CFGR = (RCC->CFGR & (~RCC_CFGR_PLLMUL)) | (RCC_CFGR_PLLMUL12); // Set the PLL multiplier RCC->CR |= RCC_CR_PLLON; // Enable the PLL while((RCC->CR & RCC_CR_PLLRDY) == 0); // Wait until PLLRDY is set RCC->CFGR |= (uint32_t) (RCC_CFGR_SW_PLL); // Select PLL as system clock while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL); // Wait until the PLL is switched on } void RCC_IRQHandler(void) // HSE running { if ((RCC->CIR & RCC_CIR_HSERDYF) != 0) // Check the flag HSE ready { RCC->CIR |= RCC_CIR_HSERDYC; // Clear the flag HSE ready FLASH->ACR |= FLASH_ACR_LATENCY; // 24 < if systemclock < 48 Mhz FLASH->ACR |= FLASH_ACR_PRFTBE; // Pref //RCC->CFGR = ((RCC->CFGR & (~RCC_CFGR_SW)) | RCC_CFGR_SW_0); // Switch the system clock to HSE Switch_to_PLL(); // Switch the system clock to PLL } else { // error led PB1 led_on(); } } void HAL_RCC_CSSCallback(void){ // reset clock sec flag RCC->CIR |= RCC_CIR_CSSC; // clear CSSF } int main( void ){ HAL_Init(); NVIC_EnableIRQ(RCC_CRS_IRQn); // interrupt NVIC_SetPriority(RCC_CRS_IRQn,0); // priority RCC->CIR |= RCC_CIR_HSERDYIE; // isr when HSE redy RCC->CR |= RCC_CR_CSSON | RCC_CR_HSEON; // enable HSE and CSS // blinking led RCC->AHBENR |= RCC_AHBENR_GPIOBEN; GPIOB->MODER |= GPIO_MODER_MODER1_0; while (1) { GPIOB->BSRR = GPIO_BSRR_BR_1; delay(500); GPIOB->BSRR = GPIO_BSRR_BS_1; delay(500); } return 0; } Изменено 10 мая, 2023 пользователем ozforester Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 136 10 мая, 2023 Опубликовано 10 мая, 2023 · Жалоба 20 минут назад, ozforester сказал: МК не хочет работать на скорости более 12 МГц (PLL множитель 3 и HSE 4 МГц). На 12 работать не должен: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ozforester 0 10 мая, 2023 Опубликовано 10 мая, 2023 (изменено) · Жалоба Спасибо. Пробовал разные множители. С другой стороны при х2 ведь работает. Начинал с х12, конечно, так как хотел разогнаться сразу до максимально-допустимой, затем для примера взял х3 как отличающуюся наглядно по частоте мигания светодиода или дающей возможность видеть на дисплее значения регистров. Думаю у меня какой-нибудь глобальный косяк, так как это первая лаба с часами на стм32. Я тут как в иксепшене по умолчанию кружу между референсом и макеткой с проводками. (: Изменено 10 мая, 2023 пользователем ozforester Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 136 10 мая, 2023 Опубликовано 10 мая, 2023 · Жалоба Вот код разгона PLL F030 до 48 МГц от HSI: Спойлер #define HSI_FREQ 8000000ULL #define HSI_DIV 2 // 4 MHz #define PLL_MUL 12 // 48 MHz #define SYSCLK ((HSI_FREQ) / (HSI_DIV) * (PLL_MUL)) #define AHBCLK (SYSCLK) static inline void init_clocks() { uint_fast32_t PREDIV1_lsb = ((HSI_DIV - 1) & 1) * RCC_CFGR_PLLXTPRE_PREDIV1_Div2; RCC->CFGR = 0 | RCC_CFGR_MCO_NOCLOCK // No clocks on MCO pin | (PLL_MUL - 2) * (RCC_CFGR_PLLMULL & -RCC_CFGR_PLLMULL) // PLLMUL | RCC_CFGR_PLLSRC_HSI_Div2 // use HSI/2 as PLL source | PREDIV1_lsb // LSB of PREDIV1, overwritten by CFGR2 | RCC_CFGR_ADCPRE_DIV4 // slowest ADC clock | RCC_CFGR_PPRE_DIV1 // APB (PCLK) clocks / 1 | RCC_CFGR_HPRE_DIV1 // AHB (SYSCLK) clocks / 1 | RCC_CFGR_SW_HSI // use HSI as system clock ; /* leave defaults RCC->CFGR3 = 0 | 0 * (RCC_CFGR3_USART1SW & -RCC_CFGR3_USART1SW) // use PCLK as UART clock | 0 * RCC_CFGR3_I2C1SW // use HSI as I2C clock | 0 * RCC_CFGR3_CECSW // use HSI/244 as CEC clock | 0 * RCC_CFGR3_ADCSW // use HSI14 as ADC clock ; */ // Enable PLL RCC->CR = (RCC->CR & RCC_CR_HSICAL) // leave factory settings | 1 * RCC_CR_HSION // Internal High Speed clock enable | 0 * RCC_CR_HSIRDY // Internal High Speed clock ready flag | 16 * (RCC_CR_HSITRIM & -RCC_CR_HSITRIM) // Internal High Speed clock trimming | 0 * RCC_CR_HSICAL // Internal High Speed clock Calibration, don't touch | 0 * RCC_CR_HSEON // External High Speed clock disable | 0 * RCC_CR_HSERDY // External High Speed clock ready flag | 0 * RCC_CR_HSEBYP // External High Speed clock Bypass disabled | 0 * RCC_CR_CSSON // Clock Security System disabled | 1 * RCC_CR_PLLON // PLL disabled | 0 * RCC_CR_PLLRDY // PLL clock ready flag ; while (!(RCC->CR & RCC_CR_PLLRDY)) ; // Set PLL clocks as system clocks RCC->CFGR = 0 | RCC_CFGR_MCO_NOCLOCK // No clocks on MCO pin | (PLL_MUL - 2) * (RCC_CFGR_PLLMULL & -RCC_CFGR_PLLMULL) // PLLMUL | RCC_CFGR_PLLSRC_HSI_Div2 // use HSI/2 as PLL source | PREDIV1_lsb // LSB of PREDIV1, overwritten by CFGR2 | RCC_CFGR_ADCPRE_DIV4 // slowest ADC clock | RCC_CFGR_PPRE_DIV1 // APB (PCLK) clocks / 1 | RCC_CFGR_HPRE_DIV1 // AHB (SYSCLK) clocks / 1 | RCC_CFGR_SW_PLL // use PLL as system clock ; // Wait until PLL is used as system clock source while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL) ; } Может найдете в нем что-то полезное. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 136 11 мая, 2023 Опубликовано 11 мая, 2023 · Жалоба Еще одна мысль появилась: А нога VDDA у вас точно запитана? У меня был случай (правда, на L151), когда в LC-фильтр в цепи VDDA вместо ферритовой бусины впаяли точно такой же по внешнему виду конденсатор. И контроллеру сносило крышу именно в момент запуска PLL. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 180 11 мая, 2023 Опубликовано 11 мая, 2023 · Жалоба Хоть исходник ТС и не лишен косяков, но я ради эксперимента залил его в свою плату на F030, кварц только 16 МГц (но предделитель 4) - все работает на всех допустимых множителях. Я делаю так (HSE (16 / 4) * 12 = 48 МГц) Спойлер void NMI_Handler(void) { if(RCC->CIR & RCC_CIR_CSSF) RCC->CIR = RCC_CIR_CSSC; NVIC_SystemReset(); } void RCC_IRQHandler(void) { u32 const cir = RCC->CIR; if((cir & (RCC_CIR_HSERDYIE | RCC_CIR_HSERDYF)) == (RCC_CIR_HSERDYIE | RCC_CIR_HSERDYF)) { RCC->CIR = RCC_CIR_HSERDYC | RCC_CIR_PLLRDYIE; RCC->CFGR = RCC_CFGR_PLLMUL12 | RCC_CFGR_PLLSRC_HSE_PREDIV | RCC_CFGR_PPRE_DIV1 | RCC_CFGR_HPRE_DIV1; RCC->CFGR2 = RCC_CFGR2_PREDIV_DIV4; RCC->CR |= RCC_CR_PLLON; } if((cir & (RCC_CIR_PLLRDYIE | RCC_CIR_PLLRDYF)) == (RCC_CIR_PLLRDYIE | RCC_CIR_PLLRDYF)) { RCC->CIR = RCC_CIR_PLLRDYC; FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY; __DSB(); __ISB(); RCC->CFGR |= RCC_CFGR_SW_PLL; NVIC_DisableIRQ(RCC_IRQn); } } void hwInitOnSysRst(void) { RCC->CR |= RCC_CR_HSEON | RCC_CR_CSSON; RCC->CIR = RCC_CIR_HSERDYIE; NVIC_EnableIRQ(RCC_IRQn); } void hwSysClkBarrier(void) { while((RCC->CFGR & RCC_CFGR_SWS_Msk) != RCC_CFGR_SWS_PLL); } Самой первой функцией в системе стартует hwInitOnSysRst(), т.е. она вызывается из обработчика сброса CPU. Блокировок на ожидания нет - все по прерываниям. Исключение - только когда логическое место по коду уже должно предполагать правильные клоки - тогда нужно вызвать принудительное ожидание hwSysClkBarrier(). У меня это место, обычно - перед инициализацией какой-то периферии, чувствительной к системным тактам. Для пущей надежности можно hwSysClkBarrier() окучить таймаутами и обработать, но мне это было не нужно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ozforester 0 11 мая, 2023 Опубликовано 11 мая, 2023 (изменено) · Жалоба 9 hours ago, Сергей Борщ said: Вот код разгона PLL F030 до 48 МГц от HSI: Reveal hidden contents #define HSI_FREQ 8000000ULL #define HSI_DIV 2 // 4 MHz #define PLL_MUL 12 // 48 MHz #define SYSCLK ((HSI_FREQ) / (HSI_DIV) * (PLL_MUL)) #define AHBCLK (SYSCLK) static inline void init_clocks() { uint_fast32_t PREDIV1_lsb = ((HSI_DIV - 1) & 1) * RCC_CFGR_PLLXTPRE_PREDIV1_Div2; RCC->CFGR = 0 | RCC_CFGR_MCO_NOCLOCK // No clocks on MCO pin | (PLL_MUL - 2) * (RCC_CFGR_PLLMULL & -RCC_CFGR_PLLMULL) // PLLMUL | RCC_CFGR_PLLSRC_HSI_Div2 // use HSI/2 as PLL source | PREDIV1_lsb // LSB of PREDIV1, overwritten by CFGR2 | RCC_CFGR_ADCPRE_DIV4 // slowest ADC clock | RCC_CFGR_PPRE_DIV1 // APB (PCLK) clocks / 1 | RCC_CFGR_HPRE_DIV1 // AHB (SYSCLK) clocks / 1 | RCC_CFGR_SW_HSI // use HSI as system clock ; /* leave defaults RCC->CFGR3 = 0 | 0 * (RCC_CFGR3_USART1SW & -RCC_CFGR3_USART1SW) // use PCLK as UART clock | 0 * RCC_CFGR3_I2C1SW // use HSI as I2C clock | 0 * RCC_CFGR3_CECSW // use HSI/244 as CEC clock | 0 * RCC_CFGR3_ADCSW // use HSI14 as ADC clock ; */ // Enable PLL RCC->CR = (RCC->CR & RCC_CR_HSICAL) // leave factory settings | 1 * RCC_CR_HSION // Internal High Speed clock enable | 0 * RCC_CR_HSIRDY // Internal High Speed clock ready flag | 16 * (RCC_CR_HSITRIM & -RCC_CR_HSITRIM) // Internal High Speed clock trimming | 0 * RCC_CR_HSICAL // Internal High Speed clock Calibration, don't touch | 0 * RCC_CR_HSEON // External High Speed clock disable | 0 * RCC_CR_HSERDY // External High Speed clock ready flag | 0 * RCC_CR_HSEBYP // External High Speed clock Bypass disabled | 0 * RCC_CR_CSSON // Clock Security System disabled | 1 * RCC_CR_PLLON // PLL disabled | 0 * RCC_CR_PLLRDY // PLL clock ready flag ; while (!(RCC->CR & RCC_CR_PLLRDY)) ; // Set PLL clocks as system clocks RCC->CFGR = 0 | RCC_CFGR_MCO_NOCLOCK // No clocks on MCO pin | (PLL_MUL - 2) * (RCC_CFGR_PLLMULL & -RCC_CFGR_PLLMULL) // PLLMUL | RCC_CFGR_PLLSRC_HSI_Div2 // use HSI/2 as PLL source | PREDIV1_lsb // LSB of PREDIV1, overwritten by CFGR2 | RCC_CFGR_ADCPRE_DIV4 // slowest ADC clock | RCC_CFGR_PPRE_DIV1 // APB (PCLK) clocks / 1 | RCC_CFGR_HPRE_DIV1 // AHB (SYSCLK) clocks / 1 | RCC_CFGR_SW_PLL // use PLL as system clock ; // Wait until PLL is used as system clock source while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL) ; } Может найдете в нем что-то полезное. Спасибо. Аналог у меня вовсе не запитан, думал раз не использую, то можно оставить в воздухе. Подключу попробую. Все никак не вытравлю плату для экспериментов, где будут учтены требования по питанию и часам. Сейчас просто квадратик под tqfp32 где и конденсаторы висят в воздухе далековато от пинов, и кварц съемный. Но, видимо помех немного, раз бит готовности HSE не пропадает, и CSS не переключается, пока кварц не вынимаю. P.S. А я не рискнул код вставлять под спойлер, не разобрался пока. И изображения вставлять не пробовал. И с цитированием вот зацепил весь текст, вместе с кодом.. Может есть на форуме тестовый раздел, где можно попробовать поизголяться с форматированием и вставкой? Изменено 11 мая, 2023 пользователем ozforester Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 180 11 мая, 2023 Опубликовано 11 мая, 2023 · Жалоба 19 минут назад, ozforester сказал: Спасибо. Аналог у меня вовсе не запитан, думал раз не использую, то можно оставить в воздухе... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ozforester 0 11 мая, 2023 Опубликовано 11 мая, 2023 (изменено) · Жалоба 1 hour ago, Arlleex said: Хоть исходник ТС и не лишен косяков, но я ради эксперимента залил его в свою плату на F030, кварц только 16 МГц (но предделитель 4) - все работает на всех допустимых множителях. Спасибо, буду видимо с железом разбираться. Переключаюсь на Си, и выходит, что 99% времени блуждаю по папкам Куба. Линуксы у меня, поэтому утилитки "find -iname " и"grep -iR" любезно подсказывают где что лежит, а как сайд-эффект изучается язык. (: Изменено 11 мая, 2023 пользователем ozforester Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 180 11 мая, 2023 Опубликовано 11 мая, 2023 · Жалоба 42 минуты назад, ozforester сказал: 99% времени блуждаю по папкам Куба Сочувствую. Но каждый сам выбирает, какой кактус и с каким аппетитом грызть) 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ozforester 0 11 мая, 2023 Опубликовано 11 мая, 2023 (изменено) · Жалоба 2 hours ago, Arlleex said: Спасибо. Прочитал тему и в даташит еще раз посмотрел. Просто пока запускал от HSI, то не испытывал трудностей. А от неподключенных VDD даже питал внешнюю периферию. (: Всегда себя успокаиваю, что чем больше ошибок, тем больше получу опыта. Говорят, что умные де на чужих ошибках учатся. Давно хотел попробовать, но пока времени нет. (: Quote Сочувствую. Но каждый сам выбирает, какой кактус и с каким аппетитом грызть) Видимо плохой из меня получился "Джордано Бруно". Хотя она всё таки вертится, и МК следует воспринимать ассемблером и регистрами комбинационных схем, а не абстракциями. (: Изменено 11 мая, 2023 пользователем ozforester Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 180 11 мая, 2023 Опубликовано 11 мая, 2023 · Жалоба 7 минут назад, ozforester сказал: Просто пока запускал от HSI, то не испытывал трудностей... А мне это удивительно, ибо даташит показывает, что даже RC-цепочка с буфером (HSI) питается от VDDA Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ozforester 0 11 мая, 2023 Опубликовано 11 мая, 2023 (изменено) · Жалоба Практика, как никак, критерий истины. (: P.S. Хотя это не повод, согласен, не следовать документации разработчика. А проводок синий, это еще не vdda, это pwm с одного таймера подавался на счетчик другого, в планах было сделать частотомер, вот и проверял как счетчик работает. Но, чтобы двигаться дальше, 8 МГц оказалось маловато. (Немного не в тему, но если тактирование подается на вход ETR, то почему пишут в референсе, что максиальная частота после прескалера должна быть в три раза меньше системной?) cssdemo.mp4 Изменено 11 мая, 2023 пользователем ozforester Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ozforester 0 11 мая, 2023 Опубликовано 11 мая, 2023 (изменено) · Жалоба Всё! Благодарю за помощь. Завёлся на 48 МГц после подключения всех питающих ног. Как грится, - "дело было не в бобине.." Дежавю. (: Изменено 11 мая, 2023 пользователем ozforester Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Obam 38 11 мая, 2023 Опубликовано 11 мая, 2023 · Жалоба Как грится, - "дело было не в бобине.." Интересно, хоть кто-нибудь присказку без купюр воспроизведёт? (((-;Ж Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться