Включаем тактирование для порта светодиодов и таймера:
/* enable led port */ RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN; /* enable tim4 */ RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;Также настроим выводы порта на режим альтернативных фунций и настроим их на подключение к таймеру №4:
/* set led pins to af state */ LED_PORT->MODER |= GPIO_MODER_MODER12_1 | GPIO_MODER_MODER13_1 | GPIO_MODER_MODER14_1 | GPIO_MODER_MODER15_1; /* select af block - tim3..5(af2 function) to led pins */ LED_PORT->AFR[1] |= (GPIO_AF2_TIM3_5 << GPIO_AFP12) | (GPIO_AF2_TIM3_5 << GPIO_AFP13) | (GPIO_AF2_TIM3_5 << GPIO_AFP14) | (GPIO_AF2_TIM3_5 << GPIO_AFP15);Также настроим таймер (настройки почти аналогичные примеру Регистры сравнения/захвата шим) за исключением значения для каналов:
/* tim4 setup presc */ TIM4->PSC = 16000 - 1; /* tim4 setup preload reg */ TIM4->ARR = 1000; /* tim4 load values to ccr1..4 */ TIM4->CCR1 = 500; TIM4->CCR2 = 0; TIM4->CCR3 = 0; TIM4->CCR4 = 0; /* tim4 setup cc chanel1..4 */ TIM4->CCMR1 |= TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2; TIM4->CCMR2 |= TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC4M_1 | TIM_CCMR2_OC4M_2; /* tim4 setup cc chanel1..4 to corresponding output pin */ TIM4->CCER |= TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC3E | TIM_CCER_CC4E;Настроим ФАПЧ на значения умножителя 64 и делителя 32, т.е. коэффициент умножения 2, а так как предделитель для ФАПЧ по умолчанию равен 2, то получаем на выходе ту же частоту что и на входе:
/* pll configuration */ RCC->PLLCFGR &= ~(RCC_PLLCFGR_PLLM | RCC_PLLCFGR_PLLN); RCC->PLLCFGR |= (64 << 6) | 32;Включаем ФАПЧ:
/* pll enable */ RCC->CR |= RCC_CR_PLLON;Также не забудем согласно ДШ задать количество циклов ожидания для максимальной частоты 64 МГц - 2 цикла ожидания:
/* enable flash wait to 2 ws */ FLASH->ACR |= FLASH_ACR_LATENCY_2WS;Ждем стабилизацию частоты ФАПЧ и переключаемся на тактирование от него:
/* wait to ready pll and switch to it */ while ((RCC->CR && RCC_CR_PLLRDY) == 0); RCC->CFGR &= ~RCC_CFGR_SWS; RCC->CFGR |= RCC_CFGR_SWS_PLL;Активируем прерывания от таймера и сам таймер №4:
/* tim4 enable update interrupt */ TIM4->DIER |= TIM_DIER_UIE; /* tim4 enable clock */ TIM4->CR1 |= TIM_CR1_CEN;Также активируем прерывания для этого таймера:
/* tim4 irq */ NVIC_EnableIRQ(TIM4_IRQn);