allsettingsdone 0 14 мая, 2013 Опубликовано 14 мая, 2013 · Жалоба Здравствуйте, начал подробно разбираться со способами тактирования STM. Написал функцию для простоты которая позволяет выбрать источник тактирования и менять множитель частоты, НО возник момент когда я тактирую мк от внутреннего RC генератора 8 МГц - то программа работает медленней чем если бы тактировал от кварца 8 МГц (смотрел на осциллографе частоту дрыгания ногами в цикле с "for(volatile uint32_t i=10; i>0; i--) {}"). И вот в случае тактирования мк от кварца 8 МГц длительность импульса - 3 мкс, а если выбрать тактирование от внутреннего RC генератора с частотой опять таки 8 Мгц - то длительность импульса будет уже 8 мкс!!! (компилирую в Keil со вторым уровнем оптимизации). И ещё совершенно не получается изменять частоту тактирования при помощи ФАПЧ (PLL). Прилагается проект в Keil. Он сам небольшой, функция называется init_clk(uint32_t clk_sourse, uint32_t PLL_status, uint32_t PLL_freq). test0_delay.zip Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 14 мая, 2013 Опубликовано 14 мая, 2013 · Жалоба ну в целом входная частота проходит еще через ряд делителей, и на разных источниках делители разные. Может вы внутренний клок поделили на что-то, а внешний нет... Также есть делители на шине портов и прочей обвески В процессоре есть специальная ножка на которую выводиться системный клок (не забудьте сделать ее максимально быстрой, в СТМах есть спец регистры которые определяют максимальную частоту работы ножки), подключите эту ножку, и смотрите реальный клок на ней, а не по каким то непонятным циклам. Настройка ПЛЛ есть в документации, и в примерах программ, в общих словах сначала надо его выключить, потом задать делители и множители, потом подключить, потом подождать сигнала что он засинхронизировался, а потом переключиться на работу от него... проект качать не очень хочется. вы бы лучше свою функцию в текст сообщения воткнули, ее бы тогда больше народу поглядело... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
allsettingsdone 0 14 мая, 2013 Опубликовано 14 мая, 2013 (изменено) · Жалоба Да вроде бы никаких делителей я не менял на других шинах, и те что есть не делил. Что касается измерения на ножке, то я вывожу прямоугольные импульсы на PC8 | PC9 (на светодиоды на STM32F100DISCOVERY), и в настройках порта выставлена частота тактирования = 50MHz (GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;) Вот код функции: //=======для выбора параметров тактирования в функции init_clk======= #define HSI 0 #define HSE 1 #define PLL_on 0 #define PLL_off 1 void init_clk(uint32_t clk_sourse, uint32_t PLL_status, uint32_t PLL_freq) { if(PLL_status == PLL_on) //если мк тактируется от PLL { if(clk_sourse == HSE) //если источником сигнала PLL является HSE { RCC->CFGR2 &= ~RCC_CFGR2_PREDIV1; //предочистка делителя HSE RCC->CFGR2 |= RCC_CFGR2_PREDIV1_DIV1; //делить частоту HSE на 1 RCC->CFGR |= RCC_CFGR_PLLSRC; //источником сигнала для PLL выбран HSE RCC->CR &= ~RCC_CR_PLLON; //отключить генератор PLL RCC->CFGR &= ~RCC_CFGR_PLLMULL; //очистить PLLMULL switch(PLL_freq) { case(2): RCC->CFGR |= RCC_CFGR_PLLMULL2; //коэфициент умножения = 2 case(3): RCC->CFGR |= RCC_CFGR_PLLMULL3; //коэфициент умножения = 3 case(4): RCC->CFGR |= RCC_CFGR_PLLMULL4; //коэфициент умножения = 4 case(5): RCC->CFGR |= RCC_CFGR_PLLMULL5; //коэфициент умножения = 5 case(6): RCC->CFGR |= RCC_CFGR_PLLMULL6; //коэфициент умножения = 6 case(7): RCC->CFGR |= RCC_CFGR_PLLMULL7; //коэфициент умножения = 7 case(8): RCC->CFGR |= RCC_CFGR_PLLMULL8; //коэфициент умножения = 8 case(9): RCC->CFGR |= RCC_CFGR_PLLMULL9; //коэфициент умножения = 9 case(10): RCC->CFGR |= RCC_CFGR_PLLMULL10; //коэфициент умножения = 10 case(11): RCC->CFGR |= RCC_CFGR_PLLMULL11; //коэфициент умножения = 11 case(12): RCC->CFGR |= RCC_CFGR_PLLMULL12; //коэфициент умножения = 12 case(13): RCC->CFGR |= RCC_CFGR_PLLMULL13; //коэфициент умножения = 13 case(14): RCC->CFGR |= RCC_CFGR_PLLMULL14; //коэфициент умножения = 14 case(15): RCC->CFGR |= RCC_CFGR_PLLMULL15; //коэфициент умножения = 15 case(16): RCC->CFGR |= RCC_CFGR_PLLMULL16; //коэфициент умножения = 16 } RCC->CR |= RCC_CR_PLLON; //включить генератор PLL while((RCC->CR & RCC_CR_PLLRDY)==0) {} //ожидание готовности PLL RCC->CFGR &= ~RCC_CFGR_SW; //очистка битов выбора источника тактового сигнала RCC->CFGR |= RCC_CFGR_SW_PLL; //выбрать источником тактового сигнала PLL while((RCC->CFGR&RCC_CFGR_SWS)!=0x08){} //ожидание переключения на PLL } else //если источником сигнала PLL является HSI { RCC->CFGR &= ~RCC_CFGR_PLLSRC; //источником сигнала для PLL выбран HSI с делением на 2 RCC->CR &= ~RCC_CR_PLLON; //отключить генератор PLL RCC->CFGR &= ~RCC_CFGR_PLLMULL; //очистить PLLMULL switch(PLL_freq) { case(2): RCC->CFGR |= RCC_CFGR_PLLMULL2; //коэфициент умножения = 2 case(3): RCC->CFGR |= RCC_CFGR_PLLMULL3; //коэфициент умножения = 3 case(4): RCC->CFGR |= RCC_CFGR_PLLMULL4; //коэфициент умножения = 4 case(5): RCC->CFGR |= RCC_CFGR_PLLMULL5; //коэфициент умножения = 5 case(6): RCC->CFGR |= RCC_CFGR_PLLMULL6; //коэфициент умножения = 6 case(7): RCC->CFGR |= RCC_CFGR_PLLMULL7; //коэфициент умножения = 7 case(8): RCC->CFGR |= RCC_CFGR_PLLMULL8; //коэфициент умножения = 8 case(9): RCC->CFGR |= RCC_CFGR_PLLMULL9; //коэфициент умножения = 9 case(10): RCC->CFGR |= RCC_CFGR_PLLMULL10; //коэфициент умножения = 10 case(11): RCC->CFGR |= RCC_CFGR_PLLMULL11; //коэфициент умножения = 11 case(12): RCC->CFGR |= RCC_CFGR_PLLMULL12; //коэфициент умножения = 12 case(13): RCC->CFGR |= RCC_CFGR_PLLMULL13; //коэфициент умножения = 13 case(14): RCC->CFGR |= RCC_CFGR_PLLMULL14; //коэфициент умножения = 14 case(15): RCC->CFGR |= RCC_CFGR_PLLMULL15; //коэфициент умножения = 15 case(16): RCC->CFGR |= RCC_CFGR_PLLMULL16; //коэфициент умножения = 16 } RCC->CR |= RCC_CR_PLLON; //включить генератор PLL while((RCC->CR & RCC_CR_PLLRDY)==0) {} //ожидание готовности PLL RCC->CFGR &= ~RCC_CFGR_SW; //очистка битов выбора источника тактового сигнала RCC->CFGR |= RCC_CFGR_SW_PLL; //выбрать источником тактового сигнала PLL while((RCC->CFGR&RCC_CFGR_SWS)!=0x08){} //ожидание переключения на PLL } } else //если мк тактируется не от PLL { if(clk_sourse == HSE) //если мк тактируется от внешнего генератора HSE { RCC->CR |= RCC_CR_HSEON; //включить генератор HSE while((RCC->CR & RCC_CR_HSERDY)==0) //ожидание готовности HSE RCC->CFGR &= ~RCC_CFGR_SW; //очистка битов выбора источника тактового сигнала RCC->CFGR |= RCC_CFGR_SW_HSE; //выбрать источником тактового сигнала генератор HSE } else //если мк тактируется от внутреннего генератора HSI { RCC->CR |= RCC_CR_HSION; //включить генератор HSI while((RCC->CR & RCC_CR_HSIRDY)==0) {} //ожидание готовности HSI RCC->CFGR &= ~RCC_CFGR_SW; //очистка битов выбора источника тактового сигнала RCC->CFGR |= RCC_CFGR_SW_HSI; //выбрать источником тактового сигнала генератор HSI } } } Вот так к примеру я вызываю функцию: init_clk(HSI,PLL_off,1); //тактирование от генератора HSI, ФАПЧ выключен, коэффициент умножения ФАПЧ = 1 (все равно в данном случае не используется) Изменено 14 мая, 2013 пользователем allsettingsdone Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
allsettingsdone 0 24 мая, 2013 Опубликовано 24 мая, 2013 (изменено) · Жалоба Может так вопрос будет понятнее: =========================================================== В случае тактирования от PLL (а PLL от внешнего кварцевого резонатора (HSE)) 1.Предочистка делителя для HSE RCC->CFGR2 &= ~RCC_CFGR2_PREDIV1; 2.Делить частоту HSE на 1 RCC->CFGR2 |= RCC_CFGR2_PREDIV1_DIV1; 3.Источником сигнала для PLL выбран HSE RCC->CFGR |= RCC_CFGR_PLLSRC; 4.Отключить генератор PLL RCC->CR &= ~RCC_CR_PLLON; 5.Очистить PLLMULL RCC->CFGR &= ~RCC_CFGR_PLLMULL; 6.Коэффициент умножения = 2 RCC->CFGR |= RCC_CFGR_PLLMULL2; 7.Включить генератор PLL RCC->CR |= RCC_CR_PLLON; 8.Ожидание готовности PLL while((RCC->CR & RCC_CR_PLLRDY)==0) {} 9.Очистка битов выбора источника тактового сигнала RCC->CFGR &= ~RCC_CFGR_SW; 10.Выбрать источником тактового сигнала PLL RCC->CFGR |= RCC_CFGR_SW_PLL; 11.Ожидание переключения на PLL while((RCC->CFGR&RCC_CFGR_SWS)!=0x08){} =========================================================== В случае тактирования от внешнего кварца (HSE) 1.Включить генератор HSE RCC->CR |= RCC_CR_HSEON; 2.Ожидание готовности HSE while((RCC->CR & RCC_CR_HSERDY)==0) 3.Очистка битов выбора источника тактового сигнала RCC->CFGR &= ~RCC_CFGR_SW; 4.Выбрать источником тактового сигнала генератор HSE RCC->CFGR |= RCC_CFGR_SW_HSE; =========================================================== В случае тактирования от внутреннего RC-генератора (HSI) без PLL 1.Включить генератор HSI RCC->CR |= RCC_CR_HSION; 2.Ожидание готовности HSI while((RCC->CR & RCC_CR_HSIRDY)==0) {} 3.Очистка битов выбора источника тактового сигнала RCC->CFGR &= ~RCC_CFGR_SW; 4.Выбрать источником тактового сигнала генератор HSI RCC->CFGR |= RCC_CFGR_SW_HSI; =========================================================== И при настройках на одинаковые частоты тактирования (во всех трех случаях должно быть 8 МГц) у меня получаются разные временные задержки. Что я делаю не так? Изменено 24 мая, 2013 пользователем allsettingsdone Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
yarunt 0 25 мая, 2013 Опубликовано 25 мая, 2013 · Жалоба По Кейловскому стартапу при выборе ppl entry clock source есть два варианта HSE или HSI/2. При HSI/2 ставлу в 2 раза умножение больше и все работает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
allsettingsdone 0 26 мая, 2013 Опубликовано 26 мая, 2013 · Жалоба На сколько я знаю при использовании PLL от HSI - частота на 2 не делится, а при использовании HSE (то есть внешнего резонатора) - для PLL частота аппаратно сама на 2 делится. Так вот что умножай что не умножай - частоты не совпадают, и не получается от PLL сделать например 16 или 24 МГц. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
yarunt 0 26 мая, 2013 Опубликовано 26 мая, 2013 · Жалоба Ну, а как обстоят дела с калибровочным байтом HSI TRIMMING, он тоже очень влияет на частоту. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться