реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> STM32 Внешний генератор
war4one
сообщение Jul 5 2011, 09:14
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 264
Регистрация: 16-07-05
Из: г. Уфа
Пользователь №: 6 851



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
}


--------------------
Электронные устройства Open Hardware
Go to the top of the page
 
+Quote Post
war4one
сообщение Jul 6 2011, 06:02
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 264
Регистрация: 16-07-05
Из: г. Уфа
Пользователь №: 6 851



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

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

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


--------------------
Электронные устройства Open Hardware
Go to the top of the page
 
+Quote Post
Serj78
сообщение Jul 6 2011, 18:03
Сообщение #3


Знающий
****

Группа: Свой
Сообщений: 966
Регистрация: 27-05-06
Из: СПб
Пользователь №: 17 499



Цитата(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. Но не думаю, что схемотехника усилителя различается у них сильно.
Go to the top of the page
 
+Quote Post
war4one
сообщение Jul 7 2011, 06:13
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 264
Регистрация: 16-07-05
Из: г. Уфа
Пользователь №: 6 851



Цитата(Serj78 @ Jul 6 2011, 22:03) *
... вы можете выпаять кварц и подать на выход кварца ( вход усилителя генератора) сигнал логического уровня с внешнего генератора или другого процессора.

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


--------------------
Электронные устройства Open Hardware
Go to the top of the page
 
+Quote Post
andron86
сообщение Jul 7 2011, 06:27
Сообщение #5


Местный
***

Группа: Участник
Сообщений: 406
Регистрация: 1-03-06
Пользователь №: 14 821



копайте варю, у меня от внешнего всё нормально. в rcc hseon включен?
Go to the top of the page
 
+Quote Post
war4one
сообщение Jul 7 2011, 08:27
Сообщение #6


Местный
***

Группа: Свой
Сообщений: 264
Регистрация: 16-07-05
Из: г. Уфа
Пользователь №: 6 851



Цитата(andron86 @ Jul 7 2011, 09:27) *
копайте варю, у меня от внешнего всё нормально. в rcc hseon включен?

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

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

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


--------------------
Электронные устройства Open Hardware
Go to the top of the page
 
+Quote Post
andron86
сообщение Jul 7 2011, 08:39
Сообщение #7


Местный
***

Группа: Участник
Сообщений: 406
Регистрация: 1-03-06
Пользователь №: 14 821



Цитата(war4one @ Jul 7 2011, 10:27) *
Да, HSEON включаю.
RCC->CR |= ((uint32_t)RCC_CR_HSEON);

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

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

в CFGR SW 01 поставили?
Go to the top of the page
 
+Quote Post
hlebn
сообщение Jul 7 2011, 13:28
Сообщение #8


Частый гость
**

Группа: Свой
Сообщений: 131
Регистрация: 22-10-04
Пользователь №: 963



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

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

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

PLL в захвате?
Go to the top of the page
 
+Quote Post
war4one
сообщение Jul 11 2011, 09:38
Сообщение #9


Местный
***

Группа: Свой
Сообщений: 264
Регистрация: 16-07-05
Из: г. Уфа
Пользователь №: 6 851



Цитата(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
}


--------------------
Электронные устройства Open Hardware
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 17:33
Рейтинг@Mail.ru


Страница сгенерированна за 0.01448 секунд с 7
ELECTRONIX ©2004-2016