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

STM32 Внешний генератор

STM32 тактируется от внутреннего 8 МГц генератора, при умножении на PLL получаем тактовую 32. При подключении внешнего генератора 6 МГц, но без изменения программы (т. е. МК должен тактироваться все еще от встроенного RC-генератора) я вижу изменение тактовой (раньше таймер выдавал прерывание каждую 1 с, а теперь каждые 1.8 с). Чем это объяснить?

 

Код инициализации тактовой частоты:

void InitClock(void)    // Инициализируем и раздаем клоки
{
    __IO uint32_t HSEStatus = (uint32_t)0x00;                    // Работа от HSI

    FLASH->ACR |= FLASH_ACR_PRFTBE;    // Включаем буфер предвыборки FLASH
    // Конфигурируем Flash на 2 цикла ожидания
    FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
    FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;    
    // HCLK = SYSCLK
    RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
    // PCLK2 = HCLK
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
    //PCLK1 = HCLK
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
    // Конфигурируем множитель PLL configuration: PLLCLK = (8/2) * 8 = 32 MHz
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSI_Div2 | RCC_CFGR_PLLMULL8);
    // Включаем PLL
    RCC->CR |= RCC_CR_PLLON;
    // Ожидаем, пока PLL выставит бит готовности
    while((RCC->CR & RCC_CR_PLLRDY) == 0){}
    // Выбираем PLL как источник системной частоты
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
    RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;    
    // Ожидаем, пока PLL выберется как источник системной частоты
    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) {}

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);    // Включаем тактирование PORTA
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);    // Включаем тактирование PORTB
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);     // Включаем тактирование SPI
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);    // Включаем тактирование таймера 2
}

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


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

Попробую по другому сформулировать вопрос.

 

Контроллер STM32F101T8. При тактировании от кварца могу обычным образом менять настройки тактовой частоты, например:

RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLXTPRE_PREDIV1_Div2 | RCC_CFGR_PLLMULL9);

Если, скажем, RCC_CFGR_PLLMULL9 заменить на RCC_CFGR_PLLMULL4, то и тактовая, соответственно, меняется.

 

Если же затактироваться от внешнего генератора, настройки умножителей ФАПЧ перестают действовать и тактовая всегда одна. Что делать? Как изменить тактовую?

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


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

Попробую по другому сформулировать вопрос.

 

Контроллер STM32F101T8. При тактировании от кварца могу обычным образом менять настройки тактовой частоты, например:

RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLXTPRE_PREDIV1_Div2 | RCC_CFGR_PLLMULL9);

Если, скажем, RCC_CFGR_PLLMULL9 заменить на RCC_CFGR_PLLMULL4, то и тактовая, соответственно, меняется.

 

Если же затактироваться от внешнего генератора, настройки умножителей ФАПЧ перестают действовать и тактовая всегда одна. Что делать? Как изменить тактовую?

 

Не исследовал это. Но вы можете выпаять кварц и подать на выход кварца ( вход усилителя генератора) сигнал логического уровня с внешнего генератора или другого процессора.( Я так пробовал, правда на 16 Мгц.) Все успешно работало. Однако процессор был несколько другой- F103. Но не думаю, что схемотехника усилителя различается у них сильно.

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


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

... вы можете выпаять кварц и подать на выход кварца ( вход усилителя генератора) сигнал логического уровня с внешнего генератора или другого процессора.

В принципе, так и делаю. Есть три идентичные платы, но одна тактируется от кварца, а две других - от генератора. Причем с генератором обе платы ведут себя одинаково.

 

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


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

копайте варю, у меня от внешнего всё нормально. в rcc hseon включен?

Да, HSEON включаю.

RCC->CR |= ((uint32_t)RCC_CR_HSEON);

 

Пробовал еще включать-выключать HSEBYP, не влияет.

 

Могли бы Вы проверенный код инита клока от внешнего кварца выложить?

 

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


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

Да, HSEON включаю.

RCC->CR |= ((uint32_t)RCC_CR_HSEON);

 

Пробовал еще включать-выключать HSEBYP, не влияет.

 

Могли бы Вы проверенный код инита клока от внешнего кварца выложить?

в CFGR SW 01 поставили?

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


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

Могли бы Вы проверенный код инита клока от внешнего кварца выложить?

В библиотеке от производителя есть примеры.

 

Работал с F103 и внешним синтезатором. С установкой частот через PLL проблем не испытывал.

 

PLL в захвате?

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


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

в CFGR SW 01 поставили?

PLL в захвате?

Сейчас вот такая процедура инициализации, может быть, что-то забыл? В частности, с HSEBYP сейчас ничего не делаю.

void InitClock(void)    // Инициализируем и раздаем клоки, пытаемся запустится от HSE, если не получается, стартуем от HSI
{
    __IO uint32_t StartUpCounter = 0;

    RCC->CR |= ((uint32_t)RCC_CR_HSEON);    // Включаем HSE
    
    do        // Ждем пока HSE не выставит бит готовности либо не выйдет таймаут
    {
        HSEStatus = RCC->CR & RCC_CR_HSERDY;
        StartUpCounter++;  
    } 
    while((HSEStatus == 0) && (StartUpCounter != HSEStartUp_TimeOut));
    
    if((RCC->CR & RCC_CR_HSERDY) != RESET)
        HSEStatus = (uint32_t)0x01;        // HSE
    else
        HSEStatus = (uint32_t)0x00;        // HSI

    FLASH->ACR |= FLASH_ACR_PRFTBE;    // Включаем буфер предвыборки FLASH
    // Конфигурируем Flash на 1 цикл ожидания
    //    Это нужно потому, что Flash не может работать на высокой частоте
    FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
    FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_1;    
    // HCLK = SYSCLK
    RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
    // PCLK2 = HCLK
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
    //PCLK1 = HCLK
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
    
    if (HSEStatus == (uint32_t)0x01)    // Работа от кварцевого генератора
    {// Конфигурируем множитель PLL configuration: PLLCLK = (6 M / 2) * 9 = 27 MHz
        RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
        RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLXTPRE_PREDIV1_Div2 | RCC_CFGR_PLLMULL9);
    }
    else                                         // Работа от встроенного RC-генератора
    {// Конфигурируем множитель PLL configuration: PLLCLK = (HSI/2) * 8 = 32 MHz
        RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
        RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSI_Div2 | RCC_CFGR_PLLMULL8);
    }

    // Включаем PLL
    RCC->CR |= RCC_CR_PLLON;
    // Ожидаем, пока PLL выставит бит готовности
    while((RCC->CR & RCC_CR_PLLRDY) == 0) {}
    // Выбираем PLL как источник системной частоты
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
    RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
    // Ожидаем, пока PLL выберется как источник системной частоты
    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) {}
    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);    // Включаем тактирование PORTA
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);    // Включаем тактирование PORTB
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);     // Включаем тактирование SPI
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);    // Включаем тактирование таймера 2
}

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


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

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

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

Гость
Ответить в этой теме...

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

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

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

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

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

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