Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32 Внешний генератор
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
war4one
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
}
war4one
Попробую по другому сформулировать вопрос.

Контроллер 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, то и тактовая, соответственно, меняется.

Если же затактироваться от внешнего генератора, настройки умножителей ФАПЧ перестают действовать и тактовая всегда одна. Что делать? Как изменить тактовую?
Serj78
Цитата(war4one @ Jul 6 2011, 10:02) *
Попробую по другому сформулировать вопрос.

Контроллер 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. Но не думаю, что схемотехника усилителя различается у них сильно.
war4one
Цитата(Serj78 @ Jul 6 2011, 22:03) *
... вы можете выпаять кварц и подать на выход кварца ( вход усилителя генератора) сигнал логического уровня с внешнего генератора или другого процессора.

В принципе, так и делаю. Есть три идентичные платы, но одна тактируется от кварца, а две других - от генератора. Причем с генератором обе платы ведут себя одинаково.
andron86
копайте варю, у меня от внешнего всё нормально. в rcc hseon включен?
war4one
Цитата(andron86 @ Jul 7 2011, 09:27) *
копайте варю, у меня от внешнего всё нормально. в rcc hseon включен?

Да, HSEON включаю.
RCC->CR |= ((uint32_t)RCC_CR_HSEON);

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

Могли бы Вы проверенный код инита клока от внешнего кварца выложить?
andron86
Цитата(war4one @ Jul 7 2011, 10:27) *
Да, HSEON включаю.
RCC->CR |= ((uint32_t)RCC_CR_HSEON);

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

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

в CFGR SW 01 поставили?
hlebn
Цитата(war4one @ Jul 7 2011, 12:27) *
Могли бы Вы проверенный код инита клока от внешнего кварца выложить?

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

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

PLL в захвате?
war4one
Цитата(andron86 @ Jul 7 2011, 12:39) *
в CFGR SW 01 поставили?

Цитата(hlebn @ Jul 7 2011, 16:28) *
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
}
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.