Начнем как обычно с включения периферии:
/* enable led & button port */
RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN | RCC_AHB1ENR_GPIOAEN;
/* enable tim4 */
RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
В эту инициализацию мы добавим включение таймера №4.
Также настроим порты ввода-вывода:
/* set led pins to output state */
LED_PORT->MODER |=
GPIO_MODER_MODER12_0 | GPIO_MODER_MODER13_0 |
GPIO_MODER_MODER14_0 | GPIO_MODER_MODER15_0;
/* pull-up button io */
BUT_PORT->PUPDR |= GPIO_PUPDR_PUPDR0_1;
Также настроим внешенее прерывание exti0:
/* route exti0 to pa0 */
SYSCFG->EXTICR[0] |= SYSCFG_EXTICR1_EXTI0_PA;
/* setup exti0 to rising edge */
EXTI->RTSR |= EXTI_RTSR_TR0;
/* enable exti0 interrupt */
EXTI->IMR |= EXTI_IMR_MR0;
После чего будем настраивать наш таймер. Начнем с предделителя - т.к. у нас частота 16МГц то зададим его таким чтобы удобно было пользоватся таймером: 16000 - 1(почему именно так указано выше):
/* tim4 setup presc */
TIM4->PSC = 16000 - 1;
После этого мы внесем в регистр автозагрузки значение 500 - это значение будет загружатся каждый раз по событию обновления(переполнения). Этим мы с учетом предделителя сделали задержку в 0.5с:
/* tim4 setup preload reg */
TIM4->ARR = 500;
Добавим в регистр ПДП/Прерываний активизацию прерывания по обновлению(переполнению):
/* tim4 enable update interrupt */
TIM4->DIER |= TIM_DIER_UIE;
После этого активизируем таймер:
/* tim4 enable clock */
TIM4->CR1 |= TIM_CR1_CEN;
Осталось самое малое - включение прерываний:
/* nvic enable exti0 irq */
NVIC_EnableIRQ(EXTI0_IRQn);
/* nvic enable tim4 irq */
NVIC_EnableIRQ(TIM4_IRQn);