work.c

Начнем изменение с того что подадим тактовый сигнал на порт с которого и управляются светодиоды. Из блок схемы мк видно что все порты в/в сидят на шине AHB1, за включение периферии на этой шине отвечает регистр системы генерации тактового сигнала и сброса RCC(мы к ней еще вернемся) - AHB1ENR:

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

/* enable led port */
RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN;

Далее необходимо настроить линии к которым подключены светодиоды на вывод(линии 12-15). Для этого есть специальный регистры в системе в/в GPIO - MODER:

Для каждой линии выделено 2 бита которые управляют 4мя состояниями:

  • 00: ввод
  • 01: вывод
  • 10: альтернативные функции
  • 11: аналоговый режим

Переведем линии 12-15 из состояния ввода в состояние вывода, для этого необходимо записать 1 в 0вой бит каждой линии:

    /* 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;

Остальные регистры настройки мы пока не трогаем, т.к. нету необходимости их изменять.

Чтобы светодиоды загорелись нам необходимо перевести линии в состояние лог "1", для этого мы воспользуемся регистром вывода GPIO - ODR(есть еще несколько способов это сделать, о них я расскажу далее):

Каждая линия представлена в этом регистре одним битом поэтому просто запишем нашу константу ALL_LEDS в этот регистр:

/* enable leds */
    LED_PORT->ODR |= ALL_LEDS;