// main.c
#include <stm32f4xx.h>
// Простая программная задержка
static void delay_cycles(uint32_t cycles)
{
// Пока не вычтем до нуля, цикл не закончится
while(cycles--);
}
// Здесь нельзя инициализировать глобальные переменные, не помеченные специально
// как не нуждающиеся в инициализации. Память инициализируется после вызова
// SystemInit и все значения будут затёрты.
//void SystemInit(void)
//{
// // Пока тут ещё ничего нет.
//}
// Отсюда начинается выполнение пользовательского кода.
int main(void)
{
// Светодиоды сидят на порту D и выводах 12 - 15.
// Первым делом надо включить тактирование порту D.
// За это отвечает 3 бит (GPIODEN) в регистре RCC_AHB1ENR (Reference manual, p.110)
RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN;
// Дальше надо настроить выводы как выходы типа Push-pull, с максимальной частотой,
// например, 50 МГц (от частоты зависит энергопотребление ножки).
// Первый регистр, GPIOx_MODER: режим работы выхода, (RM, p. 148)
// 2 бита на каждую ножку
// 0: Вход, 1: выход, 2: альтернативная функция, 3: аналоговый
GPIOD->MODER |= (1UL << 12 * 2) | (1UL << 13 * 2) | (1UL << 14 * 2) | (1UL << 15 * 2);
// Второй регистр, GPIOx_OTYPER: тип выхода. Двухтактный (0) али открытый коллектор (1)
// Один бит на каждую ножку. По умолчанию всё так, как и надо.
// Третий регистр, GPIOx_OSPEEDR: максимальная скорость порта.
// По умолчанию 2 МГц, так что ок.
// Четвёртый регистр, GPIOx_PUPDR: куда он будет по умолчанию подтягивать, если выбран двухтактный режим.
// 0: никуда, 1: питание, 2: земля, 3: резервировано. Два бита на вывод.
// Допустим, к питанию.
GPIOD->PUPDR |= (1UL << 12 * 2) | (1UL << 13 * 2) | (1UL << 14 * 2) | (1UL << 15 * 2);
// Регистр вывода: GPIOx_ODR. Что запишешь, то на ножках и будет.
// Есть регистр для установки битов и для их сброса (GPIOx_BSRR).
// Младшие 2 байта отвечают за установку, старшие - за сброс.
// Жги!
GPIOD->BSRRL = (1UL << 12) | (1UL << 13) | (1UL << 14) | (1UL << 15);
delay_cycles(1000000UL);
// Утухни
GPIOD->BSRRH = (1UL << 12) | (1UL << 13) | (1UL << 14) | (1UL << 15);
delay_cycles(1000000UL);
while(1)
{
// Зажжём 12й
GPIOD->BSRRL = (1UL << 12);
delay_cycles(1000000UL);
// Погасим 12й
GPIOD->BSRRH = (1UL << 12);
// Зажжём 13й
GPIOD->BSRRL = (1UL << 13);
delay_cycles(1000000UL);
// Погасим 13й
GPIOD->BSRRH = (1UL << 13);
// Зажжём 14й
GPIOD->BSRRL = (1UL << 14);
delay_cycles(1000000UL);
// Погасим 14й
GPIOD->BSRRH = (1UL << 14);
// Зажжём 15й
GPIOD->BSRRL = (1UL << 15);
delay_cycles(1000000UL);
// Погасим 15й
GPIOD->BSRRH = (1UL << 15);
}
}
#include <stm32f4xx.h>
// Простая программная задержка
static void delay_cycles(uint32_t cycles)
{
// Пока не вычтем до нуля, цикл не закончится
while(cycles--);
}
// Здесь нельзя инициализировать глобальные переменные, не помеченные специально
// как не нуждающиеся в инициализации. Память инициализируется после вызова
// SystemInit и все значения будут затёрты.
//void SystemInit(void)
//{
// // Пока тут ещё ничего нет.
//}
// Отсюда начинается выполнение пользовательского кода.
int main(void)
{
// Светодиоды сидят на порту D и выводах 12 - 15.
// Первым делом надо включить тактирование порту D.
// За это отвечает 3 бит (GPIODEN) в регистре RCC_AHB1ENR (Reference manual, p.110)
RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN;
// Дальше надо настроить выводы как выходы типа Push-pull, с максимальной частотой,
// например, 50 МГц (от частоты зависит энергопотребление ножки).
// Первый регистр, GPIOx_MODER: режим работы выхода, (RM, p. 148)
// 2 бита на каждую ножку
// 0: Вход, 1: выход, 2: альтернативная функция, 3: аналоговый
GPIOD->MODER |= (1UL << 12 * 2) | (1UL << 13 * 2) | (1UL << 14 * 2) | (1UL << 15 * 2);
// Второй регистр, GPIOx_OTYPER: тип выхода. Двухтактный (0) али открытый коллектор (1)
// Один бит на каждую ножку. По умолчанию всё так, как и надо.
// Третий регистр, GPIOx_OSPEEDR: максимальная скорость порта.
// По умолчанию 2 МГц, так что ок.
// Четвёртый регистр, GPIOx_PUPDR: куда он будет по умолчанию подтягивать, если выбран двухтактный режим.
// 0: никуда, 1: питание, 2: земля, 3: резервировано. Два бита на вывод.
// Допустим, к питанию.
GPIOD->PUPDR |= (1UL << 12 * 2) | (1UL << 13 * 2) | (1UL << 14 * 2) | (1UL << 15 * 2);
// Регистр вывода: GPIOx_ODR. Что запишешь, то на ножках и будет.
// Есть регистр для установки битов и для их сброса (GPIOx_BSRR).
// Младшие 2 байта отвечают за установку, старшие - за сброс.
// Жги!
GPIOD->BSRRL = (1UL << 12) | (1UL << 13) | (1UL << 14) | (1UL << 15);
delay_cycles(1000000UL);
// Утухни
GPIOD->BSRRH = (1UL << 12) | (1UL << 13) | (1UL << 14) | (1UL << 15);
delay_cycles(1000000UL);
while(1)
{
// Зажжём 12й
GPIOD->BSRRL = (1UL << 12);
delay_cycles(1000000UL);
// Погасим 12й
GPIOD->BSRRH = (1UL << 12);
// Зажжём 13й
GPIOD->BSRRL = (1UL << 13);
delay_cycles(1000000UL);
// Погасим 13й
GPIOD->BSRRH = (1UL << 13);
// Зажжём 14й
GPIOD->BSRRL = (1UL << 14);
delay_cycles(1000000UL);
// Погасим 14й
GPIOD->BSRRH = (1UL << 14);
// Зажжём 15й
GPIOD->BSRRL = (1UL << 15);
delay_cycles(1000000UL);
// Погасим 15й
GPIOD->BSRRH = (1UL << 15);
}
}
Комментариев нет:
Отправить комментарий