GPIOD->MODER = 0b10101010000000000000000000000000; // альтернативная функция на 15,14,13,12 пинах ( передаем управление ножками альтернативной функции ) GPIOD->OTYPER = 0b00000000000000000000000000000000; // Двухтактный выход на 15,14,13,12 пинах GPIOD->OSPEEDR = 0b11111111000000000000000000000000; // Скорость высокая на 15,14,13,12 пинах GPIOD->PUPDR = 0b00000000000000000000000000000000; // Без подтяжки
// TIM4->CCMR1|=(TIM_CCMR1_OC1M_0|TIM_CCMR1_OC1M_1|TIM_CCMR1_OC1M_2|TIM_CCMR1_OC2M_0|TIM_CCMR1_OC2M_1|TIM_CCMR1_OC2M_2); // TIM4->CCMR2|=(TIM_CCMR2_OC3M_0|TIM_CCMR2_OC3M_1|TIM_CCMR2_OC3M_2|TIM_CCMR2_OC4M_0|TIM_CCMR2_OC4M_1|TIM_CCMR2_OC4M_2); TIM4->CCMR1 |= 0b0110000001100000; // прямой шим на 1 и 2 канале таймера TIM4->CCMR2 |= 0b0110000001100000; // прямой шим на 3 и 4 канале таймера
TIM4->CCR1 = 0b0001000000000000; // первый канал ШИМа - длина импульса TIM4->CCR2 = 0b0011111111111111; // второй канал ШИМа - длина импульса TIM4->CCR3 = 0b0111111111111111; // третий канал ШИМа - длина импульса TIM4->CCR4 = 0b1111111111111111; // четвертый канал ШИМа - длина импульса
Как мне узнать на какой частоте работает таймер, при условии, что не установлен предделитель таймера и установлен кварц на 8 МГц ? Куда нужно смотреть ? не успеваю за своими мыслями......
Сообщение отредактировал uwrtey - Пятница, 16.05.2014, 22:14
раздел reset and clock control - в справочном руководстве? пойду сюда, почитаю...
Добавлено (04.06.2014, 22:49) --------------------------------------------- че то я забросил это дело... Надо заняться..
Добавлено (05.06.2014, 17:52) --------------------------------------------- Про тактирование я так ни чего и не понял. Как то сложно тут организовано. Я так понимаю МК заводится на внутреннем генераторе = 8 МГц, потом переключается на внешний источник - в данном случае кварцевый резонатор = 8 МГц. А дальше танцы с бубном.. Не пойму как тактируется таймер - куда смотреть то? Как я понял из статьи ДиХальта практически все блоки микроконтроллера затактовываются от линии SYSCLK... На блок схеме на линии SYSCLK 72 МГц. От куда там столько? Там всегда такая частота? Или эта частота задается умножением частоты с кварца?
Далее идет предделитель ( AHB Prescaler ) потом еще один предделитель ( APB1 Prescaler ) каким из них я управляю командой TIM4->PSC ?
В общем в голове каша пока...
не успеваю за своими мыслями......
Сообщение отредактировал uwrtey - Суббота, 17.05.2014, 00:59
а фиг его знает, я обычно пользуюсь настроечным файлом coocox... эта схема нужна лишь по началу - для понимания процесса вообще.. а потом просто вызываешь инициализацию и все... Виталий (аka ВитГо)
Формулу я не нашел ( если честно не особо то и искал )
Статья хорошая. Вроде разобрался. Написал код, который должен сервой шевелить. Днем буду пробовать серву подключать...
Появилось несколько вопросов:
1) Если я правильно понял из вышеупомянутой статьи, то в system_stm32f4xx.c изменяем параметр делителя ( AHB Preskaler ) командой #define PLL_M 8 ( или речь про какой-то другой делитель? ) Но тут что-то не сходится... Я ведь изменяю параметр PLL_M, который вроде за умножение отвечает !?, а AHB Preskaler - это уже другой параметр??? Тут что-то туплю...
2) Как МК узнает от какого источника тактового сигнала нужно тактироваться ( где и как настраивается это параметр? )
3) Предделитель таймера ( TIM4->PSC ) это и есть APB_Prescaler ? Или я опять туплю ?
не успеваю за своими мыслями......
Сообщение отредактировал uwrtey - Суббота, 07.06.2014, 01:00
по первому вопросу: смотри даташит по тактированию, это RM0090, Reference manual на контроллер, раздел 5. Reset and clock control (RCC), подраздел 5.2 Clock... частота идет следующим образом (смотри внимательно, немного неудачно я цвета выбрал..)
сначала частоту внешнего кварца ты делишь, потом получившуюся частоту подаешь на умножитель, после которого опять делишь :-)
получается что частоту 8 мгц делишь на 8 (это делитель PLL_M), получаешь 1 мгц..
потом умножителем увеличиваешь частоту до 336 мгц (умножаешь на 336 - это параметр PLL_N)
потом делишь на 2 (параметр PLL_P) и получаешь sysclk в 168 мгц..
при этом для USB нужна частота 48 мгц - а она получается путем деления 336 мгц на 7 (параметр PLL_Q)
все параметры PLL_x - это параметры блока умножителя...
после умножителя частота идет на переключатель, на котором можно выбрать источник частоты (в нашем случае источник PLL (умножитель)), и потом попадает на AHB Preskaler это делитель для получения частоты на шинах AHB/APB (смотри на картинку!!): AHB 168 мгц (это исходная частота PLLCLK) APB1 делитель 4 - 42 мгц APB2 делитель 2 - 84 мгц
дальше идем в файл stm32f4xx.h и находим что сидит:
на шинах AHBx (такт как написано выше sysclk, в нашем случае 168 мгц):
2) Как МК узнает от какого источника тактового сигнала нужно тактироваться ( где и как настраивается это параметр? )
а вот это как раз файл system_stm32f4xx.c ты вызываешь вначале программы его процедуру SystemInit(); (кстати ты помнишь о том что нужно вызывать SystemInit() прямо в начале процедуры main() ? )
/* первоначально всегда стартуем на HSI (8 мгц, внутренний), на него же откатываемся если вдруг отказывает внешний кварц
/* Reset the RCC clock configuration to the default reset state ------------*/ /* Set HSION bit */ RCC->CR |= (uint32_t)0x00000001;
/* Reset CFGR register */ RCC->CFGR = 0x00000000;
// здесь сбрасываем все регистры в первоначальное состояние, если только включились то в принципе нафиг не нужно, // если же произошел отказ внешнего кварца то без этого никак, поэтому всегда идет сброс конфигов
// и вызываем настройку делителей умножителей :=) (то что на картинке в прошлом сообщении) // процедуру SetSysClock() я ниже в спойлер засуну
/* Configure the System clock source, PLL Multiplier and Divider factors, AHB/APBx prescalers and Flash settings ----------------------------------*/ SetSysClock();
// ждем пока он заработает и его частота стабилизируется
/* Wait till HSE is ready and if Time out is reached exit */ do { HSEStatus = RCC->CR & RCC_CR_HSERDY; StartUpCounter++; } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
if (HSEStatus == (uint32_t)0x01) { /* Select regulator voltage output Scale 1 mode, System frequency up to 168 MHz */ RCC->APB1ENR |= RCC_APB1ENR_PWREN; PWR->CR |= PWR_CR_VOS;
// включаем блок умножителей/делителей /* Enable the main PLL */ RCC->CR |= RCC_CR_PLLON;
// ждем пока частоты установятся и все заработает /* Wait till the main PLL is ready */ while((RCC->CR & RCC_CR_PLLRDY) == 0) { }
/* Configure Flash prefetch, Instruction cache, Data cache and wait state */ FLASH->ACR = FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;
/* Select the main PLL as system clock source */ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); RCC->CFGR |= RCC_CFGR_SW_PLL;
/* Wait till the main PLL is used as system clock source */ while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL); { } } else {
// сюда попадаем если HSE кварц не запустился (или нет внешнего тактирования)
/* If HSE fails to start-up, the application will have wrong clock configuration. User can add here some code to deal with this error */ }
}
вот кратенько так это и происходит..
если не заморачиваться то можно просто задать значение делителя частоты PLL_M таким чтобы на выходе был 1 мгц и вызвать SystemInit() для настройки тактирования...
если заморачиваться (и подогнать делители/множители) то можно разогнать проц.. я гнал до 240 мгц с сохранением работы USB :-) но это пожалуй позже..
p.s. как вспомню i8080 c его 2 мгц такта или z80 с тактом в 3.5 мгц..... эххх.. а сейчас 168 мгц такта, и еще мало, , разгоняем до 240 мгц Виталий (аka ВитГо)
3) Предделитель таймера ( TIM4->PSC ) это и есть APB_Prescaler ? Или я опять туплю ?
нет, предделитель таймера это предделитель таймера :-) смотреть раздел 14. General-purpose timers (TIM2 to TIM5) в Reference manual (RM0090)
шина на которой сидит таймер - APB1 (смотреть в stm32f4xx.h) - эта шина имеет такт 42 мгц - вот с ней и работает предделитель. Следовательно если предделитель таймера будет равен 1 - то 42 мгц это максимальная частота тактирующая таймер.
уффф.. и про тактирование это еще не все.. как видишь на схеме из сообщений выше - еще есть куча модулей которые тактируются той или иной частотой.. например сигналы MCOx - на них можно отдавать частоту с разных источников (HSE, HSI, LSE, PLL) и еще предварительно ее можно делить прескалером от 1 до 5.. я таким образом достаю частоту в 84 мгц из микроконтроллера для работы АЦП.. Виталий (аka ВитГо)