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

Вопросы по тактированию STM32F100

Здравствуйте, начал подробно разбираться со способами тактирования 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

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


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

ну в целом входная частота проходит еще через ряд делителей, и на разных источниках делители разные. Может вы внутренний клок поделили на что-то, а внешний нет... Также есть делители на шине портов и прочей обвески

 

В процессоре есть специальная ножка на которую выводиться системный клок (не забудьте сделать ее максимально быстрой, в СТМах есть спец регистры которые определяют максимальную частоту работы ножки), подключите эту ножку, и смотрите реальный клок на ней, а не по каким то непонятным циклам.

 

Настройка ПЛЛ есть в документации, и в примерах программ, в общих словах сначала надо его выключить, потом задать делители и множители, потом подключить, потом подождать сигнала что он засинхронизировался, а потом переключиться на работу от него...

 

проект качать не очень хочется. вы бы лучше свою функцию в текст сообщения воткнули, ее бы тогда больше народу поглядело...

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


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

Да вроде бы никаких делителей я не менял на других шинах, и те что есть не делил. Что касается измерения на ножке, то я вывожу прямоугольные импульсы на 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 (все равно в данном случае не используется)

Изменено пользователем allsettingsdone

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


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

Может так вопрос будет понятнее:

 

===========================================================

В случае тактирования от 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 МГц) у меня получаются разные временные задержки.

Что я делаю не так?

Изменено пользователем allsettingsdone

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


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

По Кейловскому стартапу при выборе ppl entry clock source есть два варианта HSE или HSI/2. При HSI/2 ставлу в 2 раза умножение больше и все работает.

 

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


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

На сколько я знаю при использовании PLL от HSI - частота на 2 не делится, а при использовании HSE (то есть внешнего резонатора) - для PLL частота аппаратно сама на 2 делится. Так вот что умножай что не умножай - частоты не совпадают, и не получается от PLL сделать например 16 или 24 МГц.

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


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

Ну, а как обстоят дела с калибровочным байтом HSI TRIMMING, он тоже очень влияет на частоту.

 

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


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

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

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

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

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

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

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

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

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

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