Перейти к содержанию
    

Не могу разобраться. МК не хочет работать на скорости более 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;
}

 

Изменено пользователем ozforester

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

20 минут назад, ozforester сказал:

МК не хочет работать на скорости более 12 МГц (PLL множитель 3 и HSE 4 МГц).

На 12 работать не должен:

image.png.32e2594b09dff3d6107e9036ace90af5.png

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо. Пробовал разные множители. С другой стороны при х2 ведь работает. Начинал с х12, конечно, так как хотел разогнаться сразу до максимально-допустимой, затем для примера взял х3 как отличающуюся наглядно по частоте мигания светодиода или дающей возможность видеть на дисплее значения регистров. Думаю у меня какой-нибудь глобальный косяк, так как это первая лаба с часами на стм32. Я тут как в иксепшене по умолчанию кружу между референсом и макеткой с проводками. (:

Изменено пользователем ozforester

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот код разгона 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)
        ;
}

Может найдете в нем что-то полезное.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Еще одна мысль появилась: А нога VDDA у вас точно запитана? У меня был случай (правда, на L151), когда в LC-фильтр в цепи VDDA вместо ферритовой бусины впаяли точно такой же по внешнему виду конденсатор. И контроллеру сносило крышу именно в момент запуска PLL.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Хоть исходник ТС и не лишен косяков, но я ради эксперимента залил его в свою плату на 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() окучить таймаутами и обработать, но мне это было не нужно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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. А я не рискнул код вставлять под спойлер, не разобрался пока. И изображения вставлять не пробовал. И с цитированием вот зацепил весь текст, вместе с кодом.. Может есть на форуме тестовый раздел, где можно попробовать поизголяться с форматированием и вставкой?

Изменено пользователем ozforester

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

19 минут назад, ozforester сказал:

Спасибо. Аналог у меня вовсе не запитан, думал раз не использую, то можно оставить в воздухе...

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, Arlleex said:

Хоть исходник ТС и не лишен косяков, но я ради эксперимента залил его в свою плату на F030, кварц только 16 МГц (но предделитель 4) - все работает на всех допустимых множителях.

Спасибо, буду видимо с железом разбираться. Переключаюсь на Си, и выходит, что 99% времени блуждаю по папкам Куба.  Линуксы у меня, поэтому утилитки "find -iname " и"grep -iR" любезно подсказывают где что лежит, а как сайд-эффект изучается язык. (:

Изменено пользователем ozforester

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

42 минуты назад, ozforester сказал:

99% времени блуждаю по папкам Куба

Сочувствую. Но каждый сам выбирает, какой кактус и с каким аппетитом грызть)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 hours ago, Arlleex said:

 

Спасибо. Прочитал тему и в даташит еще раз посмотрел. Просто пока запускал от HSI, то не испытывал трудностей. А от неподключенных VDD даже  питал  внешнюю периферию.  (: Всегда себя успокаиваю, что чем больше ошибок, тем больше получу опыта. Говорят, что умные де на чужих ошибках учатся. Давно хотел попробовать, но пока времени нет. (:

Quote

Сочувствую. Но каждый сам выбирает, какой кактус и с каким аппетитом грызть)

Видимо плохой из меня получился "Джордано Бруно". Хотя она всё таки вертится, и МК следует воспринимать ассемблером и регистрами комбинационных схем, а не абстракциями. (:

Изменено пользователем ozforester

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

7 минут назад, ozforester сказал:

Просто пока запускал от HSI, то не испытывал трудностей...

А мне это удивительно, ибо даташит показывает, что даже RC-цепочка с буфером (HSI) питается от VDDA

image.thumb.png.04c7d454fae9908f6711ef713979bfaa.png

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Практика, как никак, критерий истины. (: 

P.S. Хотя это не повод, согласен, не следовать документации разработчика. А проводок синий, это еще не vdda, это pwm с одного таймера подавался на счетчик другого, в планах было сделать частотомер, вот и проверял как счетчик работает. Но, чтобы двигаться дальше, 8 МГц оказалось маловато. (Немного не в тему, но если тактирование подается на вход ETR, то почему пишут в референсе, что максиальная частота после прескалера должна быть в три раза меньше системной?)

Изменено пользователем ozforester

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Всё! Благодарю за помощь. Завёлся на 48 МГц после подключения всех питающих ног.  Как грится, - "дело было не в бобине.."  Дежавю. (:

Изменено пользователем ozforester

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как грится, - "дело было не в бобине.."
Интересно, хоть кто-нибудь присказку без купюр воспроизведёт? (((-;Ж

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...