work.c

Для начала добавим функцию аппаратной задержки - она будет вызываться обработчиком системного таймера. Через 500 вызовов происходит смена состояния светодиодов на противоположное:

/* hardware delay and switch */
void hard_delay(void) {
    static unsigned int counter;
    counter++;
    /* wait a half second */
    if (counter > 500) {
        /* switch leds */
        LED_PORT->ODR ^= ALL_LEDS;
        counter = 0;
    }
}

В функцию work() мы добавим инциализацию портов в/в и включение светодиодов:

/* enable led & button port */
    RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN | RCC_AHB1ENR_GPIOAEN;
    /* 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;
    /* enable leds */
    LED_PORT->ODR |= ALL_LEDS;

Инициализацию таймера - т.к. таймер у нас работает на частоте ядра(~16МГц) то период его будет равен 16000 циклов, что равно ~1мс:

/* setup SysTick timer */
    SysTick_Config(16000);

Т.к. мы подключили заголовочный файл ядра - core_cm4.h то воспользуемся функцией инициализации системного таймера оттуда.

И наконец добавим бесконечный цикл в котором будет происходить опрос кнопки:

/* infinity loop */
    while (1) {
        /* if button pressed */
        if (BUT_PORT->IDR & BUT1) {
            /* change status to two leds - red & green */
            LED_PORT->ODR ^= GREEN_LED | RED_LED;
            /* wait while button pressed */
            while (BUT_PORT->IDR & BUT1);
        }
    }