|
|
  |
STM32 Внешний генератор |
|
|
|
Jul 5 2011, 09:14
|
Местный
  
Группа: Свой
Сообщений: 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 }
--------------------
|
|
|
|
|
Jul 6 2011, 06:02
|
Местный
  
Группа: Свой
Сообщений: 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_PLLMULL 9 заменить на RCC_CFGR_PLLMULL 4, то и тактовая, соответственно, меняется. Если же затактироваться от внешнего генератора, настройки умножителей ФАПЧ перестают действовать и тактовая всегда одна. Что делать? Как изменить тактовую?
--------------------
|
|
|
|
|
Jul 6 2011, 18:03
|

Знающий
   
Группа: Свой
Сообщений: 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_PLLMULL 9 заменить на RCC_CFGR_PLLMULL 4, то и тактовая, соответственно, меняется. Если же затактироваться от внешнего генератора, настройки умножителей ФАПЧ перестают действовать и тактовая всегда одна. Что делать? Как изменить тактовую? Не исследовал это. Но вы можете выпаять кварц и подать на выход кварца ( вход усилителя генератора) сигнал логического уровня с внешнего генератора или другого процессора.( Я так пробовал, правда на 16 Мгц.) Все успешно работало. Однако процессор был несколько другой- F103. Но не думаю, что схемотехника усилителя различается у них сильно.
|
|
|
|
|
Jul 7 2011, 06:13
|
Местный
  
Группа: Свой
Сообщений: 264
Регистрация: 16-07-05
Из: г. Уфа
Пользователь №: 6 851

|
Цитата(Serj78 @ Jul 6 2011, 22:03)  ... вы можете выпаять кварц и подать на выход кварца ( вход усилителя генератора) сигнал логического уровня с внешнего генератора или другого процессора. В принципе, так и делаю. Есть три идентичные платы, но одна тактируется от кварца, а две других - от генератора. Причем с генератором обе платы ведут себя одинаково.
--------------------
|
|
|
|
|
Jul 7 2011, 08:27
|
Местный
  
Группа: Свой
Сообщений: 264
Регистрация: 16-07-05
Из: г. Уфа
Пользователь №: 6 851

|
Цитата(andron86 @ Jul 7 2011, 09:27)  копайте варю, у меня от внешнего всё нормально. в rcc hseon включен? Да, HSEON включаю. RCC->CR |= ((uint32_t)RCC_CR_HSEON); Пробовал еще включать-выключать HSEBYP, не влияет. Могли бы Вы проверенный код инита клока от внешнего кварца выложить?
--------------------
|
|
|
|
|
Jul 7 2011, 08:39
|
Местный
  
Группа: Участник
Сообщений: 406
Регистрация: 1-03-06
Пользователь №: 14 821

|
Цитата(war4one @ Jul 7 2011, 10:27)  Да, HSEON включаю. RCC->CR |= ((uint32_t)RCC_CR_HSEON);
Пробовал еще включать-выключать HSEBYP, не влияет.
Могли бы Вы проверенный код инита клока от внешнего кварца выложить? в CFGR SW 01 поставили?
|
|
|
|
|
Jul 7 2011, 13:28
|
Частый гость
 
Группа: Свой
Сообщений: 131
Регистрация: 22-10-04
Пользователь №: 963

|
Цитата(war4one @ Jul 7 2011, 12:27)  Могли бы Вы проверенный код инита клока от внешнего кварца выложить? В библиотеке от производителя есть примеры. Работал с F103 и внешним синтезатором. С установкой частот через PLL проблем не испытывал. PLL в захвате?
|
|
|
|
|
Jul 11 2011, 09:38
|
Местный
  
Группа: Свой
Сообщений: 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 }
--------------------
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|